sys_ia32.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:63k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * sys_ia32.c: Conversion between 32bit and 64bit native syscalls. Based on
  3.  *             sys_sparc32 
  4.  *
  5.  * Copyright (C) 2000 VA Linux Co
  6.  * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
  7.  * Copyright (C) 1999  Arun Sharma <arun.sharma@intel.com>
  8.  * Copyright (C) 1997,1998  Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  9.  * Copyright (C) 1997  David S. Miller (davem@caip.rutgers.edu)
  10.  * Copyright (C) 2000 Hewlett-Packard Co.
  11.  * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
  12.  * Copyright (C) 2000,2001 Andi Kleen, SuSE Labs (x86-64 port) 
  13.  *
  14.  * These routines maintain argument size conversion between 32bit and 64bit
  15.  * environment. In 2.5 most of this should be moved to a generic directory. 
  16.  *
  17.  * This file assumes that there is a hole at the end of user address space.
  18.  * $Id: sys_ia32.c,v 1.42 2002/09/17 15:23:41 ak Exp $
  19.  */
  20. #include <linux/config.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/fs.h> 
  24. #include <linux/file.h> 
  25. #include <linux/signal.h>
  26. #include <linux/utime.h>
  27. #include <linux/resource.h>
  28. #include <linux/times.h>
  29. #include <linux/utsname.h>
  30. #include <linux/timex.h>
  31. #include <linux/smp.h>
  32. #include <linux/smp_lock.h>
  33. #include <linux/sem.h>
  34. #include <linux/msg.h>
  35. #include <linux/mm.h>
  36. #include <linux/shm.h>
  37. #include <linux/slab.h>
  38. #include <linux/uio.h>
  39. #include <linux/nfs_fs.h>
  40. #include <linux/smb_fs.h>
  41. #include <linux/smb_mount.h>
  42. #include <linux/ncp_fs.h>
  43. #include <linux/quota.h>
  44. #include <linux/module.h>
  45. #include <linux/sunrpc/svc.h>
  46. #include <linux/nfsd/nfsd.h>
  47. #include <linux/nfsd/cache.h>
  48. #include <linux/nfsd/xdr.h>
  49. #include <linux/nfsd/syscall.h>
  50. #include <linux/poll.h>
  51. #include <linux/personality.h>
  52. #include <linux/stat.h>
  53. #include <linux/ipc.h>
  54. #include <linux/rwsem.h>
  55. #include <linux/binfmts.h>
  56. #include <linux/init.h>
  57. #include <asm/mman.h>
  58. #include <asm/types.h>
  59. #include <asm/uaccess.h>
  60. #include <asm/semaphore.h>
  61. #include <asm/ipc.h>
  62. #include <asm/atomic.h>
  63. #include <net/scm.h>
  64. #include <net/sock.h>
  65. #include <asm/ia32.h>
  66. #define A(__x) ((unsigned long)(__x))
  67. #define AA(__x) ((unsigned long)(__x))
  68. #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1)))
  69. #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
  70. #undef high2lowuid
  71. #undef high2lowgid
  72. #undef low2highuid
  73. #undef low2highgid
  74. #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
  75. #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
  76. #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
  77. #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
  78. extern int overflowuid,overflowgid; 
  79. static int
  80. putstat(struct stat32 *ubuf, struct stat *kbuf)
  81. {
  82. if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat32)) ||
  83.     __put_user (kbuf->st_dev, &ubuf->st_dev) ||
  84.     __put_user (kbuf->st_ino, &ubuf->st_ino) ||
  85.     __put_user (kbuf->st_mode, &ubuf->st_mode) ||
  86.     __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
  87.     __put_user (kbuf->st_uid, &ubuf->st_uid) ||
  88.     __put_user (kbuf->st_gid, &ubuf->st_gid) ||
  89.     __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
  90.     __put_user (kbuf->st_size, &ubuf->st_size) ||
  91.     __put_user (kbuf->st_atime, &ubuf->st_atime) ||
  92.     __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
  93.     __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
  94.     __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
  95.     __put_user (kbuf->st_blocks, &ubuf->st_blocks))
  96. return -EFAULT;
  97. return 0;
  98. }
  99. extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
  100. asmlinkage long
  101. sys32_newstat(char * filename, struct stat32 *statbuf)
  102. {
  103. int ret;
  104. struct stat s;
  105. mm_segment_t old_fs = get_fs();
  106. set_fs (KERNEL_DS);
  107. ret = sys_newstat(filename, &s);
  108. set_fs (old_fs);
  109. if (putstat (statbuf, &s))
  110. return -EFAULT;
  111. return ret;
  112. }
  113. extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
  114. asmlinkage long
  115. sys32_newlstat(char * filename, struct stat32 *statbuf)
  116. {
  117. int ret;
  118. struct stat s;
  119. mm_segment_t old_fs = get_fs();
  120. set_fs (KERNEL_DS);
  121. ret = sys_newlstat(filename, &s);
  122. set_fs (old_fs);
  123. if (putstat (statbuf, &s))
  124. return -EFAULT;
  125. return ret;
  126. }
  127. extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
  128. asmlinkage long
  129. sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
  130. {
  131. int ret;
  132. struct stat s;
  133. mm_segment_t old_fs = get_fs();
  134. set_fs (KERNEL_DS);
  135. ret = sys_newfstat(fd, &s);
  136. set_fs (old_fs);
  137. if (putstat (statbuf, &s))
  138. return -EFAULT;
  139. return ret;
  140. }
  141. /* Another set for IA32/LFS -- x86_64 struct stat is different due to 
  142.    support for 64bit inode numbers. */
  143. static int
  144. putstat64(struct stat64 *ubuf, struct stat *kbuf)
  145. {
  146. if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
  147.     __put_user (kbuf->st_dev, &ubuf->st_dev) ||
  148.     __put_user (kbuf->st_ino, &ubuf->__st_ino) ||
  149.     __put_user (kbuf->st_ino, &ubuf->st_ino) ||
  150.     __put_user (kbuf->st_mode, &ubuf->st_mode) ||
  151.     __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
  152.     __put_user (kbuf->st_uid, &ubuf->st_uid) ||
  153.     __put_user (kbuf->st_gid, &ubuf->st_gid) ||
  154.     __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
  155.     __put_user (kbuf->st_size, &ubuf->st_size) ||
  156.     __put_user (kbuf->st_atime, &ubuf->st_atime) ||
  157.     __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
  158.     __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
  159.     __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
  160.     __put_user (kbuf->st_blocks, &ubuf->st_blocks))
  161. return -EFAULT;
  162. return 0;
  163. }
  164. asmlinkage long
  165. sys32_stat64(char * filename, struct stat64 *statbuf)
  166. {
  167. int ret;
  168. struct stat s;
  169. mm_segment_t old_fs = get_fs();
  170. set_fs (KERNEL_DS);
  171. ret = sys_newstat(filename, &s);
  172. set_fs (old_fs);
  173. if (putstat64 (statbuf, &s))
  174. return -EFAULT;
  175. return ret;
  176. }
  177. asmlinkage long
  178. sys32_lstat64(char * filename, struct stat64 *statbuf)
  179. {
  180. int ret;
  181. struct stat s;
  182. mm_segment_t old_fs = get_fs();
  183. set_fs (KERNEL_DS);
  184. ret = sys_newlstat(filename, &s);
  185. set_fs (old_fs);
  186. if (putstat64 (statbuf, &s))
  187. return -EFAULT;
  188. return ret;
  189. }
  190. asmlinkage long
  191. sys32_fstat64(unsigned int fd, struct stat64 *statbuf)
  192. {
  193. int ret;
  194. struct stat s;
  195. mm_segment_t old_fs = get_fs();
  196. set_fs (KERNEL_DS);
  197. ret = sys_newfstat(fd, &s);
  198. set_fs (old_fs);
  199. if (putstat64 (statbuf, &s))
  200. return -EFAULT;
  201. return ret;
  202. }
  203. /*
  204.  * Linux/i386 didn't use to be able to handle more than
  205.  * 4 system call parameters, so these system calls used a memory
  206.  * block for parameter passing..
  207.  */
  208. struct mmap_arg_struct {
  209. unsigned int addr;
  210. unsigned int len;
  211. unsigned int prot;
  212. unsigned int flags;
  213. unsigned int fd;
  214. unsigned int offset;
  215. };
  216. asmlinkage __u32
  217. sys32_mmap(struct mmap_arg_struct *arg)
  218. {
  219. struct mmap_arg_struct a;
  220. struct file *file = NULL;
  221. unsigned long retval;
  222. struct mm_struct *mm ;
  223. if (copy_from_user(&a, arg, sizeof(a)))
  224. return -EFAULT;
  225. if (a.offset & ~PAGE_MASK)
  226. return -EINVAL; 
  227. if (!(a.flags & MAP_ANONYMOUS)) {
  228. file = fget(a.fd);
  229. if (!file)
  230. return -EBADF;
  231. }
  232. if (a.prot & PROT_READ) 
  233. a.prot |= PROT_EXEC; 
  234. a.flags |= MAP_32BIT;
  235. mm = current->mm; 
  236. down_write(&mm->mmap_sem); 
  237. retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT);
  238. if (file)
  239. fput(file);
  240. /* Should not happen */
  241. if (retval >= 0xFFFFFFFF && (long)retval > 0) { 
  242. do_munmap(mm, retval, a.len); 
  243. retval = -ENOMEM; 
  244. up_write(&mm->mmap_sem); 
  245. return retval;
  246. }
  247. extern asmlinkage long sys_mprotect(unsigned long start,size_t len,unsigned long prot);
  248. asmlinkage int sys32_mprotect(unsigned long start, size_t len, unsigned long prot)
  249. {
  250. if (prot & PROT_READ) 
  251. prot |= PROT_EXEC; 
  252. return sys_mprotect(start,len,prot); 
  253. }
  254. asmlinkage long
  255. sys32_pipe(int *fd)
  256. {
  257. int retval;
  258. int fds[2];
  259. retval = do_pipe(fds);
  260. if (retval)
  261. goto out;
  262. if (copy_to_user(fd, fds, sizeof(fds)))
  263. retval = -EFAULT;
  264.   out:
  265. return retval;
  266. }
  267. asmlinkage long
  268. sys32_rt_sigaction(int sig, struct sigaction32 *act,
  269.    struct sigaction32 *oact,  unsigned int sigsetsize)
  270. {
  271. struct k_sigaction new_ka, old_ka;
  272. int ret;
  273. sigset32_t set32;
  274. /* XXX: Don't preclude handling different sized sigset_t's.  */
  275. if (sigsetsize != sizeof(sigset32_t))
  276. return -EINVAL;
  277. if (act) {
  278. if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
  279.     __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
  280.     __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
  281.     __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)||
  282.     __copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t)))
  283. return -EFAULT;
  284. /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
  285. switch (_NSIG_WORDS) {
  286. case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
  287. | (((long)set32.sig[7]) << 32);
  288. case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
  289. | (((long)set32.sig[5]) << 32);
  290. case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
  291. | (((long)set32.sig[3]) << 32);
  292. case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
  293. | (((long)set32.sig[1]) << 32);
  294. }
  295. }
  296. ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  297. if (!ret && oact) {
  298. /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
  299. switch (_NSIG_WORDS) {
  300. case 4:
  301. set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
  302. set32.sig[6] = old_ka.sa.sa_mask.sig[3];
  303. case 3:
  304. set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
  305. set32.sig[4] = old_ka.sa.sa_mask.sig[2];
  306. case 2:
  307. set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
  308. set32.sig[2] = old_ka.sa.sa_mask.sig[1];
  309. case 1:
  310. set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
  311. set32.sig[0] = old_ka.sa.sa_mask.sig[0];
  312. }
  313. if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
  314.     __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
  315.     __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
  316.     __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
  317.     __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t)))
  318. return -EFAULT;
  319. }
  320. return ret;
  321. }
  322. asmlinkage long
  323. sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
  324. {
  325.         struct k_sigaction new_ka, old_ka;
  326.         int ret;
  327.         if (act) {
  328. old_sigset32_t mask;
  329. if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
  330.     __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
  331.     __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
  332.     __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) ||
  333.     __get_user(mask, &act->sa_mask))
  334. return -EFAULT;
  335. siginitset(&new_ka.sa.sa_mask, mask);
  336.         }
  337.         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  338. if (!ret && oact) {
  339. if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
  340.     __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
  341.     __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
  342.     __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
  343.     __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
  344. return -EFAULT;
  345.         }
  346. return ret;
  347. }
  348. extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
  349.   size_t sigsetsize);
  350. asmlinkage long
  351. sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
  352.      unsigned int sigsetsize)
  353. {
  354. sigset_t s;
  355. sigset32_t s32;
  356. int ret;
  357. mm_segment_t old_fs = get_fs();
  358. if (set) {
  359. if (copy_from_user (&s32, set, sizeof(sigset32_t)))
  360. return -EFAULT;
  361. switch (_NSIG_WORDS) {
  362. case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
  363. case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
  364. case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
  365. case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
  366. }
  367. }
  368. set_fs (KERNEL_DS);
  369. ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL,
  370.  sigsetsize); 
  371. set_fs (old_fs);
  372. if (ret) return ret;
  373. if (oset) {
  374. switch (_NSIG_WORDS) {
  375. case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
  376. case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
  377. case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
  378. case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
  379. }
  380. if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
  381. return -EFAULT;
  382. }
  383. return 0;
  384. }
  385. static int
  386. put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
  387. {
  388. if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct statfs32)) ||
  389.     __put_user (kbuf->f_type, &ubuf->f_type) ||
  390.     __put_user (kbuf->f_bsize, &ubuf->f_bsize) ||
  391.     __put_user (kbuf->f_blocks, &ubuf->f_blocks) ||
  392.     __put_user (kbuf->f_bfree, &ubuf->f_bfree) ||
  393.     __put_user (kbuf->f_bavail, &ubuf->f_bavail) ||
  394.     __put_user (kbuf->f_files, &ubuf->f_files) ||
  395.     __put_user (kbuf->f_ffree, &ubuf->f_ffree) ||
  396.     __put_user (kbuf->f_namelen, &ubuf->f_namelen) ||
  397.     __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
  398.     __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]))
  399. return -EFAULT;
  400. return 0;
  401. }
  402. extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
  403. asmlinkage long
  404. sys32_statfs(const char * path, struct statfs32 *buf)
  405. {
  406. int ret;
  407. struct statfs s;
  408. mm_segment_t old_fs = get_fs();
  409. set_fs (KERNEL_DS);
  410. ret = sys_statfs((const char *)path, &s);
  411. set_fs (old_fs);
  412. if (put_statfs(buf, &s))
  413. return -EFAULT;
  414. return ret;
  415. }
  416. extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
  417. asmlinkage long
  418. sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
  419. {
  420. int ret;
  421. struct statfs s;
  422. mm_segment_t old_fs = get_fs();
  423. set_fs (KERNEL_DS);
  424. ret = sys_fstatfs(fd, &s);
  425. set_fs (old_fs);
  426. if (put_statfs(buf, &s))
  427. return -EFAULT;
  428. return ret;
  429. }
  430. struct timeval32
  431. {
  432.     int tv_sec, tv_usec;
  433. };
  434. struct itimerval32
  435. {
  436.     struct timeval32 it_interval;
  437.     struct timeval32 it_value;
  438. };
  439. static inline long
  440. get_tv32(struct timeval *o, struct timeval32 *i)
  441. {
  442. int err = -EFAULT; 
  443. if (access_ok(VERIFY_READ, i, sizeof(*i))) { 
  444. err = __get_user(o->tv_sec, &i->tv_sec);
  445. err |= __get_user(o->tv_usec, &i->tv_usec);
  446. }
  447. return err; 
  448. }
  449. static inline long
  450. put_tv32(struct timeval32 *o, struct timeval *i)
  451. {
  452. int err = -EFAULT;
  453. if (access_ok(VERIFY_WRITE, o, sizeof(*o))) { 
  454. err = __put_user(i->tv_sec, &o->tv_sec);
  455. err |= __put_user(i->tv_usec, &o->tv_usec);
  456. return err; 
  457. }
  458. static inline long
  459. get_it32(struct itimerval *o, struct itimerval32 *i)
  460. {
  461. int err = -EFAULT; 
  462. if (access_ok(VERIFY_READ, i, sizeof(*i))) { 
  463. err = __get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec);
  464. err |= __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec);
  465. err |= __get_user(o->it_value.tv_sec, &i->it_value.tv_sec);
  466. err |= __get_user(o->it_value.tv_usec, &i->it_value.tv_usec);
  467. }
  468. return err;
  469. }
  470. static inline long
  471. put_it32(struct itimerval32 *o, struct itimerval *i)
  472. {
  473. int err = -EFAULT;
  474. if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
  475. err = __put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec);
  476. err |= __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec);
  477. err |= __put_user(i->it_value.tv_sec, &o->it_value.tv_sec);
  478. err |= __put_user(i->it_value.tv_usec, &o->it_value.tv_usec); 
  479. return err;
  480. }
  481. extern int do_getitimer(int which, struct itimerval *value);
  482. asmlinkage long
  483. sys32_getitimer(int which, struct itimerval32 *it)
  484. {
  485. struct itimerval kit;
  486. int error;
  487. error = do_getitimer(which, &kit);
  488. if (!error && put_it32(it, &kit))
  489. error = -EFAULT;
  490. return error;
  491. }
  492. extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
  493. asmlinkage long
  494. sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
  495. {
  496. struct itimerval kin, kout;
  497. int error;
  498. if (in) {
  499. if (get_it32(&kin, in))
  500. return -EFAULT;
  501. } else
  502. memset(&kin, 0, sizeof(kin));
  503. error = do_setitimer(which, &kin, out ? &kout : NULL);
  504. if (error || !out)
  505. return error;
  506. if (put_it32(out, &kout))
  507. return -EFAULT;
  508. return 0;
  509. }
  510. asmlinkage unsigned long 
  511. sys32_alarm(unsigned int seconds)
  512. {
  513. struct itimerval it_new, it_old;
  514. unsigned int oldalarm;
  515. it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
  516. it_new.it_value.tv_sec = seconds;
  517. it_new.it_value.tv_usec = 0;
  518. do_setitimer(ITIMER_REAL, &it_new, &it_old);
  519. oldalarm = it_old.it_value.tv_sec;
  520. /* ehhh.. We can't return 0 if we have an alarm pending.. */
  521. /* And we'd better return too much than too little anyway */
  522. if (it_old.it_value.tv_usec)
  523. oldalarm++;
  524. return oldalarm;
  525. }
  526. /* Translations due to time_t size differences.  Which affects all
  527.    sorts of things, like timeval and itimerval.  */
  528. struct utimbuf_32 {
  529. int atime;
  530. int mtime;
  531. };
  532. extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
  533. extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
  534. extern struct timezone sys_tz;
  535. extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
  536. asmlinkage long
  537. sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
  538. {
  539. if (tv) {
  540. struct timeval ktv;
  541. do_gettimeofday(&ktv);
  542. if (put_tv32(tv, &ktv))
  543. return -EFAULT;
  544. }
  545. if (tz) {
  546. if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
  547. return -EFAULT;
  548. }
  549. return 0;
  550. }
  551. asmlinkage long
  552. sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
  553. {
  554. struct timeval ktv;
  555. struct timezone ktz;
  556.   if (tv) {
  557. if (get_tv32(&ktv, tv))
  558. return -EFAULT;
  559. }
  560. if (tz) {
  561. if (copy_from_user(&ktz, tz, sizeof(ktz)))
  562. return -EFAULT;
  563. }
  564. return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
  565. }
  566. struct linux32_dirent {
  567. u32 d_ino;
  568. u32 d_off;
  569. u16 d_reclen;
  570. char d_name[1];
  571. };
  572. struct old_linux32_dirent {
  573. u32 d_ino;
  574. u32 d_offset;
  575. u16 d_namlen;
  576. char d_name[1];
  577. };
  578. struct getdents32_callback {
  579. struct linux32_dirent * current_dir;
  580. struct linux32_dirent * previous;
  581. int count;
  582. int error;
  583. };
  584. struct readdir32_callback {
  585. struct old_linux32_dirent * dirent;
  586. int count;
  587. };
  588. static int
  589. filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
  590.    unsigned int d_type)
  591. {
  592. struct linux32_dirent * dirent;
  593. struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
  594. int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
  595. buf->error = -EINVAL; /* only used if we fail.. */
  596. if (reclen > buf->count)
  597. return -EINVAL;
  598. dirent = buf->previous;
  599. if (dirent)
  600. put_user(offset, &dirent->d_off);
  601. dirent = buf->current_dir;
  602. buf->previous = dirent;
  603. put_user(ino, &dirent->d_ino);
  604. put_user(reclen, &dirent->d_reclen);
  605. copy_to_user(dirent->d_name, name, namlen);
  606. put_user(0, dirent->d_name + namlen);
  607. ((char *) dirent) += reclen;
  608. buf->current_dir = dirent;
  609. buf->count -= reclen;
  610. return 0;
  611. }
  612. asmlinkage long
  613. sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
  614. {
  615. struct file * file;
  616. struct linux32_dirent * lastdirent;
  617. struct getdents32_callback buf;
  618. int error;
  619. error = -EBADF;
  620. file = fget(fd);
  621. if (!file)
  622. goto out;
  623. buf.current_dir = (struct linux32_dirent *) dirent;
  624. buf.previous = NULL;
  625. buf.count = count;
  626. buf.error = 0;
  627. error = vfs_readdir(file, filldir32, &buf);
  628. if (error < 0)
  629. goto out_putf;
  630. error = buf.error;
  631. lastdirent = buf.previous;
  632. if (lastdirent) {
  633. put_user(file->f_pos, &lastdirent->d_off);
  634. error = count - buf.count;
  635. }
  636. out_putf:
  637. fput(file);
  638. out:
  639. return error;
  640. }
  641. static int
  642. fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type)
  643. {
  644. struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
  645. struct old_linux32_dirent * dirent;
  646. if (buf->count)
  647. return -EINVAL;
  648. buf->count++;
  649. dirent = buf->dirent;
  650. put_user(ino, &dirent->d_ino);
  651. put_user(offset, &dirent->d_offset);
  652. put_user(namlen, &dirent->d_namlen);
  653. copy_to_user(dirent->d_name, name, namlen);
  654. put_user(0, dirent->d_name + namlen);
  655. return 0;
  656. }
  657. asmlinkage long
  658. sys32_oldreaddir (unsigned int fd, void * dirent, unsigned int count)
  659. {
  660. int error;
  661. struct file * file;
  662. struct readdir32_callback buf;
  663. error = -EBADF;
  664. file = fget(fd);
  665. if (!file)
  666. goto out;
  667. buf.count = 0;
  668. buf.dirent = dirent;
  669. error = vfs_readdir(file, fillonedir32, &buf);
  670. if (error >= 0)
  671. error = buf.count;
  672. fput(file);
  673. out:
  674. return error;
  675. }
  676. /*
  677.  * We can actually return ERESTARTSYS instead of EINTR, but I'd
  678.  * like to be certain this leads to no problems. So I return
  679.  * EINTR just for safety.
  680.  *
  681.  * Update: ERESTARTSYS breaks at least the xview clock binary, so
  682.  * I'm trying ERESTARTNOHAND which restart only when you want to.
  683.  */
  684. #define MAX_SELECT_SECONDS 
  685. ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
  686. #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
  687. asmlinkage long
  688. sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
  689. {
  690. fd_set_bits fds;
  691. char *bits;
  692. long timeout;
  693. int ret, size;
  694. timeout = MAX_SCHEDULE_TIMEOUT;
  695. if (tvp32) {
  696. time_t sec, usec;
  697. get_user(sec, &tvp32->tv_sec);
  698. get_user(usec, &tvp32->tv_usec);
  699. ret = -EINVAL;
  700. if (sec < 0 || usec < 0)
  701. goto out_nofds;
  702. if ((unsigned long) sec < MAX_SELECT_SECONDS) {
  703. timeout = ROUND_UP_TIME(usec, 1000000/HZ);
  704. timeout += sec * (unsigned long) HZ;
  705. }
  706. }
  707. ret = -EINVAL;
  708. if (n < 0)
  709. goto out_nofds;
  710. if (n > current->files->max_fdset)
  711. n = current->files->max_fdset;
  712. /*
  713.  * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
  714.  * since we used fdset we need to allocate memory in units of
  715.  * long-words. 
  716.  */
  717. ret = -ENOMEM;
  718. size = FDS_BYTES(n);
  719. bits = kmalloc(6 * size, GFP_KERNEL);
  720. if (!bits)
  721. goto out_nofds;
  722. fds.in      = (unsigned long *)  bits;
  723. fds.out     = (unsigned long *) (bits +   size);
  724. fds.ex      = (unsigned long *) (bits + 2*size);
  725. fds.res_in  = (unsigned long *) (bits + 3*size);
  726. fds.res_out = (unsigned long *) (bits + 4*size);
  727. fds.res_ex  = (unsigned long *) (bits + 5*size);
  728. if ((ret = get_fd_set(n, inp, fds.in)) ||
  729.     (ret = get_fd_set(n, outp, fds.out)) ||
  730.     (ret = get_fd_set(n, exp, fds.ex)))
  731. goto out;
  732. zero_fd_set(n, fds.res_in);
  733. zero_fd_set(n, fds.res_out);
  734. zero_fd_set(n, fds.res_ex);
  735. ret = do_select(n, &fds, &timeout);
  736. if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) {
  737. time_t sec = 0, usec = 0;
  738. if (timeout) {
  739. sec = timeout / HZ;
  740. usec = timeout % HZ;
  741. usec *= (1000000/HZ);
  742. }
  743. put_user(sec, (int *)&tvp32->tv_sec);
  744. put_user(usec, (int *)&tvp32->tv_usec);
  745. }
  746. if (ret < 0)
  747. goto out;
  748. if (!ret) {
  749. ret = -ERESTARTNOHAND;
  750. if (signal_pending(current))
  751. goto out;
  752. ret = 0;
  753. }
  754. set_fd_set(n, inp, fds.res_in);
  755. set_fd_set(n, outp, fds.res_out);
  756. set_fd_set(n, exp, fds.res_ex);
  757. out:
  758. kfree(bits);
  759. out_nofds:
  760. return ret;
  761. }
  762. struct sel_arg_struct {
  763. unsigned int n;
  764. unsigned int inp;
  765. unsigned int outp;
  766. unsigned int exp;
  767. unsigned int tvp;
  768. };
  769. asmlinkage long
  770. sys32_old_select(struct sel_arg_struct *arg)
  771. {
  772. struct sel_arg_struct a;
  773. if (copy_from_user(&a, arg, sizeof(a)))
  774. return -EFAULT;
  775. return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
  776.     (struct timeval32 *)A(a.tvp));
  777. }
  778. struct timespec32 {
  779. int  tv_sec;
  780. int tv_nsec;
  781. };
  782. extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); 
  783. asmlinkage long
  784. sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
  785. {
  786. struct timespec t;
  787. int ret;
  788. mm_segment_t old_fs = get_fs ();
  789. if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) ||
  790.     __get_user (t.tv_sec, &rqtp->tv_sec) ||
  791.     __get_user (t.tv_nsec, &rqtp->tv_nsec))
  792. return -EFAULT;
  793. set_fs (KERNEL_DS);
  794. ret = sys_nanosleep(&t, rmtp ? &t : NULL);
  795. set_fs (old_fs);
  796. if (rmtp && ret == -EINTR) {
  797. if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) ||
  798.     __put_user (t.tv_sec, &rmtp->tv_sec) ||
  799.          __put_user (t.tv_nsec, &rmtp->tv_nsec))
  800. return -EFAULT;
  801. }
  802. return ret;
  803. }
  804. asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
  805. asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
  806. struct iovec *
  807. get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
  808. {
  809. int i;
  810. u32 buf, len;
  811. struct iovec *ivp, *iov;
  812. /* Get the "struct iovec" from user memory */
  813. if (!count)
  814. return 0;
  815. if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
  816. return(struct iovec *)0;
  817. if (count > UIO_MAXIOV)
  818. return(struct iovec *)0;
  819. if (count > UIO_FASTIOV) {
  820. iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
  821. if (!iov)
  822. return((struct iovec *)0);
  823. } else
  824. iov = iov_buf;
  825. ivp = iov;
  826. for (i = 0; i < count; i++) {
  827. if (__get_user(len, &iov32->iov_len) ||
  828.     __get_user(buf, &iov32->iov_base)) {
  829. if (iov != iov_buf)
  830. kfree(iov);
  831. return((struct iovec *)0);
  832. }
  833. if (verify_area(type, (void *)A(buf), len)) {
  834. if (iov != iov_buf)
  835. kfree(iov);
  836. return((struct iovec *)0);
  837. }
  838. ivp->iov_base = (void *)A(buf);
  839. ivp->iov_len = (__kernel_size_t)len;
  840. iov32++;
  841. ivp++;
  842. }
  843. return(iov);
  844. }
  845. asmlinkage long
  846. sys32_readv(int fd, struct iovec32 *vector, u32 count)
  847. {
  848. struct iovec iovstack[UIO_FASTIOV];
  849. struct iovec *iov;
  850. int ret;
  851. mm_segment_t old_fs = get_fs();
  852. if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0)
  853. return -EFAULT;
  854. set_fs(KERNEL_DS);
  855. ret = sys_readv(fd, iov, count);
  856. set_fs(old_fs);
  857. if (iov != iovstack)
  858. kfree(iov);
  859. return ret;
  860. }
  861. asmlinkage long
  862. sys32_writev(int fd, struct iovec32 *vector, u32 count)
  863. {
  864. struct iovec iovstack[UIO_FASTIOV];
  865. struct iovec *iov;
  866. int ret;
  867. mm_segment_t old_fs = get_fs();
  868. if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0)
  869. return -EFAULT;
  870. set_fs(KERNEL_DS);
  871. ret = sys_writev(fd, iov, count);
  872. set_fs(old_fs);
  873. if (iov != iovstack)
  874. kfree(iov);
  875. return ret;
  876. }
  877. #define RLIM_INFINITY32 0xffffffff
  878. #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
  879. struct rlimit32 {
  880. int rlim_cur;
  881. int rlim_max;
  882. };
  883. extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
  884. asmlinkage long
  885. sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
  886. {
  887. struct rlimit r;
  888. int ret;
  889. mm_segment_t old_fs;
  890. old_fs = get_fs();
  891. set_fs(KERNEL_DS);
  892. ret = sys_getrlimit(resource, &r);
  893. set_fs(old_fs);
  894. if (!ret) {
  895. if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
  896.     __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) ||
  897.     __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max))
  898. ret = -EFAULT;
  899. }
  900. return ret;
  901. }
  902. extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
  903. asmlinkage long
  904. sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
  905. {
  906. struct rlimit r;
  907. int ret;
  908. mm_segment_t old_fs;
  909. old_fs = get_fs();
  910. set_fs(KERNEL_DS);
  911. ret = sys_old_getrlimit(resource, &r);
  912. set_fs(old_fs);
  913. if (!ret) {
  914. if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
  915.     __put_user(r.rlim_cur, &rlim->rlim_cur) ||
  916.     __put_user(r.rlim_max, &rlim->rlim_max))
  917. ret = -EFAULT;
  918. }
  919. return ret;
  920. }
  921. extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
  922. asmlinkage long
  923. sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
  924. {
  925. struct rlimit r;
  926. int ret;
  927. mm_segment_t old_fs = get_fs ();
  928. if (resource >= RLIM_NLIMITS) return -EINVAL;
  929. if (verify_area(VERIFY_READ, rlim, sizeof(struct rlimit32)) ||
  930.     __get_user (r.rlim_cur, &rlim->rlim_cur) ||
  931.     __get_user (r.rlim_max, &rlim->rlim_max))
  932. return -EFAULT;
  933. if (r.rlim_cur == RLIM_INFINITY32)
  934. r.rlim_cur = RLIM_INFINITY;
  935. if (r.rlim_max == RLIM_INFINITY32)
  936. r.rlim_max = RLIM_INFINITY;
  937. set_fs (KERNEL_DS);
  938. ret = sys_setrlimit(resource, &r);
  939. set_fs (old_fs);
  940. return ret;
  941. }
  942. /*
  943.  * sys_time() can be implemented in user-level using
  944.  * sys_gettimeofday().  IA64 did this but i386 Linux did not
  945.  * so we have to implement this system call here.
  946.  */
  947. asmlinkage long sys32_time(int * tloc)
  948. {
  949. int i;
  950. /* SMP: This is fairly trivial. We grab CURRENT_TIME and 
  951.    stuff it to user space. No side effects */
  952. i = CURRENT_TIME;
  953. if (tloc) {
  954. if (put_user(i,tloc))
  955. i = -EFAULT;
  956. }
  957. return i;
  958. }
  959. struct rusage32 {
  960.         struct timeval32 ru_utime;
  961.         struct timeval32 ru_stime;
  962.         int    ru_maxrss;
  963.         int    ru_ixrss;
  964.         int    ru_idrss;
  965.         int    ru_isrss;
  966.         int    ru_minflt;
  967.         int    ru_majflt;
  968.         int    ru_nswap;
  969.         int    ru_inblock;
  970.         int    ru_oublock;
  971.         int    ru_msgsnd; 
  972.         int    ru_msgrcv; 
  973.         int    ru_nsignals;
  974.         int    ru_nvcsw;
  975.         int    ru_nivcsw;
  976. };
  977. static int
  978. put_rusage (struct rusage32 *ru, struct rusage *r)
  979. {
  980. if (verify_area(VERIFY_WRITE, ru, sizeof(struct rusage32)) ||
  981.     __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
  982.     __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
  983.     __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
  984.     __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
  985.     __put_user (r->ru_maxrss, &ru->ru_maxrss) ||
  986.     __put_user (r->ru_ixrss, &ru->ru_ixrss) ||
  987.     __put_user (r->ru_idrss, &ru->ru_idrss) ||
  988.     __put_user (r->ru_isrss, &ru->ru_isrss) ||
  989.     __put_user (r->ru_minflt, &ru->ru_minflt) ||
  990.     __put_user (r->ru_majflt, &ru->ru_majflt) ||
  991.     __put_user (r->ru_nswap, &ru->ru_nswap) ||
  992.     __put_user (r->ru_inblock, &ru->ru_inblock) ||
  993.     __put_user (r->ru_oublock, &ru->ru_oublock) ||
  994.     __put_user (r->ru_msgsnd, &ru->ru_msgsnd) ||
  995.     __put_user (r->ru_msgrcv, &ru->ru_msgrcv) ||
  996.     __put_user (r->ru_nsignals, &ru->ru_nsignals) ||
  997.     __put_user (r->ru_nvcsw, &ru->ru_nvcsw) ||
  998.     __put_user (r->ru_nivcsw, &ru->ru_nivcsw))
  999. return -EFAULT;
  1000. return 0;
  1001. }
  1002. extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
  1003. int options, struct rusage * ru);
  1004. asmlinkage long
  1005. sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
  1006.     struct rusage32 *ru)
  1007. {
  1008. if (!ru)
  1009. return sys_wait4(pid, stat_addr, options, NULL);
  1010. else {
  1011. struct rusage r;
  1012. int ret;
  1013. unsigned int status;
  1014. mm_segment_t old_fs = get_fs();
  1015. set_fs (KERNEL_DS);
  1016. ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
  1017. set_fs (old_fs);
  1018. if (put_rusage (ru, &r)) return -EFAULT;
  1019. if (stat_addr && put_user (status, stat_addr))
  1020. return -EFAULT;
  1021. return ret;
  1022. }
  1023. }
  1024. asmlinkage long
  1025. sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
  1026. {
  1027. return sys32_wait4(pid, stat_addr, options, NULL);
  1028. }
  1029. extern asmlinkage long
  1030. sys_getrusage(int who, struct rusage *ru);
  1031. asmlinkage long
  1032. sys32_getrusage(int who, struct rusage32 *ru)
  1033. {
  1034. struct rusage r;
  1035. int ret;
  1036. mm_segment_t old_fs = get_fs();
  1037. set_fs (KERNEL_DS);
  1038. ret = sys_getrusage(who, &r);
  1039. set_fs (old_fs);
  1040. if (put_rusage (ru, &r)) return -EFAULT;
  1041. return ret;
  1042. }
  1043. struct tms32 {
  1044. __kernel_clock_t32 tms_utime;
  1045. __kernel_clock_t32 tms_stime;
  1046. __kernel_clock_t32 tms_cutime;
  1047. __kernel_clock_t32 tms_cstime;
  1048. };
  1049. extern int sys_times(struct tms *);
  1050.                                
  1051. asmlinkage long
  1052. sys32_times(struct tms32 *tbuf)
  1053. {
  1054. struct tms t;
  1055. long ret;
  1056. mm_segment_t old_fs = get_fs ();
  1057. set_fs (KERNEL_DS);
  1058. ret = sys_times(tbuf ? &t : NULL);
  1059. set_fs (old_fs);
  1060. if (tbuf) {
  1061. if (verify_area(VERIFY_WRITE, tbuf, sizeof(struct tms32)) ||
  1062.     __put_user (t.tms_utime, &tbuf->tms_utime) ||
  1063.     __put_user (t.tms_stime, &tbuf->tms_stime) ||
  1064.     __put_user (t.tms_cutime, &tbuf->tms_cutime) ||
  1065.     __put_user (t.tms_cstime, &tbuf->tms_cstime))
  1066. return -EFAULT;
  1067. }
  1068. return ret;
  1069. }
  1070. static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
  1071. {
  1072. int err;
  1073. err = get_user(kfl->l_type, &ufl->l_type);
  1074. err |= __get_user(kfl->l_whence, &ufl->l_whence);
  1075. err |= __get_user(kfl->l_start, &ufl->l_start);
  1076. err |= __get_user(kfl->l_len, &ufl->l_len);
  1077. err |= __get_user(kfl->l_pid, &ufl->l_pid);
  1078. return err;
  1079. }
  1080. static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
  1081. {
  1082. int err;
  1083. err = __put_user(kfl->l_type, &ufl->l_type);
  1084. err |= __put_user(kfl->l_whence, &ufl->l_whence);
  1085. err |= __put_user(kfl->l_start, &ufl->l_start);
  1086. err |= __put_user(kfl->l_len, &ufl->l_len);
  1087. err |= __put_user(kfl->l_pid, &ufl->l_pid);
  1088. return err;
  1089. }
  1090. extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
  1091. asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
  1092. asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
  1093. {
  1094. switch (cmd) {
  1095. case F_GETLK:
  1096. case F_SETLK:
  1097. case F_SETLKW:
  1098. {
  1099. struct flock f;
  1100. mm_segment_t old_fs;
  1101. long ret;
  1102. if (get_flock(&f, (struct flock32 *)arg))
  1103. return -EFAULT;
  1104. old_fs = get_fs(); set_fs (KERNEL_DS);
  1105. ret = sys_fcntl(fd, cmd, (unsigned long)&f);
  1106. set_fs (old_fs);
  1107. if (ret) return ret;
  1108. if (put_flock(&f, (struct flock32 *)arg))
  1109. return -EFAULT;
  1110. return 0;
  1111. }
  1112. case F_GETLK64: 
  1113. case F_SETLK64: 
  1114. case F_SETLKW64: 
  1115. return sys32_fcntl64(fd,cmd,arg); 
  1116. default:
  1117. return sys_fcntl(fd, cmd, (unsigned long)arg);
  1118. }
  1119. }
  1120. static inline int get_flock64(struct ia32_flock64 *fl32, struct flock *fl64)
  1121. {
  1122. if (access_ok(fl32, sizeof(struct ia32_flock64), VERIFY_WRITE)) {
  1123. int ret = __get_user(fl64->l_type, &fl32->l_type); 
  1124. ret |= __get_user(fl64->l_whence, &fl32->l_whence);
  1125. ret |= __get_user(fl64->l_start, &fl32->l_start); 
  1126. ret |= __get_user(fl64->l_len, &fl32->l_len); 
  1127. ret |= __get_user(fl64->l_pid, &fl32->l_pid); 
  1128. return ret; 
  1129. }
  1130. return -EFAULT; 
  1131. }
  1132. static inline int put_flock64(struct ia32_flock64 *fl32, struct flock *fl64)
  1133. {
  1134. if (access_ok(fl32, sizeof(struct ia32_flock64), VERIFY_WRITE)) {
  1135. int ret = __put_user(fl64->l_type, &fl32->l_type); 
  1136. ret |= __put_user(fl64->l_whence, &fl32->l_whence);
  1137. ret |= __put_user(fl64->l_start, &fl32->l_start); 
  1138. ret |= __put_user(fl64->l_len, &fl32->l_len); 
  1139. ret |= __put_user(fl64->l_pid, &fl32->l_pid); 
  1140. return ret; 
  1141. }
  1142. return -EFAULT; 
  1143. }
  1144. asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
  1145. {
  1146. struct flock fl64;  
  1147. mm_segment_t oldfs = get_fs(); 
  1148. int ret = 0; 
  1149. int oldcmd = cmd;
  1150. unsigned long oldarg = arg;
  1151. switch (cmd) {
  1152. case F_GETLK64: 
  1153. cmd = F_GETLK; 
  1154. goto cnv;
  1155. case F_SETLK64: 
  1156. cmd = F_SETLK; 
  1157. goto cnv; 
  1158. case F_SETLKW64:
  1159. cmd = F_SETLKW; 
  1160. cnv:
  1161. ret = get_flock64((struct ia32_flock64 *)arg, &fl64); 
  1162. arg = (unsigned long)&fl64; 
  1163. set_fs(KERNEL_DS); 
  1164. break; 
  1165. case F_GETLK:
  1166. case F_SETLK:
  1167. case F_SETLKW:
  1168. return sys32_fcntl(fd,cmd,arg); 
  1169. }
  1170. if (!ret)
  1171. ret = sys_fcntl(fd, cmd, arg);
  1172. set_fs(oldfs); 
  1173. if (oldcmd == F_GETLK64 && !ret)
  1174. ret = put_flock64((struct ia32_flock64 *)oldarg, &fl64); 
  1175. return ret; 
  1176. }
  1177. int sys32_ni_syscall(int call)
  1178. printk(KERN_INFO "IA32 syscall %d from %s not implementedn", call,
  1179.        current->comm);
  1180. return -ENOSYS;        
  1181. /* 32-bit timeval and related flotsam.  */
  1182. extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
  1183. struct utimbuf32 {
  1184. __kernel_time_t32 actime, modtime;
  1185. };
  1186. asmlinkage long
  1187. sys32_utime(char * filename, struct utimbuf32 *times)
  1188. {
  1189. struct utimbuf t;
  1190. mm_segment_t old_fs;
  1191. int ret;
  1192. char *filenam;
  1193. if (!times)
  1194. return sys_utime(filename, NULL);
  1195. if (verify_area(VERIFY_READ, times, sizeof(struct utimbuf32)) ||
  1196.     __get_user (t.actime, &times->actime) ||
  1197.     __get_user (t.modtime, &times->modtime))
  1198. return -EFAULT;
  1199. filenam = getname (filename);
  1200. ret = PTR_ERR(filenam);
  1201. if (!IS_ERR(filenam)) {
  1202. old_fs = get_fs();
  1203. set_fs (KERNEL_DS); 
  1204. ret = sys_utime(filenam, &t);
  1205. set_fs (old_fs);
  1206. putname(filenam);
  1207. }
  1208. return ret;
  1209. }
  1210. extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
  1211. unsigned long arg2);
  1212. asmlinkage long
  1213. sys32_sysfs(int option, u32 arg1, u32 arg2)
  1214. {
  1215. return sys_sysfs(option, arg1, arg2);
  1216. }
  1217. extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
  1218. unsigned long new_flags, void *data);
  1219. static char *badfs[] = {
  1220. "smbfs", "ncpfs", NULL
  1221. }; 
  1222. static int checktype(char *user_type) 
  1223. int err = 0; 
  1224. char **s,*kernel_type = getname(user_type); 
  1225. if (!kernel_type || IS_ERR(kernel_type)) 
  1226. return -EFAULT; 
  1227. for (s = badfs; *s; ++s) 
  1228. if (!strcmp(kernel_type, *s)) { 
  1229. printk(KERN_ERR "mount32: unsupported fs `%s' -- use 64bit mountn", *s); 
  1230. err = -EINVAL; 
  1231. break;
  1232. putname(user_type); 
  1233. return err;
  1234. asmlinkage long
  1235. sys32_mount(char *dev_name, char *dir_name, char *type,
  1236.     unsigned long new_flags, u32 data)
  1237. {
  1238. int err;
  1239. if(!capable(CAP_SYS_ADMIN))
  1240. return -EPERM;
  1241. err = checktype(type);
  1242. if (err)
  1243. return err;
  1244. return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data));
  1245. }
  1246. struct sysinfo32 {
  1247.         s32 uptime;
  1248.         u32 loads[3];
  1249.         u32 totalram;
  1250.         u32 freeram;
  1251.         u32 sharedram;
  1252.         u32 bufferram;
  1253.         u32 totalswap;
  1254.         u32 freeswap;
  1255.         unsigned short procs;
  1256.         char _f[22];
  1257. };
  1258. extern asmlinkage long sys_sysinfo(struct sysinfo *info);
  1259. asmlinkage long
  1260. sys32_sysinfo(struct sysinfo32 *info)
  1261. {
  1262. struct sysinfo s;
  1263. int ret;
  1264. mm_segment_t old_fs = get_fs ();
  1265. set_fs (KERNEL_DS);
  1266. ret = sys_sysinfo(&s);
  1267. set_fs (old_fs);
  1268. if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) ||
  1269.     __put_user (s.uptime, &info->uptime) ||
  1270.     __put_user (s.loads[0], &info->loads[0]) ||
  1271.     __put_user (s.loads[1], &info->loads[1]) ||
  1272.     __put_user (s.loads[2], &info->loads[2]) ||
  1273.     __put_user (s.totalram, &info->totalram) ||
  1274.     __put_user (s.freeram, &info->freeram) ||
  1275.     __put_user (s.sharedram, &info->sharedram) ||
  1276.     __put_user (s.bufferram, &info->bufferram) ||
  1277.     __put_user (s.totalswap, &info->totalswap) ||
  1278.     __put_user (s.freeswap, &info->freeswap) ||
  1279.     __put_user (s.procs, &info->procs))
  1280. return -EFAULT;
  1281. return 0;
  1282. }
  1283.                 
  1284. extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
  1285. struct timespec *interval);
  1286. asmlinkage long
  1287. sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
  1288. {
  1289. struct timespec t;
  1290. int ret;
  1291. mm_segment_t old_fs = get_fs ();
  1292. set_fs (KERNEL_DS);
  1293. ret = sys_sched_rr_get_interval(pid, &t);
  1294. set_fs (old_fs);
  1295. if (verify_area(VERIFY_WRITE, interval, sizeof(struct timespec32)) ||
  1296.     __put_user (t.tv_sec, &interval->tv_sec) ||
  1297.     __put_user (t.tv_nsec, &interval->tv_nsec))
  1298. return -EFAULT;
  1299. return ret;
  1300. }
  1301. extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
  1302.       old_sigset_t *oset);
  1303. asmlinkage long
  1304. sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset)
  1305. {
  1306. old_sigset_t s;
  1307. int ret;
  1308. mm_segment_t old_fs = get_fs();
  1309. if (set && get_user (s, set)) return -EFAULT;
  1310. set_fs (KERNEL_DS);
  1311. ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
  1312. set_fs (old_fs);
  1313. if (ret) return ret;
  1314. if (oset && put_user (s, oset)) return -EFAULT;
  1315. return 0;
  1316. }
  1317. extern asmlinkage long sys_sigpending(old_sigset_t *set);
  1318. asmlinkage long
  1319. sys32_sigpending(old_sigset32_t *set)
  1320. {
  1321. old_sigset_t s;
  1322. int ret;
  1323. mm_segment_t old_fs = get_fs();
  1324. set_fs (KERNEL_DS);
  1325. ret = sys_sigpending(&s);
  1326. set_fs (old_fs);
  1327. if (put_user (s, set)) return -EFAULT;
  1328. return ret;
  1329. }
  1330. extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
  1331. asmlinkage long
  1332. sys32_rt_sigpending(sigset32_t *set, __kernel_size_t32 sigsetsize)
  1333. {
  1334. sigset_t s;
  1335. sigset32_t s32;
  1336. int ret;
  1337. mm_segment_t old_fs = get_fs();
  1338. set_fs (KERNEL_DS);
  1339. ret = sys_rt_sigpending(&s, sigsetsize);
  1340. set_fs (old_fs);
  1341. if (!ret) {
  1342. switch (_NSIG_WORDS) {
  1343. case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
  1344. case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
  1345. case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
  1346. case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
  1347. }
  1348. if (copy_to_user (set, &s32, sizeof(sigset32_t)))
  1349. return -EFAULT;
  1350. }
  1351. return ret;
  1352. }
  1353. siginfo_t32 *
  1354. siginfo64to32(siginfo_t32 *d, siginfo_t *s)
  1355. {
  1356. memset (d, 0, sizeof(siginfo_t32));
  1357. d->si_signo = s->si_signo;
  1358. d->si_errno = s->si_errno;
  1359. d->si_code = s->si_code;
  1360. if (s->si_signo >= SIGRTMIN) {
  1361. d->si_pid = s->si_pid;
  1362. d->si_uid = s->si_uid;
  1363. /* XXX: Ouch, how to find this out??? */
  1364. d->si_int = s->si_int;
  1365. } else switch (s->si_signo) {
  1366. /* XXX: What about POSIX1.b timers */
  1367. case SIGCHLD:
  1368. d->si_pid = s->si_pid;
  1369. d->si_status = s->si_status;
  1370. d->si_utime = s->si_utime;
  1371. d->si_stime = s->si_stime;
  1372. break;
  1373. case SIGSEGV:
  1374. case SIGBUS:
  1375. case SIGFPE:
  1376. case SIGILL:
  1377. d->si_addr = (long)(s->si_addr);
  1378. // d->si_trapno = s->si_trapno;
  1379. break;
  1380. case SIGPOLL:
  1381. d->si_band = s->si_band;
  1382. d->si_fd = s->si_fd;
  1383. break;
  1384. default:
  1385. d->si_pid = s->si_pid;
  1386. d->si_uid = s->si_uid;
  1387. break;
  1388. }
  1389. return d;
  1390. }
  1391. siginfo_t *
  1392. siginfo32to64(siginfo_t *d, siginfo_t32 *s)
  1393. {
  1394. d->si_signo = s->si_signo;
  1395. d->si_errno = s->si_errno;
  1396. d->si_code = s->si_code;
  1397. if (s->si_signo >= SIGRTMIN) {
  1398. d->si_pid = s->si_pid;
  1399. d->si_uid = s->si_uid;
  1400. /* XXX: Ouch, how to find this out??? */
  1401. d->si_int = s->si_int;
  1402. } else switch (s->si_signo) {
  1403. /* XXX: What about POSIX1.b timers */
  1404. case SIGCHLD:
  1405. d->si_pid = s->si_pid;
  1406. d->si_status = s->si_status;
  1407. d->si_utime = s->si_utime;
  1408. d->si_stime = s->si_stime;
  1409. break;
  1410. case SIGSEGV:
  1411. case SIGBUS:
  1412. case SIGFPE:
  1413. case SIGILL:
  1414. d->si_addr = (void *)A(s->si_addr);
  1415. // d->si_trapno = s->si_trapno;
  1416. break;
  1417. case SIGPOLL:
  1418. d->si_band = s->si_band;
  1419. d->si_fd = s->si_fd;
  1420. break;
  1421. default:
  1422. d->si_pid = s->si_pid;
  1423. d->si_uid = s->si_uid;
  1424. break;
  1425. }
  1426. return d;
  1427. }
  1428. extern asmlinkage long
  1429. sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
  1430.     const struct timespec *uts, size_t sigsetsize);
  1431. asmlinkage long
  1432. sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
  1433.       struct timespec32 *uts, __kernel_size_t32 sigsetsize)
  1434. {
  1435. sigset_t s;
  1436. sigset32_t s32;
  1437. struct timespec t;
  1438. int ret;
  1439. mm_segment_t old_fs = get_fs();
  1440. siginfo_t info;
  1441. siginfo_t32 info32;
  1442. if (copy_from_user (&s32, uthese, sizeof(sigset32_t)))
  1443. return -EFAULT;
  1444. switch (_NSIG_WORDS) {
  1445. case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
  1446. case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
  1447. case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
  1448. case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
  1449. }
  1450. if (uts) {
  1451. if (verify_area(VERIFY_READ, uts, sizeof(struct timespec32)) ||
  1452.     __get_user (t.tv_sec, &uts->tv_sec) ||
  1453.     __get_user (t.tv_nsec, &uts->tv_nsec))
  1454. return -EFAULT;
  1455. }
  1456. set_fs (KERNEL_DS);
  1457. ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
  1458. set_fs (old_fs);
  1459. if (ret >= 0 && uinfo) {
  1460. if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
  1461.   sizeof(siginfo_t32)))
  1462. return -EFAULT;
  1463. }
  1464. return ret;
  1465. }
  1466. extern asmlinkage long
  1467. sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
  1468. asmlinkage long
  1469. sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
  1470. {
  1471. siginfo_t info;
  1472. siginfo_t32 info32;
  1473. int ret;
  1474. mm_segment_t old_fs = get_fs();
  1475. if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))
  1476. return -EFAULT;
  1477. /* XXX: Is this correct? */
  1478. siginfo32to64(&info, &info32);
  1479. set_fs (KERNEL_DS);
  1480. ret = sys_rt_sigqueueinfo(pid, sig, &info);
  1481. set_fs (old_fs);
  1482. return ret;
  1483. }
  1484. extern void check_pending(int signum);
  1485. asmlinkage long sys_utimes(char *, struct timeval *);
  1486. asmlinkage long
  1487. sys32_utimes(char *filename, struct timeval32 *tvs)
  1488. {
  1489. char *kfilename;
  1490. struct timeval ktvs[2];
  1491. mm_segment_t old_fs;
  1492. int ret;
  1493. kfilename = getname(filename);
  1494. ret = PTR_ERR(kfilename);
  1495. if (!IS_ERR(kfilename)) {
  1496. if (tvs) {
  1497. if (get_tv32(&ktvs[0], tvs) ||
  1498.     get_tv32(&ktvs[1], 1+tvs))
  1499. return -EFAULT;
  1500. }
  1501. old_fs = get_fs();
  1502. set_fs(KERNEL_DS);
  1503. ret = sys_utimes(kfilename, &ktvs[0]);
  1504. set_fs(old_fs);
  1505. putname(kfilename);
  1506. }
  1507. return ret;
  1508. }
  1509. /* These are here just in case some old ia32 binary calls it. */
  1510. asmlinkage long
  1511. sys32_pause(void)
  1512. {
  1513. current->state = TASK_INTERRUPTIBLE;
  1514. schedule();
  1515. return -ERESTARTNOHAND;
  1516. }
  1517. struct sysctl_ia32 {
  1518. unsigned int name;
  1519. int nlen;
  1520. unsigned int oldval;
  1521. unsigned int oldlenp;
  1522. unsigned int newval;
  1523. unsigned int newlen;
  1524. unsigned int __unused[4];
  1525. };
  1526. asmlinkage long
  1527. sys32_sysctl(struct sysctl_ia32 *args32)
  1528. {
  1529. #ifndef CONFIG_SYSCTL
  1530. return -ENOSYS; 
  1531. #else
  1532. struct sysctl_ia32 a32;
  1533. mm_segment_t old_fs = get_fs ();
  1534. void *oldvalp, *newvalp;
  1535. size_t oldlen;
  1536. int *namep;
  1537. long ret;
  1538. extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
  1539.      void *newval, size_t newlen);
  1540. if (copy_from_user(&a32, args32, sizeof (a32)))
  1541. return -EFAULT;
  1542. /*
  1543.  * We need to pre-validate these because we have to disable address checking
  1544.  * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
  1545.  * user specifying bad addresses here.  Well, since we're dealing with 32 bit
  1546.  * addresses, we KNOW that access_ok() will always succeed, so this is an
  1547.  * expensive NOP, but so what...
  1548.  */
  1549. namep = (int *) A(a32.name);
  1550. oldvalp = (void *) A(a32.oldval);
  1551. newvalp = (void *) A(a32.newval);
  1552. if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
  1553.     || !access_ok(VERIFY_WRITE, namep, 0)
  1554.     || !access_ok(VERIFY_WRITE, oldvalp, 0)
  1555.     || !access_ok(VERIFY_WRITE, newvalp, 0))
  1556. return -EFAULT;
  1557. set_fs(KERNEL_DS);
  1558. lock_kernel();
  1559. ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
  1560. unlock_kernel();
  1561. set_fs(old_fs);
  1562. if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
  1563. return -EFAULT;
  1564. return ret;
  1565. #endif
  1566. }
  1567. extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
  1568.     size_t count, loff_t pos);
  1569. extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
  1570.      size_t count, loff_t pos);
  1571. typedef __kernel_ssize_t32 ssize_t32;
  1572. /* warning: next two assume little endian */ 
  1573. asmlinkage ssize_t32
  1574. sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,
  1575.     u32 poslo, u32 poshi)
  1576. {
  1577. return sys_pread(fd, ubuf, count,
  1578.  ((loff_t)AA(poshi) << 32) | AA(poslo));
  1579. }
  1580. asmlinkage ssize_t32
  1581. sys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count,
  1582.      u32 poslo, u32 poshi)
  1583. {
  1584. return sys_pwrite(fd, ubuf, count,
  1585.   ((loff_t)AA(poshi) << 32) | AA(poslo));
  1586. }
  1587. extern asmlinkage long sys_personality(unsigned long);
  1588. asmlinkage long
  1589. sys32_personality(unsigned long personality)
  1590. {
  1591. int ret;
  1592. if (personality(current->personality) == PER_LINUX32 && 
  1593. personality == PER_LINUX)
  1594. personality = PER_LINUX32;
  1595. ret = sys_personality(personality);
  1596. if (ret == PER_LINUX32)
  1597. ret = PER_LINUX;
  1598. return ret;
  1599. }
  1600. extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
  1601.        size_t count); 
  1602. asmlinkage long
  1603. sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
  1604. {
  1605. mm_segment_t old_fs = get_fs();
  1606. int ret;
  1607. off_t of;
  1608. if (offset && get_user(of, offset))
  1609. return -EFAULT;
  1610. set_fs(KERNEL_DS);
  1611. ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
  1612. set_fs(old_fs);
  1613. if (!ret && offset && put_user(of, offset))
  1614. return -EFAULT;
  1615. return ret;
  1616. }
  1617. /* Handle adjtimex compatability. */
  1618. struct timex32 {
  1619. u32 modes;
  1620. s32 offset, freq, maxerror, esterror;
  1621. s32 status, constant, precision, tolerance;
  1622. struct timeval32 time;
  1623. s32 tick;
  1624. s32 ppsfreq, jitter, shift, stabil;
  1625. s32 jitcnt, calcnt, errcnt, stbcnt;
  1626. s32  :32; s32  :32; s32  :32; s32  :32;
  1627. s32  :32; s32  :32; s32  :32; s32  :32;
  1628. s32  :32; s32  :32; s32  :32; s32  :32;
  1629. };
  1630. extern int do_adjtimex(struct timex *);
  1631. asmlinkage long
  1632. sys32_adjtimex(struct timex32 *utp)
  1633. {
  1634. struct timex txc;
  1635. int ret;
  1636. memset(&txc, 0, sizeof(struct timex));
  1637. if(verify_area(VERIFY_READ, utp, sizeof(struct timex32)) ||
  1638.    __get_user(txc.modes, &utp->modes) ||
  1639.    __get_user(txc.offset, &utp->offset) ||
  1640.    __get_user(txc.freq, &utp->freq) ||
  1641.    __get_user(txc.maxerror, &utp->maxerror) ||
  1642.    __get_user(txc.esterror, &utp->esterror) ||
  1643.    __get_user(txc.status, &utp->status) ||
  1644.    __get_user(txc.constant, &utp->constant) ||
  1645.    __get_user(txc.precision, &utp->precision) ||
  1646.    __get_user(txc.tolerance, &utp->tolerance) ||
  1647.    __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
  1648.    __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
  1649.    __get_user(txc.tick, &utp->tick) ||
  1650.    __get_user(txc.ppsfreq, &utp->ppsfreq) ||
  1651.    __get_user(txc.jitter, &utp->jitter) ||
  1652.    __get_user(txc.shift, &utp->shift) ||
  1653.    __get_user(txc.stabil, &utp->stabil) ||
  1654.    __get_user(txc.jitcnt, &utp->jitcnt) ||
  1655.    __get_user(txc.calcnt, &utp->calcnt) ||
  1656.    __get_user(txc.errcnt, &utp->errcnt) ||
  1657.    __get_user(txc.stbcnt, &utp->stbcnt))
  1658. return -EFAULT;
  1659. ret = do_adjtimex(&txc);
  1660. if(verify_area(VERIFY_WRITE, utp, sizeof(struct timex32)) ||
  1661.    __put_user(txc.modes, &utp->modes) ||
  1662.    __put_user(txc.offset, &utp->offset) ||
  1663.    __put_user(txc.freq, &utp->freq) ||
  1664.    __put_user(txc.maxerror, &utp->maxerror) ||
  1665.    __put_user(txc.esterror, &utp->esterror) ||
  1666.    __put_user(txc.status, &utp->status) ||
  1667.    __put_user(txc.constant, &utp->constant) ||
  1668.    __put_user(txc.precision, &utp->precision) ||
  1669.    __put_user(txc.tolerance, &utp->tolerance) ||
  1670.    __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
  1671.    __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
  1672.    __put_user(txc.tick, &utp->tick) ||
  1673.    __put_user(txc.ppsfreq, &utp->ppsfreq) ||
  1674.    __put_user(txc.jitter, &utp->jitter) ||
  1675.    __put_user(txc.shift, &utp->shift) ||
  1676.    __put_user(txc.stabil, &utp->stabil) ||
  1677.    __put_user(txc.jitcnt, &utp->jitcnt) ||
  1678.    __put_user(txc.calcnt, &utp->calcnt) ||
  1679.    __put_user(txc.errcnt, &utp->errcnt) ||
  1680.    __put_user(txc.stbcnt, &utp->stbcnt))
  1681. ret = -EFAULT;
  1682. return ret;
  1683. }
  1684. /* common code for old and new mmaps */
  1685. static inline long do_mmap2(
  1686. unsigned long addr, unsigned long len,
  1687. unsigned long prot, unsigned long flags,
  1688. unsigned long fd, unsigned long pgoff)
  1689. {
  1690. int error = -EBADF;
  1691. struct file * file = NULL;
  1692. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  1693. if (!(flags & MAP_ANONYMOUS)) {
  1694. file = fget(fd);
  1695. if (!file)
  1696. goto out;
  1697. }
  1698. down_write(&current->mm->mmap_sem);
  1699. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  1700. up_write(&current->mm->mmap_sem);
  1701. if (file)
  1702. fput(file);
  1703. out:
  1704. return error;
  1705. }
  1706. asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
  1707. unsigned long prot, unsigned long flags,
  1708. unsigned long fd, unsigned long pgoff)
  1709. {
  1710. return do_mmap2(addr, len, prot, flags, fd, pgoff);
  1711. }
  1712. asmlinkage long sys32_olduname(struct oldold_utsname * name)
  1713. {
  1714. int error;
  1715. if (!name)
  1716. return -EFAULT;
  1717. if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
  1718. return -EFAULT;
  1719.   
  1720.    down_read(&uts_sem);
  1721. error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
  1722.  __put_user(0,name->sysname+__OLD_UTS_LEN);
  1723.  __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
  1724.  __put_user(0,name->nodename+__OLD_UTS_LEN);
  1725.  __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
  1726.  __put_user(0,name->release+__OLD_UTS_LEN);
  1727.  __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
  1728.  __put_user(0,name->version+__OLD_UTS_LEN);
  1729.  { 
  1730.  char *arch = (personality(current->personality) == PER_LINUX32)
  1731.  ? "i686" : "x86_64"; 
  1732.  
  1733.  __copy_to_user(&name->machine,arch,strlen(arch)+1);
  1734.  }
  1735.  up_read(&uts_sem);
  1736.  
  1737.  error = error ? -EFAULT : 0;
  1738.  
  1739.  return error;
  1740. }
  1741. asmlinkage long sys32_uname(struct old_utsname * name)
  1742. {
  1743. int err;
  1744. down_read(&uts_sem);
  1745. err=copy_to_user(name, &system_utsname, sizeof (*name));
  1746. up_read(&uts_sem);
  1747. if (personality(current->personality) == PER_LINUX32)
  1748. err = copy_to_user(name->machine, "i686", 5);
  1749. return err?-EFAULT:0;
  1750. }
  1751. extern int sys_ustat(dev_t, struct ustat *);
  1752. int sys32_ustat(dev_t dev, struct ustat32 *u32p)
  1753. {
  1754. struct ustat u;
  1755. mm_segment_t seg;
  1756. int ret;
  1757. seg = get_fs(); 
  1758. set_fs(KERNEL_DS); 
  1759. ret = sys_ustat(dev,&u); 
  1760. set_fs(seg);
  1761. if (ret >= 0) { 
  1762. if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || 
  1763.     __put_user((__u32) u.f_tfree, &u32p->f_tfree) ||
  1764.     __put_user((__u32) u.f_tinode, &u32p->f_tfree) ||
  1765.     __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) ||
  1766.     __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack)))
  1767. ret = -EFAULT;
  1768. }
  1769. return ret;
  1770. static int nargs(u32 src, char **dst) 
  1771. int cnt;
  1772. u32 val; 
  1773. cnt = 0; 
  1774. do { 
  1775. int ret = get_user(val, (__u32 *)(u64)src); 
  1776. if (ret)
  1777. return ret;
  1778. if (dst)
  1779. dst[cnt] = (char *)(u64)val; 
  1780. cnt++;
  1781. src += 4;
  1782. if (cnt >= (MAX_ARG_PAGES*PAGE_SIZE)/sizeof(void*))
  1783. return -E2BIG; 
  1784. } while(val); 
  1785. if (dst)
  1786. dst[cnt-1] = 0; 
  1787. return cnt; 
  1788. int sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs)
  1789. mm_segment_t oldseg; 
  1790. char **buf; 
  1791. int na,ne;
  1792. int ret;
  1793. unsigned sz; 
  1794. na = nargs(argv, NULL); 
  1795. if (na < 0) 
  1796. return -EFAULT; 
  1797. ne = nargs(envp, NULL); 
  1798. if (ne < 0) 
  1799. return -EFAULT; 
  1800. sz = (na+ne)*sizeof(void *); 
  1801. if (sz > PAGE_SIZE) 
  1802. buf = vmalloc(sz); 
  1803. else
  1804. buf = kmalloc(sz, GFP_KERNEL); 
  1805. if (!buf)
  1806. return -ENOMEM; 
  1807. ret = nargs(argv, buf);
  1808. if (ret < 0)
  1809. goto free;
  1810. ret = nargs(envp, buf + na); 
  1811. if (ret < 0)
  1812. goto free; 
  1813. name = getname(name); 
  1814. ret = PTR_ERR(name); 
  1815. if (IS_ERR(name))
  1816. goto free; 
  1817. oldseg = get_fs(); 
  1818. set_fs(KERNEL_DS);
  1819. ret = do_execve(name, buf, buf+na, &regs);  
  1820. set_fs(oldseg); 
  1821. if (ret == 0)
  1822. current->ptrace &= ~PT_DTRACE;
  1823. putname(name);
  1824.  
  1825. free:
  1826. if (sz > PAGE_SIZE)
  1827. vfree(buf); 
  1828. else
  1829. kfree(buf);
  1830. return ret; 
  1831. asmlinkage int sys32_fork(struct pt_regs regs)
  1832. {
  1833. return do_fork(SIGCHLD, regs.rsp, &regs, 0);
  1834. }
  1835. asmlinkage int sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
  1836. {
  1837. if (!newsp)
  1838. newsp = regs.rsp;
  1839. return do_fork(clone_flags, newsp, &regs, 0);
  1840. }
  1841. /*
  1842.  * This is trivial, and on the face of it looks like it
  1843.  * could equally well be done in user mode.
  1844.  *
  1845.  * Not so, for quite unobvious reasons - register pressure.
  1846.  * In user mode vfork() cannot have a stack frame, and if
  1847.  * done by calling the "clone()" system call directly, you
  1848.  * do not have enough call-clobbered registers to hold all
  1849.  * the information you need.
  1850.  */
  1851. asmlinkage int sys32_vfork(struct pt_regs regs)
  1852. {
  1853. return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0);
  1854. }
  1855. /*
  1856.  * Some system calls that need sign extended arguments. This could be done by a generic wrapper.
  1857.  */ 
  1858. extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
  1859. int sys32_lseek (unsigned int fd, int offset, unsigned int whence)
  1860. {
  1861. return sys_lseek(fd, offset, whence);
  1862. }
  1863. extern int sys_kill(pid_t pid, int sig); 
  1864. int sys32_kill(int pid, int sig)
  1865. {
  1866. return sys_kill(pid, sig);
  1867. }
  1868.  
  1869. #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
  1870. /* Stuff for NFS server syscalls... */
  1871. struct nfsctl_svc32 {
  1872. u16 svc32_port;
  1873. s32 svc32_nthreads;
  1874. };
  1875. struct nfsctl_client32 {
  1876. s8 cl32_ident[NFSCLNT_IDMAX+1];
  1877. s32 cl32_naddr;
  1878. struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
  1879. s32 cl32_fhkeytype;
  1880. s32 cl32_fhkeylen;
  1881. u8 cl32_fhkey[NFSCLNT_KEYMAX];
  1882. };
  1883. struct nfsctl_export32 {
  1884. s8 ex32_client[NFSCLNT_IDMAX+1];
  1885. s8 ex32_path[NFS_MAXPATHLEN+1];
  1886. __kernel_dev_t32 ex32_dev;
  1887. __kernel_ino_t32 ex32_ino;
  1888. s32 ex32_flags;
  1889. __kernel_uid_t32 ex32_anon_uid;
  1890. __kernel_gid_t32 ex32_anon_gid;
  1891. };
  1892. struct nfsctl_uidmap32 {
  1893. u32 ug32_ident;   /* char * */
  1894. __kernel_uid_t32 ug32_uidbase;
  1895. s32 ug32_uidlen;
  1896. u32 ug32_udimap;  /* uid_t * */
  1897. __kernel_uid_t32 ug32_gidbase;
  1898. s32 ug32_gidlen;
  1899. u32 ug32_gdimap;  /* gid_t * */
  1900. };
  1901. struct nfsctl_fhparm32 {
  1902. struct sockaddr gf32_addr;
  1903. __kernel_dev_t32 gf32_dev;
  1904. __kernel_ino_t32 gf32_ino;
  1905. s32 gf32_version;
  1906. };
  1907. struct nfsctl_fdparm32 {
  1908. struct sockaddr gd32_addr;
  1909. s8 gd32_path[NFS_MAXPATHLEN+1];
  1910. s32 gd32_version;
  1911. };
  1912. struct nfsctl_fsparm32 {
  1913. struct sockaddr gd32_addr;
  1914. s8 gd32_path[NFS_MAXPATHLEN+1];
  1915. s32 gd32_maxlen;
  1916. };
  1917. struct nfsctl_arg32 {
  1918. s32 ca32_version; /* safeguard */
  1919. union {
  1920. struct nfsctl_svc32 u32_svc;
  1921. struct nfsctl_client32 u32_client;
  1922. struct nfsctl_export32 u32_export;
  1923. struct nfsctl_uidmap32 u32_umap;
  1924. struct nfsctl_fhparm32 u32_getfh;
  1925. struct nfsctl_fdparm32 u32_getfd;
  1926. struct nfsctl_fsparm32 u32_getfs;
  1927. } u;
  1928. #define ca32_svc u.u32_svc
  1929. #define ca32_client u.u32_client
  1930. #define ca32_export u.u32_export
  1931. #define ca32_umap u.u32_umap
  1932. #define ca32_getfh u.u32_getfh
  1933. #define ca32_getfd u.u32_getfd
  1934. #define ca32_getfs u.u32_getfs
  1935. #define ca32_authd u.u32_authd
  1936. };
  1937. union nfsctl_res32 {
  1938. __u8 cr32_getfh[NFS_FHSIZE];
  1939. struct knfsd_fh cr32_getfs;
  1940. };
  1941. static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  1942. {
  1943. int err;
  1944. err = get_user(karg->ca_version, &arg32->ca32_version);
  1945. err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
  1946. err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
  1947. return err;
  1948. }
  1949. static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  1950. {
  1951. int err;
  1952. err = get_user(karg->ca_version, &arg32->ca32_version);
  1953. err |= copy_from_user(&karg->ca_client.cl_ident[0],
  1954.   &arg32->ca32_client.cl32_ident[0],
  1955.   NFSCLNT_IDMAX);
  1956. err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
  1957. err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
  1958.   &arg32->ca32_client.cl32_addrlist[0],
  1959.   (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
  1960. err |= __get_user(karg->ca_client.cl_fhkeytype,
  1961.       &arg32->ca32_client.cl32_fhkeytype);
  1962. err |= __get_user(karg->ca_client.cl_fhkeylen,
  1963.       &arg32->ca32_client.cl32_fhkeylen);
  1964. err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
  1965.   &arg32->ca32_client.cl32_fhkey[0],
  1966.   NFSCLNT_KEYMAX);
  1967. return err;
  1968. }
  1969. static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  1970. {
  1971. int err;
  1972. err = get_user(karg->ca_version, &arg32->ca32_version);
  1973. err |= copy_from_user(&karg->ca_export.ex_client[0],
  1974.   &arg32->ca32_export.ex32_client[0],
  1975.   NFSCLNT_IDMAX);
  1976. err |= copy_from_user(&karg->ca_export.ex_path[0],
  1977.   &arg32->ca32_export.ex32_path[0],
  1978.   NFS_MAXPATHLEN);
  1979. err |= __get_user(karg->ca_export.ex_dev,
  1980.       &arg32->ca32_export.ex32_dev);
  1981. err |= __get_user(karg->ca_export.ex_ino,
  1982.       &arg32->ca32_export.ex32_ino);
  1983. err |= __get_user(karg->ca_export.ex_flags,
  1984.       &arg32->ca32_export.ex32_flags);
  1985. err |= __get_user(karg->ca_export.ex_anon_uid,
  1986.       &arg32->ca32_export.ex32_anon_uid);
  1987. err |= __get_user(karg->ca_export.ex_anon_gid,
  1988.       &arg32->ca32_export.ex32_anon_gid);
  1989. karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
  1990. karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
  1991. return err;
  1992. }
  1993. static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  1994. {
  1995. u32 uaddr;
  1996. int i;
  1997. int err;
  1998. memset(karg, 0, sizeof(*karg));
  1999. if(get_user(karg->ca_version, &arg32->ca32_version))
  2000. return -EFAULT;
  2001. karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
  2002. if(!karg->ca_umap.ug_ident)
  2003. return -ENOMEM;
  2004. err = get_user(uaddr, &arg32->ca32_umap.ug32_ident);
  2005. if(strncpy_from_user(karg->ca_umap.ug_ident,
  2006.      (char *)A(uaddr), PAGE_SIZE) <= 0)
  2007. return -EFAULT;
  2008. err |= __get_user(karg->ca_umap.ug_uidbase,
  2009.       &arg32->ca32_umap.ug32_uidbase);
  2010. err |= __get_user(karg->ca_umap.ug_uidlen,
  2011.       &arg32->ca32_umap.ug32_uidlen);
  2012. err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
  2013. if (err)
  2014. return -EFAULT;
  2015. karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
  2016.   GFP_USER);
  2017. if(!karg->ca_umap.ug_udimap)
  2018. return -ENOMEM;
  2019. for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
  2020. err |= __get_user(karg->ca_umap.ug_udimap[i],
  2021.       &(((__kernel_uid_t32 *)A(uaddr))[i]));
  2022. err |= __get_user(karg->ca_umap.ug_gidbase,
  2023.       &arg32->ca32_umap.ug32_gidbase);
  2024. err |= __get_user(karg->ca_umap.ug_uidlen,
  2025.       &arg32->ca32_umap.ug32_gidlen);
  2026. err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
  2027. if (err)
  2028. return -EFAULT;
  2029. karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
  2030.   GFP_USER);
  2031. if(!karg->ca_umap.ug_gdimap)
  2032. return -ENOMEM;
  2033. for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
  2034. err |= __get_user(karg->ca_umap.ug_gdimap[i],
  2035.       &(((__kernel_gid_t32 *)A(uaddr))[i]));
  2036. return err;
  2037. }
  2038. static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  2039. {
  2040. int err;
  2041. err = get_user(karg->ca_version, &arg32->ca32_version);
  2042. err |= copy_from_user(&karg->ca_getfh.gf_addr,
  2043.   &arg32->ca32_getfh.gf32_addr,
  2044.   (sizeof(struct sockaddr)));
  2045. err |= __get_user(karg->ca_getfh.gf_dev,
  2046.       &arg32->ca32_getfh.gf32_dev);
  2047. err |= __get_user(karg->ca_getfh.gf_ino,
  2048.       &arg32->ca32_getfh.gf32_ino);
  2049. err |= __get_user(karg->ca_getfh.gf_version,
  2050.       &arg32->ca32_getfh.gf32_version);
  2051. return err;
  2052. }
  2053. static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  2054. {
  2055. int err;
  2056. err = get_user(karg->ca_version, &arg32->ca32_version);
  2057. err |= copy_from_user(&karg->ca_getfd.gd_addr,
  2058.   &arg32->ca32_getfd.gd32_addr,
  2059.   (sizeof(struct sockaddr)));
  2060. err |= copy_from_user(&karg->ca_getfd.gd_path,
  2061.   &arg32->ca32_getfd.gd32_path,
  2062.   (NFS_MAXPATHLEN+1));
  2063. err |= get_user(karg->ca_getfd.gd_version,
  2064.       &arg32->ca32_getfd.gd32_version);
  2065. return err;
  2066. }
  2067. static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
  2068. {
  2069. int err;
  2070. err = get_user(karg->ca_version, &arg32->ca32_version);
  2071. err |= copy_from_user(&karg->ca_getfs.gd_addr,
  2072.   &arg32->ca32_getfs.gd32_addr,
  2073.   (sizeof(struct sockaddr)));
  2074. err |= copy_from_user(&karg->ca_getfs.gd_path,
  2075.   &arg32->ca32_getfs.gd32_path,
  2076.   (NFS_MAXPATHLEN+1));
  2077. err |= get_user(karg->ca_getfs.gd_maxlen,
  2078.       &arg32->ca32_getfs.gd32_maxlen);
  2079. return err;
  2080. }
  2081. /* This really doesn't need translations, we are only passing
  2082.  * back a union which contains opaque nfs file handle data.
  2083.  */
  2084. static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
  2085. {
  2086. return copy_to_user(res32, kres, sizeof(*res32));
  2087. }
  2088. int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
  2089. {
  2090. struct nfsctl_arg *karg = NULL;
  2091. union nfsctl_res *kres = NULL;
  2092. mm_segment_t oldfs;
  2093. int err;
  2094. karg = kmalloc(sizeof(*karg), GFP_USER);
  2095. if(!karg)
  2096. return -ENOMEM;
  2097. if(res32) {
  2098. kres = kmalloc(sizeof(*kres), GFP_USER);
  2099. if(!kres) {
  2100. kfree(karg);
  2101. return -ENOMEM;
  2102. }
  2103. }
  2104. switch(cmd) {
  2105. case NFSCTL_SVC:
  2106. err = nfs_svc32_trans(karg, arg32);
  2107. break;
  2108. case NFSCTL_ADDCLIENT:
  2109. err = nfs_clnt32_trans(karg, arg32);
  2110. break;
  2111. case NFSCTL_DELCLIENT:
  2112. err = nfs_clnt32_trans(karg, arg32);
  2113. break;
  2114. case NFSCTL_EXPORT:
  2115. case NFSCTL_UNEXPORT:
  2116. err = nfs_exp32_trans(karg, arg32);
  2117. break;
  2118. /* This one is unimplemented, be we're ready for it. */
  2119. case NFSCTL_UGIDUPDATE:
  2120. err = nfs_uud32_trans(karg, arg32);
  2121. break;
  2122. case NFSCTL_GETFH:
  2123. err = nfs_getfh32_trans(karg, arg32);
  2124. break;
  2125. case NFSCTL_GETFD:
  2126. err = nfs_getfd32_trans(karg, arg32);
  2127. break;
  2128. case NFSCTL_GETFS:
  2129. err = nfs_getfs32_trans(karg, arg32);
  2130. break;
  2131. default:
  2132. err = -EINVAL;
  2133. break;
  2134. }
  2135. if(err)
  2136. goto done;
  2137. oldfs = get_fs();
  2138. set_fs(KERNEL_DS);
  2139. err = sys_nfsservctl(cmd, karg, kres);
  2140. set_fs(oldfs);
  2141. if (err)
  2142. goto done;
  2143. if((cmd == NFSCTL_GETFH) ||
  2144.    (cmd == NFSCTL_GETFD) ||
  2145.    (cmd == NFSCTL_GETFS))
  2146. err = nfs_getfh32_res_trans(kres, res32);
  2147. done:
  2148. if(karg) {
  2149. if(cmd == NFSCTL_UGIDUPDATE) {
  2150. if(karg->ca_umap.ug_ident)
  2151. kfree(karg->ca_umap.ug_ident);
  2152. if(karg->ca_umap.ug_udimap)
  2153. kfree(karg->ca_umap.ug_udimap);
  2154. if(karg->ca_umap.ug_gdimap)
  2155. kfree(karg->ca_umap.ug_gdimap);
  2156. }
  2157. kfree(karg);
  2158. }
  2159. if(kres)
  2160. kfree(kres);
  2161. return err;
  2162. }
  2163. #else /* !NFSD */
  2164. extern asmlinkage long sys_ni_syscall(void);
  2165. int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
  2166. {
  2167. return sys_ni_syscall();
  2168. }
  2169. #endif
  2170. int sys32_module_warning(void)
  2171. static long warn_time = -(60*HZ); 
  2172. if (time_before(warn_time + 60*HZ,jiffies) && strcmp(current->comm,"klogd")) { 
  2173. printk(KERN_INFO "%s: 32bit modutils not supported on 64bit kerneln",
  2174.        current->comm);
  2175. warn_time = jiffies;
  2176. return -ENOSYS ;
  2177. struct exec_domain ia32_exec_domain = { 
  2178. name: "linux/x86",
  2179. pers_low: PER_LINUX32,
  2180. pers_high: PER_LINUX32,
  2181. };      
  2182. static int __init ia32_init (void)
  2183. {
  2184. printk("IA32 emulation $Id: sys_ia32.c,v 1.42 2002/09/17 15:23:41 ak Exp $n");  
  2185. ia32_exec_domain.signal_map = default_exec_domain.signal_map;
  2186. ia32_exec_domain.signal_invmap = default_exec_domain.signal_invmap;
  2187. register_exec_domain(&ia32_exec_domain);
  2188. return 0;
  2189. }
  2190. __initcall(ia32_init);