misc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:21k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: misc.c,v 1.33 2001/09/18 22:29:06 davem Exp $
  2.  * misc.c: Miscelaneous syscall emulation for Solaris
  3.  *
  4.  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  5.  */
  6. #include <linux/config.h>
  7. #include <linux/module.h> 
  8. #include <linux/types.h>
  9. #include <linux/smp_lock.h>
  10. #include <linux/utsname.h>
  11. #include <linux/limits.h>
  12. #include <linux/mm.h>
  13. #include <linux/smp.h>
  14. #include <linux/mman.h>
  15. #include <linux/file.h>
  16. #include <linux/timex.h>
  17. #include <asm/uaccess.h>
  18. #include <asm/string.h>
  19. #include <asm/oplib.h>
  20. #include <asm/idprom.h>
  21. #include "conv.h"
  22. /* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
  23.    Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM, 
  24.    ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
  25.    equivalents. I return EINVAL in that case, which is very wrong. If
  26.    someone suggest a better value for them, you're welcomed.
  27.    On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
  28.    but that doesn't matter here. --jj */
  29. int solaris_err_table[] = {
  30. /* 0 */  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  31. /* 10 */  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  32. /* 20 */  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  33. /* 30 */  30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
  34. /* 40 */  97, 98, 99, 120, 121, 122, 123, 124, 125, 126, 
  35. /* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
  36. /* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
  37. /* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46, 
  38. /* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82, 
  39. /* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
  40. /* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
  41. /* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
  42. /* 120 */ 22, 22, 88, 86, 85, 22, 22,
  43. };
  44. #define SOLARIS_NR_OPEN 256
  45. static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off)
  46. {
  47. struct file *file = NULL;
  48. unsigned long retval, ret_type;
  49. /* Do we need it here? */
  50. set_personality(PER_SVR4);
  51. if (flags & MAP_NORESERVE) {
  52. static int cnt = 0;
  53. if (cnt < 5) {
  54. printk("%s:  unimplemented Solaris MAP_NORESERVE mmap() flagn",
  55.        current->comm);
  56. cnt++;
  57. }
  58. flags &= ~MAP_NORESERVE;
  59. }
  60. retval = -EBADF;
  61. if(!(flags & MAP_ANONYMOUS)) {
  62. if(fd >= SOLARIS_NR_OPEN)
  63. goto out;
  64.   file = fget(fd);
  65. if (!file)
  66. goto out;
  67. else {
  68. struct inode * inode = file->f_dentry->d_inode;
  69. if(MAJOR(inode->i_rdev) == MEM_MAJOR &&
  70.    MINOR(inode->i_rdev) == 5) {
  71. flags |= MAP_ANONYMOUS;
  72. fput(file);
  73. file = NULL;
  74. }
  75. }
  76. }
  77. retval = -EINVAL;
  78. len = PAGE_ALIGN(len);
  79. if(!(flags & MAP_FIXED))
  80. addr = 0;
  81. else if (len > 0xf0000000UL || addr > 0xf0000000UL - len)
  82. goto out_putf;
  83. ret_type = flags & _MAP_NEW;
  84. flags &= ~_MAP_NEW;
  85. down_write(&current->mm->mmap_sem);
  86. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  87. retval = do_mmap(file,
  88.  (unsigned long) addr, (unsigned long) len,
  89.  (unsigned long) prot, (unsigned long) flags, off);
  90. up_write(&current->mm->mmap_sem);
  91. if(!ret_type)
  92. retval = ((retval < 0xf0000000) ? 0 : retval);
  93.                         
  94. out_putf:
  95. if (file)
  96. fput(file);
  97. out:
  98. return (u32) retval;
  99. }
  100. asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
  101. {
  102. return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);
  103. }
  104. asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi)
  105. {
  106. u32 offlo;
  107. if (regs->u_regs[UREG_G1]) {
  108. if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
  109. return -EFAULT;
  110. } else {
  111. if (get_user (offlo, (u32 *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
  112. return -EFAULT;
  113. }
  114. return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
  115. }
  116. asmlinkage int solaris_brk(u32 brk)
  117. {
  118. int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17);
  119. return sunos_brk(brk);
  120. }
  121. #define set_utsfield(to, from, dotchop, countfrom) {
  122. char *p; 
  123. int i, len = (countfrom) ? 
  124. ((sizeof(to) > sizeof(from) ? 
  125. sizeof(from) : sizeof(to))) : sizeof(to); 
  126. if (copy_to_user(to, from, len))
  127. return -EFAULT;
  128. if (dotchop) 
  129. for (p=from,i=0; *p && *p != '.' && --len; p++,i++); 
  130. else 
  131. i = len - 1; 
  132. if (__put_user('', (char *)(to+i)))
  133. return -EFAULT;
  134. }
  135. struct sol_uname {
  136. char sysname[9];
  137. char nodename[9];
  138. char release[9];
  139. char version[9];
  140. char machine[9];
  141. };
  142. struct sol_utsname {
  143. char sysname[257];
  144. char nodename[257];
  145. char release[257];
  146. char version[257];
  147. char machine[257];
  148. };
  149. static char *machine(void)
  150. {
  151. switch (sparc_cpu_model) {
  152. case sun4: return "sun4";
  153. case sun4c: return "sun4c";
  154. case sun4e: return "sun4e";
  155. case sun4m: return "sun4m";
  156. case sun4d: return "sun4d";
  157. case sun4u: return "sun4u";
  158. default: return "sparc";
  159. }
  160. }
  161. static char *platform(char *buffer)
  162. {
  163. int len;
  164. *buffer = 0;
  165. len = prom_getproperty(prom_root_node, "name", buffer, 256);
  166. if(len > 0)
  167. buffer[len] = 0;
  168. if (*buffer) {
  169. char *p;
  170. for (p = buffer; *p; p++)
  171. if (*p == '/' || *p == ' ') *p = '_';
  172. return buffer;
  173. }
  174. return "sun4u";
  175. }
  176. static char *serial(char *buffer)
  177. {
  178. int node = prom_getchild(prom_root_node);
  179. int len;
  180. node = prom_searchsiblings(node, "options");
  181. *buffer = 0;
  182. len = prom_getproperty(node, "system-board-serial#", buffer, 256);
  183. if(len > 0)
  184. buffer[len] = 0;
  185. if (!*buffer)
  186. return "4512348717234";
  187. else
  188. return buffer;
  189. }
  190. asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
  191. {
  192. switch (which) {
  193. case 0: /* old uname */
  194. /* Let's cheat */
  195. set_utsfield(((struct sol_uname *)A(buf))->sysname, 
  196. "SunOS", 1, 0);
  197. down_read(&uts_sem);
  198. set_utsfield(((struct sol_uname *)A(buf))->nodename, 
  199. system_utsname.nodename, 1, 1);
  200. up_read(&uts_sem);
  201. set_utsfield(((struct sol_uname *)A(buf))->release, 
  202. "2.6", 0, 0);
  203. set_utsfield(((struct sol_uname *)A(buf))->version, 
  204. "Generic", 0, 0);
  205. set_utsfield(((struct sol_uname *)A(buf))->machine, 
  206. machine(), 0, 0);
  207. return 0;
  208. case 2: /* ustat */
  209. return -ENOSYS;
  210. case 3: /* fusers */
  211. return -ENOSYS;
  212. default:
  213. return -ENOSYS;
  214. }
  215. }
  216. asmlinkage int solaris_utsname(u32 buf)
  217. {
  218. /* Why should we not lie a bit? */
  219. down_read(&uts_sem);
  220. set_utsfield(((struct sol_utsname *)A(buf))->sysname, 
  221. "SunOS", 0, 0);
  222. set_utsfield(((struct sol_utsname *)A(buf))->nodename, 
  223. system_utsname.nodename, 1, 1);
  224. set_utsfield(((struct sol_utsname *)A(buf))->release, 
  225. "5.6", 0, 0);
  226. set_utsfield(((struct sol_utsname *)A(buf))->version, 
  227. "Generic", 0, 0);
  228. set_utsfield(((struct sol_utsname *)A(buf))->machine, 
  229. machine(), 0, 0);
  230. up_read(&uts_sem);
  231. return 0;
  232. }
  233. #define SI_SYSNAME 1       /* return name of operating system */
  234. #define SI_HOSTNAME 2       /* return name of node */
  235. #define SI_RELEASE 3       /* return release of operating system */
  236. #define SI_VERSION 4       /* return version field of utsname */
  237. #define SI_MACHINE 5       /* return kind of machine */
  238. #define SI_ARCHITECTURE 6       /* return instruction set arch */
  239. #define SI_HW_SERIAL 7       /* return hardware serial number */
  240. #define SI_HW_PROVIDER 8       /* return hardware manufacturer */
  241. #define SI_SRPC_DOMAIN 9       /* return secure RPC domain */
  242. #define SI_PLATFORM 513     /* return platform identifier */
  243. asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
  244. {
  245. char *p, *q, *r;
  246. char buffer[256];
  247. int len;
  248. /* Again, we cheat :)) */
  249. switch (cmd) {
  250. case SI_SYSNAME: r = "SunOS"; break;
  251. case SI_HOSTNAME:
  252. r = buffer + 256;
  253. down_read(&uts_sem);
  254. for (p = system_utsname.nodename, q = buffer; 
  255.      q < r && *p && *p != '.'; *q++ = *p++);
  256. up_read(&uts_sem);
  257. *q = 0;
  258. r = buffer;
  259. break;
  260. case SI_RELEASE: r = "5.6"; break;
  261. case SI_MACHINE: r = machine(); break;
  262. case SI_ARCHITECTURE: r = "sparc"; break;
  263. case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
  264. case SI_HW_SERIAL: r = serial(buffer); break;
  265. case SI_PLATFORM: r = platform(buffer); break;
  266. case SI_SRPC_DOMAIN: r = ""; break;
  267. case SI_VERSION: r = "Generic"; break;
  268. default: return -EINVAL;
  269. }
  270. len = strlen(r) + 1;
  271. if (count < len) {
  272. if (copy_to_user((char *)A(buf), r, count - 1) ||
  273.     __put_user(0, (char *)A(buf) + count - 1))
  274. return -EFAULT;
  275. } else {
  276. if (copy_to_user((char *)A(buf), r, len))
  277. return -EFAULT;
  278. }
  279. return len;
  280. }
  281. #define SOLARIS_CONFIG_NGROUPS 2
  282. #define SOLARIS_CONFIG_CHILD_MAX 3
  283. #define SOLARIS_CONFIG_OPEN_FILES 4
  284. #define SOLARIS_CONFIG_POSIX_VER 5
  285. #define SOLARIS_CONFIG_PAGESIZE 6
  286. #define SOLARIS_CONFIG_CLK_TCK 7
  287. #define SOLARIS_CONFIG_XOPEN_VER 8
  288. #define SOLARIS_CONFIG_PROF_TCK 10
  289. #define SOLARIS_CONFIG_NPROC_CONF 11
  290. #define SOLARIS_CONFIG_NPROC_ONLN 12
  291. #define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
  292. #define SOLARIS_CONFIG_AIO_MAX 14
  293. #define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
  294. #define SOLARIS_CONFIG_DELAYTIMER_MAX 16
  295. #define SOLARIS_CONFIG_MQ_OPEN_MAX 17
  296. #define SOLARIS_CONFIG_MQ_PRIO_MAX 18
  297. #define SOLARIS_CONFIG_RTSIG_MAX 19
  298. #define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
  299. #define SOLARIS_CONFIG_SEM_VALUE_MAX 21
  300. #define SOLARIS_CONFIG_SIGQUEUE_MAX 22
  301. #define SOLARIS_CONFIG_SIGRT_MIN 23
  302. #define SOLARIS_CONFIG_SIGRT_MAX 24
  303. #define SOLARIS_CONFIG_TIMER_MAX 25
  304. #define SOLARIS_CONFIG_PHYS_PAGES 26
  305. #define SOLARIS_CONFIG_AVPHYS_PAGES 27
  306. extern unsigned prom_cpu_nodes[NR_CPUS];
  307. asmlinkage int solaris_sysconf(int id)
  308. {
  309. switch (id) {
  310. case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX;
  311. case SOLARIS_CONFIG_CHILD_MAX: return CHILD_MAX;
  312. case SOLARIS_CONFIG_OPEN_FILES: return OPEN_MAX;
  313. case SOLARIS_CONFIG_POSIX_VER: return 199309;
  314. case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE;
  315. case SOLARIS_CONFIG_XOPEN_VER: return 3;
  316. case SOLARIS_CONFIG_CLK_TCK:
  317. case SOLARIS_CONFIG_PROF_TCK:
  318. return prom_getintdefault(prom_cpu_nodes[smp_processor_id()],
  319.   "clock-frequency", 167000000);
  320. #ifdef CONFIG_SMP
  321. case SOLARIS_CONFIG_NPROC_CONF: return NR_CPUS;
  322. case SOLARIS_CONFIG_NPROC_ONLN: return smp_num_cpus;
  323. #else
  324. case SOLARIS_CONFIG_NPROC_CONF: return 1;
  325. case SOLARIS_CONFIG_NPROC_ONLN: return 1;
  326. #endif
  327. case SOLARIS_CONFIG_SIGRT_MIN: return 37;
  328. case SOLARIS_CONFIG_SIGRT_MAX: return 44;
  329. case SOLARIS_CONFIG_PHYS_PAGES:
  330. case SOLARIS_CONFIG_AVPHYS_PAGES:
  331. {
  332. struct sysinfo s;
  333. si_meminfo(&s);
  334. if (id == SOLARIS_CONFIG_PHYS_PAGES)
  335. return s.totalram >>= PAGE_SHIFT;
  336. else
  337. return s.freeram >>= PAGE_SHIFT;
  338. }
  339. /* XXX support these as well -jj */
  340. case SOLARIS_CONFIG_AIO_LISTIO_MAX: return -EINVAL;
  341. case SOLARIS_CONFIG_AIO_MAX: return -EINVAL;
  342. case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL;
  343. case SOLARIS_CONFIG_DELAYTIMER_MAX: return -EINVAL;
  344. case SOLARIS_CONFIG_MQ_OPEN_MAX: return -EINVAL;
  345. case SOLARIS_CONFIG_MQ_PRIO_MAX: return -EINVAL;
  346. case SOLARIS_CONFIG_RTSIG_MAX: return -EINVAL;
  347. case SOLARIS_CONFIG_SEM_NSEMS_MAX: return -EINVAL;
  348. case SOLARIS_CONFIG_SEM_VALUE_MAX: return -EINVAL;
  349. case SOLARIS_CONFIG_SIGQUEUE_MAX: return -EINVAL;
  350. case SOLARIS_CONFIG_TIMER_MAX: return -EINVAL;
  351. default: return -EINVAL;
  352. }
  353. }
  354. asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
  355. {
  356. int ret;
  357. switch (cmd) {
  358. case 0: /* getpgrp */
  359. return current->pgrp;
  360. case 1: /* setpgrp */
  361. {
  362. int (*sys_setpgid)(pid_t,pid_t) =
  363. (int (*)(pid_t,pid_t))SYS(setpgid);
  364. /* can anyone explain me the difference between
  365.    Solaris setpgrp and setsid? */
  366. ret = sys_setpgid(0, 0);
  367. if (ret) return ret;
  368. current->tty = NULL;
  369. return current->pgrp;
  370. }
  371. case 2: /* getsid */
  372. {
  373. int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid);
  374. return sys_getsid(pid);
  375. }
  376. case 3: /* setsid */
  377. {
  378. int (*sys_setsid)(void) = (int (*)(void))SYS(setsid);
  379. return sys_setsid();
  380. }
  381. case 4: /* getpgid */
  382. {
  383. int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid);
  384. return sys_getpgid(pid);
  385. }
  386. case 5: /* setpgid */
  387. {
  388. int (*sys_setpgid)(pid_t,pid_t) = 
  389. (int (*)(pid_t,pid_t))SYS(setpgid);
  390. return sys_setpgid(pid,pgid);
  391. }
  392. }
  393. return -EINVAL;
  394. }
  395. asmlinkage int solaris_gettimeofday(u32 tim)
  396. {
  397. int (*sys_gettimeofday)(struct timeval *, struct timezone *) =
  398. (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday);
  399. return sys_gettimeofday((struct timeval *)(u64)tim, NULL);
  400. }
  401. #define RLIM_SOL_INFINITY32 0x7fffffff
  402. #define RLIM_SOL_SAVED_MAX32 0x7ffffffe
  403. #define RLIM_SOL_SAVED_CUR32 0x7ffffffd
  404. #define RLIM_SOL_INFINITY ((u64)-3)
  405. #define RLIM_SOL_SAVED_MAX ((u64)-2)
  406. #define RLIM_SOL_SAVED_CUR ((u64)-1)
  407. #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
  408. #define RLIMIT_SOL_NOFILE 5
  409. #define RLIMIT_SOL_VMEM 6
  410. struct rlimit32 {
  411. u32 rlim_cur;
  412. u32 rlim_max;
  413. };
  414. asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 *rlim)
  415. {
  416. struct rlimit r;
  417. int ret;
  418. mm_segment_t old_fs = get_fs ();
  419. int (*sys_getrlimit)(unsigned int, struct rlimit *) =
  420. (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
  421. if (resource > RLIMIT_SOL_VMEM)
  422. return -EINVAL;
  423. switch (resource) {
  424. case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
  425. case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
  426. default: break;
  427. }
  428. set_fs (KERNEL_DS);
  429. ret = sys_getrlimit(resource, &r);
  430. set_fs (old_fs);
  431. if (!ret) {
  432. if (r.rlim_cur == RLIM_INFINITY)
  433. r.rlim_cur = RLIM_SOL_INFINITY32;
  434. else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32)
  435. r.rlim_cur = RLIM_SOL_SAVED_CUR32;
  436. if (r.rlim_max == RLIM_INFINITY)
  437. r.rlim_max = RLIM_SOL_INFINITY32;
  438. else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32)
  439. r.rlim_max = RLIM_SOL_SAVED_MAX32;
  440. ret = put_user (r.rlim_cur, &rlim->rlim_cur);
  441. ret |= __put_user (r.rlim_max, &rlim->rlim_max);
  442. }
  443. return ret;
  444. }
  445. asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 *rlim)
  446. {
  447. struct rlimit r, rold;
  448. int ret;
  449. mm_segment_t old_fs = get_fs ();
  450. int (*sys_getrlimit)(unsigned int, struct rlimit *) =
  451. (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
  452. int (*sys_setrlimit)(unsigned int, struct rlimit *) =
  453. (int (*)(unsigned int, struct rlimit *))SYS(setrlimit);
  454. if (resource > RLIMIT_SOL_VMEM)
  455. return -EINVAL;
  456. switch (resource) {
  457. case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
  458. case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
  459. default: break;
  460. }
  461. if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
  462.     __get_user (r.rlim_max, &rlim->rlim_max))
  463. return -EFAULT;
  464. set_fs (KERNEL_DS);
  465. ret = sys_getrlimit(resource, &rold);
  466. if (!ret) {
  467. if (r.rlim_cur == RLIM_SOL_INFINITY32)
  468. r.rlim_cur = RLIM_INFINITY;
  469. else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32)
  470. r.rlim_cur = rold.rlim_cur;
  471. else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32)
  472. r.rlim_cur = rold.rlim_max;
  473. if (r.rlim_max == RLIM_SOL_INFINITY32)
  474. r.rlim_max = RLIM_INFINITY;
  475. else if (r.rlim_max == RLIM_SOL_SAVED_CUR32)
  476. r.rlim_max = rold.rlim_cur;
  477. else if (r.rlim_max == RLIM_SOL_SAVED_MAX32)
  478. r.rlim_max = rold.rlim_max;
  479. ret = sys_setrlimit(resource, &r);
  480. }
  481. set_fs (old_fs);
  482. return ret;
  483. }
  484. asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit *rlim)
  485. {
  486. struct rlimit r;
  487. int ret;
  488. mm_segment_t old_fs = get_fs ();
  489. int (*sys_getrlimit)(unsigned int, struct rlimit *) =
  490. (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
  491. if (resource > RLIMIT_SOL_VMEM)
  492. return -EINVAL;
  493. switch (resource) {
  494. case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
  495. case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
  496. default: break;
  497. }
  498. set_fs (KERNEL_DS);
  499. ret = sys_getrlimit(resource, &r);
  500. set_fs (old_fs);
  501. if (!ret) {
  502. if (r.rlim_cur == RLIM_INFINITY)
  503. r.rlim_cur = RLIM_SOL_INFINITY;
  504. if (r.rlim_max == RLIM_INFINITY)
  505. r.rlim_max = RLIM_SOL_INFINITY;
  506. ret = put_user (r.rlim_cur, &rlim->rlim_cur);
  507. ret |= __put_user (r.rlim_max, &rlim->rlim_max);
  508. }
  509. return ret;
  510. }
  511. asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit *rlim)
  512. {
  513. struct rlimit r, rold;
  514. int ret;
  515. mm_segment_t old_fs = get_fs ();
  516. int (*sys_getrlimit)(unsigned int, struct rlimit *) =
  517. (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
  518. int (*sys_setrlimit)(unsigned int, struct rlimit *) =
  519. (int (*)(unsigned int, struct rlimit *))SYS(setrlimit);
  520. if (resource > RLIMIT_SOL_VMEM)
  521. return -EINVAL;
  522. switch (resource) {
  523. case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
  524. case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
  525. default: break;
  526. }
  527. if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
  528.     __get_user (r.rlim_max, &rlim->rlim_max))
  529. return -EFAULT;
  530. set_fs (KERNEL_DS);
  531. ret = sys_getrlimit(resource, &rold);
  532. if (!ret) {
  533. if (r.rlim_cur == RLIM_SOL_INFINITY)
  534. r.rlim_cur = RLIM_INFINITY;
  535. else if (r.rlim_cur == RLIM_SOL_SAVED_CUR)
  536. r.rlim_cur = rold.rlim_cur;
  537. else if (r.rlim_cur == RLIM_SOL_SAVED_MAX)
  538. r.rlim_cur = rold.rlim_max;
  539. if (r.rlim_max == RLIM_SOL_INFINITY)
  540. r.rlim_max = RLIM_INFINITY;
  541. else if (r.rlim_max == RLIM_SOL_SAVED_CUR)
  542. r.rlim_max = rold.rlim_cur;
  543. else if (r.rlim_max == RLIM_SOL_SAVED_MAX)
  544. r.rlim_max = rold.rlim_max;
  545. ret = sys_setrlimit(resource, &r);
  546. }
  547. set_fs (old_fs);
  548. return ret;
  549. }
  550. struct timeval32 {
  551. int tv_sec, tv_usec;
  552. };
  553. struct sol_ntptimeval {
  554. struct timeval32 time;
  555. s32 maxerror;
  556. s32 esterror;
  557. };
  558. struct sol_timex {
  559. u32 modes;
  560. s32 offset;
  561. s32 freq;
  562. s32 maxerror;
  563. s32 esterror;
  564. s32 status;
  565. s32 constant;
  566. s32 precision;
  567. s32 tolerance;
  568. s32 ppsfreq;
  569. s32 jitter;
  570. s32 shift;
  571. s32 stabil;
  572. s32 jitcnt;
  573. s32 calcnt;
  574. s32 errcnt;
  575. s32 stbcnt;
  576. };
  577. asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval *ntp)
  578. {
  579. int (*sys_adjtimex)(struct timex *) =
  580. (int (*)(struct timex *))SYS(adjtimex);
  581. struct timex t;
  582. int ret;
  583. mm_segment_t old_fs = get_fs();
  584. set_fs(KERNEL_DS);
  585. t.modes = 0;
  586. ret = sys_adjtimex(&t);
  587. set_fs(old_fs);
  588. if (ret < 0)
  589. return ret;
  590. ret = put_user (t.time.tv_sec, &ntp->time.tv_sec);
  591. ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec);
  592. ret |= __put_user (t.maxerror, &ntp->maxerror);
  593. ret |= __put_user (t.esterror, &ntp->esterror);
  594. return ret;                         
  595. }
  596. asmlinkage int solaris_ntp_adjtime(struct sol_timex *txp)
  597. {
  598. int (*sys_adjtimex)(struct timex *) =
  599. (int (*)(struct timex *))SYS(adjtimex);
  600. struct timex t;
  601. int ret, err;
  602. mm_segment_t old_fs = get_fs();
  603. ret = get_user (t.modes, &txp->modes);
  604. ret |= __get_user (t.offset, &txp->offset);
  605. ret |= __get_user (t.freq, &txp->freq);
  606. ret |= __get_user (t.maxerror, &txp->maxerror);
  607. ret |= __get_user (t.esterror, &txp->esterror);
  608. ret |= __get_user (t.status, &txp->status);
  609. ret |= __get_user (t.constant, &txp->constant);
  610. set_fs(KERNEL_DS);
  611. ret = sys_adjtimex(&t);
  612. set_fs(old_fs);
  613. if (ret < 0)
  614. return ret;
  615. err = put_user (t.offset, &txp->offset);
  616. err |= __put_user (t.freq, &txp->freq);
  617. err |= __put_user (t.maxerror, &txp->maxerror);
  618. err |= __put_user (t.esterror, &txp->esterror);
  619. err |= __put_user (t.status, &txp->status);
  620. err |= __put_user (t.constant, &txp->constant);
  621. err |= __put_user (t.precision, &txp->precision);
  622. err |= __put_user (t.tolerance, &txp->tolerance);
  623. err |= __put_user (t.ppsfreq, &txp->ppsfreq);
  624. err |= __put_user (t.jitter, &txp->jitter);
  625. err |= __put_user (t.shift, &txp->shift);
  626. err |= __put_user (t.stabil, &txp->stabil);
  627. err |= __put_user (t.jitcnt, &txp->jitcnt);
  628. err |= __put_user (t.calcnt, &txp->calcnt);
  629. err |= __put_user (t.errcnt, &txp->errcnt);
  630. err |= __put_user (t.stbcnt, &txp->stbcnt);
  631. if (err)
  632. return -EFAULT;
  633. return ret;
  634. }
  635. asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
  636. {
  637. printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08xn", 
  638. (int)regs->u_regs[UREG_G1], 
  639. (int)regs->u_regs[UREG_I0],
  640. (int)regs->u_regs[UREG_I1],
  641. (int)regs->u_regs[UREG_I2],
  642. (int)regs->u_regs[UREG_I3]);
  643. return -ENOSYS;
  644. }
  645. asmlinkage void solaris_register(void)
  646. {
  647. set_personality(PER_SVR4);
  648. }
  649. extern long solaris_to_linux_signals[], linux_to_solaris_signals[];
  650. struct exec_domain solaris_exec_domain = {
  651. name: "Solaris",
  652. handler: NULL,
  653. pers_low: 1, /* PER_SVR4 personality */
  654. pers_high: 1,
  655. signal_map: solaris_to_linux_signals,
  656. signal_invmap: linux_to_solaris_signals,
  657. module: THIS_MODULE,
  658. next: NULL
  659. };
  660. extern int init_socksys(void);
  661. #ifdef MODULE
  662. MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
  663. MODULE_DESCRIPTION("Solaris binary emulation module");
  664. EXPORT_NO_SYMBOLS;
  665. #ifdef __sparc_v9__
  666. extern u32 tl0_solaris[8];
  667. #define update_ttable(x) 
  668. tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000;
  669. __asm__ __volatile__ ("membar #StoreStore; flush %0" : : "r" (&tl0_solaris[3]))
  670. #else
  671. #endif
  672. extern u32 solaris_sparc_syscall[];
  673. extern u32 solaris_syscall[];
  674. extern void cleanup_socksys(void);
  675. int init_module(void)
  676. {
  677. int ret;
  678. SOLDD(("Solaris module at %pn", solaris_sparc_syscall));
  679. register_exec_domain(&solaris_exec_domain);
  680. if ((ret = init_socksys())) {
  681. unregister_exec_domain(&solaris_exec_domain);
  682. return ret;
  683. }
  684. update_ttable(solaris_sparc_syscall);
  685. return 0;
  686. }
  687. void cleanup_module(void)
  688. {
  689. update_ttable(solaris_syscall);
  690. cleanup_socksys();
  691. unregister_exec_domain(&solaris_exec_domain);
  692. }
  693. #else
  694. int init_solaris_emul(void)
  695. {
  696. register_exec_domain(&solaris_exec_domain);
  697. init_socksys();
  698. return 0;
  699. }
  700. #endif