[PATCH] x86_64 merge: arch + asm
[opensuse:kernel.git] / arch / x86_64 / ia32 / sys_ia32.c
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  */
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 <asm/mman.h>
56 #include <asm/types.h>
57 #include <asm/uaccess.h>
58 #include <asm/semaphore.h>
59 #include <asm/ipc.h>
60 #include <asm/atomic.h>
61
62 #include <net/scm.h>
63 #include <net/sock.h>
64 #include <asm/ia32.h>
65
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
71 static int
72 putstat(struct stat32 *ubuf, struct stat *kbuf)
73 {
74         if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat32)) ||
75             __put_user (kbuf->st_dev, &ubuf->st_dev) ||
76             __put_user (kbuf->st_ino, &ubuf->st_ino) ||
77             __put_user (kbuf->st_mode, &ubuf->st_mode) ||
78             __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
79             __put_user (kbuf->st_uid, &ubuf->st_uid) ||
80             __put_user (kbuf->st_gid, &ubuf->st_gid) ||
81             __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
82             __put_user (kbuf->st_size, &ubuf->st_size) ||
83             __put_user (kbuf->st_atime, &ubuf->st_atime) ||
84             __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
85             __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
86             __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
87             __put_user (kbuf->st_blocks, &ubuf->st_blocks))
88                 return -EFAULT;
89         return 0;
90 }
91
92 extern asmlinkage long sys_newstat(char * filename, struct stat * statbuf);
93
94 asmlinkage long
95 sys32_newstat(char * filename, struct stat32 *statbuf)
96 {
97         int ret;
98         struct stat s;
99         mm_segment_t old_fs = get_fs();
100         
101         set_fs (KERNEL_DS);
102         ret = sys_newstat(filename, &s);
103         set_fs (old_fs);
104         if (putstat (statbuf, &s))
105                 return -EFAULT;
106         return ret;
107 }
108
109 extern asmlinkage long sys_newlstat(char * filename, struct stat * statbuf);
110
111 asmlinkage long
112 sys32_newlstat(char * filename, struct stat32 *statbuf)
113 {
114         int ret;
115         struct stat s;
116         mm_segment_t old_fs = get_fs();
117         
118         set_fs (KERNEL_DS);
119         ret = sys_newlstat(filename, &s);
120         set_fs (old_fs);
121         if (putstat (statbuf, &s))
122                 return -EFAULT;
123         return ret;
124 }
125
126 extern asmlinkage long sys_newfstat(unsigned int fd, struct stat * statbuf);
127
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         
135         set_fs (KERNEL_DS);
136         ret = sys_newfstat(fd, &s);
137         set_fs (old_fs);
138         if (putstat (statbuf, &s))
139                 return -EFAULT;
140         return ret;
141 }
142
143 /* Another set for IA32/LFS -- x86_64 struct stat is different due to 
144    support for 64bit inode numbers. */
145
146 static int
147 putstat64(struct stat64 *ubuf, struct stat *kbuf)
148 {
149         if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) ||
150             __put_user (kbuf->st_dev, &ubuf->st_dev) ||
151             __put_user (kbuf->st_ino, &ubuf->__st_ino) ||
152             __put_user (kbuf->st_ino, &ubuf->st_ino) ||
153             __put_user (kbuf->st_mode, &ubuf->st_mode) ||
154             __put_user (kbuf->st_nlink, &ubuf->st_nlink) ||
155             __put_user (kbuf->st_uid, &ubuf->st_uid) ||
156             __put_user (kbuf->st_gid, &ubuf->st_gid) ||
157             __put_user (kbuf->st_rdev, &ubuf->st_rdev) ||
158             __put_user (kbuf->st_size, &ubuf->st_size) ||
159             __put_user (kbuf->st_atime, &ubuf->st_atime) ||
160             __put_user (kbuf->st_mtime, &ubuf->st_mtime) ||
161             __put_user (kbuf->st_ctime, &ubuf->st_ctime) ||
162             __put_user (kbuf->st_blksize, &ubuf->st_blksize) ||
163             __put_user (kbuf->st_blocks, &ubuf->st_blocks))
164                 return -EFAULT;
165         return 0;
166 }
167
168 asmlinkage long
169 sys32_stat64(char * filename, struct stat64 *statbuf)
170 {
171         int ret;
172         struct stat s;
173         mm_segment_t old_fs = get_fs();
174         
175         set_fs (KERNEL_DS);
176         ret = sys_newstat(filename, &s);
177         set_fs (old_fs);
178         if (putstat64 (statbuf, &s))
179                 return -EFAULT;
180         return ret;
181 }
182
183 asmlinkage long
184 sys32_lstat64(char * filename, struct stat64 *statbuf)
185 {
186         int ret;
187         struct stat s;
188         mm_segment_t old_fs = get_fs();
189         
190         set_fs (KERNEL_DS);
191         ret = sys_newlstat(filename, &s);
192         set_fs (old_fs);
193         if (putstat64 (statbuf, &s))
194                 return -EFAULT;
195         return ret;
196 }
197
198 asmlinkage long
199 sys32_fstat64(unsigned int fd, struct stat64 *statbuf)
200 {
201         int ret;
202         struct stat s;
203         mm_segment_t old_fs = get_fs();
204         
205         set_fs (KERNEL_DS);
206         ret = sys_newfstat(fd, &s);
207         set_fs (old_fs);
208         if (putstat64 (statbuf, &s))
209                 return -EFAULT;
210         return ret;
211 }
212
213
214
215 /*
216  * Linux/i386 didn't use to be able to handle more than
217  * 4 system call parameters, so these system calls used a memory
218  * block for parameter passing..
219  */
220
221 struct mmap_arg_struct {
222         unsigned int addr;
223         unsigned int len;
224         unsigned int prot;
225         unsigned int flags;
226         unsigned int fd;
227         unsigned int offset;
228 };
229
230 asmlinkage __u32
231 sys32_mmap(struct mmap_arg_struct *arg)
232 {
233         struct mmap_arg_struct a;
234         struct file *file = NULL;
235         unsigned long retval;
236         struct mm_struct *mm ;
237
238         if (copy_from_user(&a, arg, sizeof(a)))
239                 return -EFAULT;
240
241         if (a.offset & ~PAGE_MASK)
242                 return -EINVAL; 
243
244         if (!(a.flags & MAP_ANONYMOUS)) {
245                 file = fget(a.fd);
246                 if (!file)
247                         return -EBADF;
248         }
249
250         mm = current->mm; 
251         down_write(&mm->mmap_sem); 
252         retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT);
253         if (file)
254                 fput(file);
255
256         if (retval >= 0xFFFFFFFF) { 
257                 do_munmap(mm, retval, a.len); 
258                 retval = -ENOMEM; 
259         } 
260         up_write(&mm->mmap_sem); 
261
262
263
264         return retval;
265 }
266
267 asmlinkage long
268 sys32_pipe(int *fd)
269 {
270         int retval;
271         int fds[2];
272
273         retval = do_pipe(fds);
274         if (retval)
275                 goto out;
276         if (copy_to_user(fd, fds, sizeof(fds)))
277                 retval = -EFAULT;
278   out:
279         return retval;
280 }
281
282 asmlinkage long
283 sys32_rt_sigaction(int sig, struct sigaction32 *act,
284                    struct sigaction32 *oact,  unsigned int sigsetsize)
285 {
286         struct k_sigaction new_ka, old_ka;
287         int ret;
288         sigset32_t set32;
289
290         /* XXX: Don't preclude handling different sized sigset_t's.  */
291         if (sigsetsize != sizeof(sigset32_t))
292                 return -EINVAL;
293
294         if (act) {
295                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
296                     __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
297                     __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
298                     __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer)||
299                     __copy_from_user(&set32, &act->sa_mask, sizeof(sigset32_t)))
300                         return -EFAULT;
301
302                 /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
303                 switch (_NSIG_WORDS) {
304                 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
305                                 | (((long)set32.sig[7]) << 32);
306                 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
307                                 | (((long)set32.sig[5]) << 32);
308                 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
309                                 | (((long)set32.sig[3]) << 32);
310                 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
311                                 | (((long)set32.sig[1]) << 32);
312                 }
313         }
314
315         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
316
317         if (!ret && oact) {
318                 /* FIXME: here we rely on _IA32_NSIG_WORS to be >= than _NSIG_WORDS << 1 */
319                 switch (_NSIG_WORDS) {
320                 case 4:
321                         set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
322                         set32.sig[6] = old_ka.sa.sa_mask.sig[3];
323                 case 3:
324                         set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
325                         set32.sig[4] = old_ka.sa.sa_mask.sig[2];
326                 case 2:
327                         set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
328                         set32.sig[2] = old_ka.sa.sa_mask.sig[1];
329                 case 1:
330                         set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
331                         set32.sig[0] = old_ka.sa.sa_mask.sig[0];
332                 }
333                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
334                     __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
335                     __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
336                     __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
337                     __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset32_t)))
338                         return -EFAULT;
339         }
340
341         return ret;
342 }
343
344 asmlinkage long
345 sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
346 {
347         struct k_sigaction new_ka, old_ka;
348         int ret;
349
350         if (act) {
351                 old_sigset32_t mask;
352
353                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
354                     __get_user((long)new_ka.sa.sa_handler, &act->sa_handler) ||
355                     __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
356                     __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer) ||
357                     __get_user(mask, &act->sa_mask))
358                         return -EFAULT;
359                 siginitset(&new_ka.sa.sa_mask, mask);
360         }
361
362         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
363
364         if (!ret && oact) {
365                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
366                     __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
367                     __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) ||
368                     __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
369                     __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
370                         return -EFAULT;
371         }
372
373         return ret;
374 }
375
376 extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset,
377                                           size_t sigsetsize);
378
379 asmlinkage long
380 sys32_rt_sigprocmask(int how, sigset32_t *set, sigset32_t *oset,
381                      unsigned int sigsetsize)
382 {
383         sigset_t s;
384         sigset32_t s32;
385         int ret;
386         mm_segment_t old_fs = get_fs();
387         
388         if (set) {
389                 if (copy_from_user (&s32, set, sizeof(sigset32_t)))
390                         return -EFAULT;
391                 switch (_NSIG_WORDS) {
392                 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
393                 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
394                 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
395                 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
396                 }
397         }
398         set_fs (KERNEL_DS);
399         ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL,
400                                  sigsetsize); 
401         set_fs (old_fs);
402         if (ret) return ret;
403         if (oset) {
404                 switch (_NSIG_WORDS) {
405                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
406                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
407                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
408                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
409                 }
410                 if (copy_to_user (oset, &s32, sizeof(sigset32_t)))
411                         return -EFAULT;
412         }
413         return 0;
414 }
415
416 static int
417 put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
418 {
419         if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct statfs32)) ||
420             __put_user (kbuf->f_type, &ubuf->f_type) ||
421             __put_user (kbuf->f_bsize, &ubuf->f_bsize) ||
422             __put_user (kbuf->f_blocks, &ubuf->f_blocks) ||
423             __put_user (kbuf->f_bfree, &ubuf->f_bfree) ||
424             __put_user (kbuf->f_bavail, &ubuf->f_bavail) ||
425             __put_user (kbuf->f_files, &ubuf->f_files) ||
426             __put_user (kbuf->f_ffree, &ubuf->f_ffree) ||
427             __put_user (kbuf->f_namelen, &ubuf->f_namelen) ||
428             __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
429             __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]))
430                 return -EFAULT;
431         return 0;
432 }
433
434 extern asmlinkage long sys_statfs(const char * path, struct statfs * buf);
435
436 asmlinkage long
437 sys32_statfs(const char * path, struct statfs32 *buf)
438 {
439         int ret;
440         struct statfs s;
441         mm_segment_t old_fs = get_fs();
442         
443         set_fs (KERNEL_DS);
444         ret = sys_statfs((const char *)path, &s);
445         set_fs (old_fs);
446         if (put_statfs(buf, &s))
447                 return -EFAULT;
448         return ret;
449 }
450
451 extern asmlinkage long sys_fstatfs(unsigned int fd, struct statfs * buf);
452
453 asmlinkage long
454 sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
455 {
456         int ret;
457         struct statfs s;
458         mm_segment_t old_fs = get_fs();
459         
460         set_fs (KERNEL_DS);
461         ret = sys_fstatfs(fd, &s);
462         set_fs (old_fs);
463         if (put_statfs(buf, &s))
464                 return -EFAULT;
465         return ret;
466 }
467
468 struct timeval32
469 {
470     int tv_sec, tv_usec;
471 };
472
473 struct itimerval32
474 {
475     struct timeval32 it_interval;
476     struct timeval32 it_value;
477 };
478
479 static inline long
480 get_tv32(struct timeval *o, struct timeval32 *i)
481 {
482         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
483                 __get_user(o->tv_sec, &i->tv_sec) ||
484                 __get_user(o->tv_usec, &i->tv_usec));
485         return ENOSYS;
486 }
487
488 static inline long
489 put_tv32(struct timeval32 *o, struct timeval *i)
490 {
491         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
492                 __put_user(i->tv_sec, &o->tv_sec) ||
493                 __put_user(i->tv_usec, &o->tv_usec));
494 }
495
496 static inline long
497 get_it32(struct itimerval *o, struct itimerval32 *i)
498 {
499         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
500                 __get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) ||
501                 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) ||
502                 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) ||
503                 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec));
504         return ENOSYS;
505 }
506
507 static inline long
508 put_it32(struct itimerval32 *o, struct itimerval *i)
509 {
510         return (!access_ok(VERIFY_WRITE, i, sizeof(*i)) ||
511                 __put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) ||
512                 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) ||
513                 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) ||
514                 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec));
515         return ENOSYS;
516 }
517
518 extern int do_getitimer(int which, struct itimerval *value);
519
520 asmlinkage long
521 sys32_getitimer(int which, struct itimerval32 *it)
522 {
523         struct itimerval kit;
524         int error;
525
526         error = do_getitimer(which, &kit);
527         if (!error && put_it32(it, &kit))
528                 error = -EFAULT;
529
530         return error;
531 }
532
533 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
534
535 asmlinkage long
536 sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
537 {
538         struct itimerval kin, kout;
539         int error;
540
541         if (in) {
542                 if (get_it32(&kin, in))
543                         return -EFAULT;
544         } else
545                 memset(&kin, 0, sizeof(kin));
546
547         error = do_setitimer(which, &kin, out ? &kout : NULL);
548         if (error || !out)
549                 return error;
550         if (put_it32(out, &kout))
551                 return -EFAULT;
552
553         return 0;
554
555 }
556 asmlinkage unsigned long 
557 sys32_alarm(unsigned int seconds)
558 {
559         struct itimerval it_new, it_old;
560         unsigned int oldalarm;
561
562         it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
563         it_new.it_value.tv_sec = seconds;
564         it_new.it_value.tv_usec = 0;
565         do_setitimer(ITIMER_REAL, &it_new, &it_old);
566         oldalarm = it_old.it_value.tv_sec;
567         /* ehhh.. We can't return 0 if we have an alarm pending.. */
568         /* And we'd better return too much than too little anyway */
569         if (it_old.it_value.tv_usec)
570                 oldalarm++;
571         return oldalarm;
572 }
573
574 /* Translations due to time_t size differences.  Which affects all
575    sorts of things, like timeval and itimerval.  */
576
577 struct utimbuf_32 {
578         int     atime;
579         int     mtime;
580 };
581
582 extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
583 extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
584
585 asmlinkage long
586 ia32_utime(char * filename, struct utimbuf_32 *times32)
587 {
588         mm_segment_t old_fs = get_fs();
589         struct timeval tv[2];
590         long ret;
591
592         if (times32) {
593                 get_user(tv[0].tv_sec, &times32->atime);
594                 tv[0].tv_usec = 0;
595                 get_user(tv[1].tv_sec, &times32->mtime);
596                 tv[1].tv_usec = 0;
597                 set_fs (KERNEL_DS);
598         } else {
599                 set_fs (KERNEL_DS);
600                 ret = sys_gettimeofday(&tv[0], 0);
601                 if (ret < 0)
602                         goto out;
603                 tv[1] = tv[0];
604         }
605         ret = sys_utimes(filename, tv);
606   out:
607         set_fs (old_fs);
608         return ret;
609 }
610
611 extern struct timezone sys_tz;
612 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
613
614 asmlinkage long
615 sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
616 {
617         if (tv) {
618                 struct timeval ktv;
619                 do_gettimeofday(&ktv);
620                 if (put_tv32(tv, &ktv))
621                         return -EFAULT;
622         }
623         if (tz) {
624                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
625                         return -EFAULT;
626         }
627         return 0;
628 }
629
630 asmlinkage long
631 sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
632 {
633         struct timeval ktv;
634         struct timezone ktz;
635
636         if (tv) {
637                 if (get_tv32(&ktv, tv))
638                         return -EFAULT;
639         }
640         if (tz) {
641                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
642                         return -EFAULT;
643         }
644
645         return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
646 }
647
648 struct linux32_dirent {
649         u32     d_ino;
650         u32     d_off;
651         u16     d_reclen;
652         char    d_name[1];
653 };
654
655 struct old_linux32_dirent {
656         u32     d_ino;
657         u32     d_offset;
658         u16     d_namlen;
659         char    d_name[1];
660 };
661
662 struct getdents32_callback {
663         struct linux32_dirent * current_dir;
664         struct linux32_dirent * previous;
665         int count;
666         int error;
667 };
668
669 struct readdir32_callback {
670         struct old_linux32_dirent * dirent;
671         int count;
672 };
673
674 static int
675 filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
676            unsigned int d_type)
677 {
678         struct linux32_dirent * dirent;
679         struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
680         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
681
682         buf->error = -EINVAL;   /* only used if we fail.. */
683         if (reclen > buf->count)
684                 return -EINVAL;
685         dirent = buf->previous;
686         if (dirent)
687                 put_user(offset, &dirent->d_off);
688         dirent = buf->current_dir;
689         buf->previous = dirent;
690         put_user(ino, &dirent->d_ino);
691         put_user(reclen, &dirent->d_reclen);
692         copy_to_user(dirent->d_name, name, namlen);
693         put_user(0, dirent->d_name + namlen);
694         ((char *) dirent) += reclen;
695         buf->current_dir = dirent;
696         buf->count -= reclen;
697         return 0;
698 }
699
700 asmlinkage long
701 sys32_getdents (unsigned int fd, void * dirent, unsigned int count)
702 {
703         struct file * file;
704         struct linux32_dirent * lastdirent;
705         struct getdents32_callback buf;
706         int error;
707
708         error = -EBADF;
709         file = fget(fd);
710         if (!file)
711                 goto out;
712
713         buf.current_dir = (struct linux32_dirent *) dirent;
714         buf.previous = NULL;
715         buf.count = count;
716         buf.error = 0;
717
718         error = vfs_readdir(file, filldir32, &buf);
719         if (error < 0)
720                 goto out_putf;
721         error = buf.error;
722         lastdirent = buf.previous;
723         if (lastdirent) {
724                 put_user(file->f_pos, &lastdirent->d_off);
725                 error = count - buf.count;
726         }
727
728 out_putf:
729         fput(file);
730 out:
731         return error;
732 }
733
734 static int
735 fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type)
736 {
737         struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
738         struct old_linux32_dirent * dirent;
739
740         if (buf->count)
741                 return -EINVAL;
742         buf->count++;
743         dirent = buf->dirent;
744         put_user(ino, &dirent->d_ino);
745         put_user(offset, &dirent->d_offset);
746         put_user(namlen, &dirent->d_namlen);
747         copy_to_user(dirent->d_name, name, namlen);
748         put_user(0, dirent->d_name + namlen);
749         return 0;
750 }
751
752 asmlinkage long
753 sys32_oldreaddir (unsigned int fd, void * dirent, unsigned int count)
754 {
755         int error;
756         struct file * file;
757         struct readdir32_callback buf;
758
759         error = -EBADF;
760         file = fget(fd);
761         if (!file)
762                 goto out;
763
764         buf.count = 0;
765         buf.dirent = dirent;
766
767         error = vfs_readdir(file, fillonedir32, &buf);
768         if (error >= 0)
769                 error = buf.count;
770         fput(file);
771 out:
772         return error;
773 }
774
775 /*
776  * We can actually return ERESTARTSYS instead of EINTR, but I'd
777  * like to be certain this leads to no problems. So I return
778  * EINTR just for safety.
779  *
780  * Update: ERESTARTSYS breaks at least the xview clock binary, so
781  * I'm trying ERESTARTNOHAND which restart only when you want to.
782  */
783 #define MAX_SELECT_SECONDS \
784         ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
785 #define ROUND_UP_TIME(x,y) (((x)+(y)-1)/(y))
786
787 asmlinkage long
788 sys32_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval32 *tvp32)
789 {
790         fd_set_bits fds;
791         char *bits;
792         long timeout;
793         int ret, size;
794
795         timeout = MAX_SCHEDULE_TIMEOUT;
796         if (tvp32) {
797                 time_t sec, usec;
798
799                 get_user(sec, &tvp32->tv_sec);
800                 get_user(usec, &tvp32->tv_usec);
801
802                 ret = -EINVAL;
803                 if (sec < 0 || usec < 0)
804                         goto out_nofds;
805
806                 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
807                         timeout = ROUND_UP_TIME(usec, 1000000/HZ);
808                         timeout += sec * (unsigned long) HZ;
809                 }
810         }
811
812         ret = -EINVAL;
813         if (n < 0)
814                 goto out_nofds;
815
816         if (n > current->files->max_fdset)
817                 n = current->files->max_fdset;
818
819         /*
820          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
821          * since we used fdset we need to allocate memory in units of
822          * long-words. 
823          */
824         ret = -ENOMEM;
825         size = FDS_BYTES(n);
826         bits = kmalloc(6 * size, GFP_KERNEL);
827         if (!bits)
828                 goto out_nofds;
829         fds.in      = (unsigned long *)  bits;
830         fds.out     = (unsigned long *) (bits +   size);
831         fds.ex      = (unsigned long *) (bits + 2*size);
832         fds.res_in  = (unsigned long *) (bits + 3*size);
833         fds.res_out = (unsigned long *) (bits + 4*size);
834         fds.res_ex  = (unsigned long *) (bits + 5*size);
835
836         if ((ret = get_fd_set(n, inp, fds.in)) ||
837             (ret = get_fd_set(n, outp, fds.out)) ||
838             (ret = get_fd_set(n, exp, fds.ex)))
839                 goto out;
840         zero_fd_set(n, fds.res_in);
841         zero_fd_set(n, fds.res_out);
842         zero_fd_set(n, fds.res_ex);
843
844         ret = do_select(n, &fds, &timeout);
845
846         if (tvp32 && !(current->personality & STICKY_TIMEOUTS)) {
847                 time_t sec = 0, usec = 0;
848                 if (timeout) {
849                         sec = timeout / HZ;
850                         usec = timeout % HZ;
851                         usec *= (1000000/HZ);
852                 }
853                 put_user(sec, (int *)&tvp32->tv_sec);
854                 put_user(usec, (int *)&tvp32->tv_usec);
855         }
856
857         if (ret < 0)
858                 goto out;
859         if (!ret) {
860                 ret = -ERESTARTNOHAND;
861                 if (signal_pending(current))
862                         goto out;
863                 ret = 0;
864         }
865
866         set_fd_set(n, inp, fds.res_in);
867         set_fd_set(n, outp, fds.res_out);
868         set_fd_set(n, exp, fds.res_ex);
869
870 out:
871         kfree(bits);
872 out_nofds:
873         return ret;
874 }
875
876 struct sel_arg_struct {
877         unsigned int n;
878         unsigned int inp;
879         unsigned int outp;
880         unsigned int exp;
881         unsigned int tvp;
882 };
883
884 asmlinkage long
885 sys32_old_select(struct sel_arg_struct *arg)
886 {
887         struct sel_arg_struct a;
888
889         if (copy_from_user(&a, arg, sizeof(a)))
890                 return -EFAULT;
891         return sys32_select(a.n, (fd_set *)A(a.inp), (fd_set *)A(a.outp), (fd_set *)A(a.exp),
892                             (struct timeval32 *)A(a.tvp));
893 }
894
895 struct timespec32 {
896         int     tv_sec;
897         int     tv_nsec;
898 };
899
900 extern asmlinkage long sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp); 
901
902 asmlinkage long
903 sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
904 {
905         struct timespec t;
906         int ret;
907         mm_segment_t old_fs = get_fs ();
908         
909         if (verify_area(VERIFY_READ, rqtp, sizeof(struct timespec32)) ||
910             __get_user (t.tv_sec, &rqtp->tv_sec) ||
911             __get_user (t.tv_nsec, &rqtp->tv_nsec))
912                 return -EFAULT;
913         set_fs (KERNEL_DS);
914         ret = sys_nanosleep(&t, rmtp ? &t : NULL);
915         set_fs (old_fs);
916         if (rmtp && ret == -EINTR) {
917                 if (verify_area(VERIFY_WRITE, rmtp, sizeof(struct timespec32)) ||
918                     __put_user (t.tv_sec, &rmtp->tv_sec) ||
919                     __put_user (t.tv_nsec, &rmtp->tv_nsec))
920                         return -EFAULT;
921         }
922         return ret;
923 }
924
925 asmlinkage ssize_t sys_readv(unsigned long,const struct iovec *,unsigned long);
926 asmlinkage ssize_t sys_writev(unsigned long,const struct iovec *,unsigned long);
927
928 struct iovec *
929 get_iovec32(struct iovec32 *iov32, struct iovec *iov_buf, u32 count, int type)
930 {
931         int i;
932         u32 buf, len;
933         struct iovec *ivp, *iov;
934
935         /* Get the "struct iovec" from user memory */
936
937         if (!count)
938                 return 0;
939         if(verify_area(VERIFY_READ, iov32, sizeof(struct iovec32)*count))
940                 return(struct iovec *)0;
941         if (count > UIO_MAXIOV)
942                 return(struct iovec *)0;
943         if (count > UIO_FASTIOV) {
944                 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
945                 if (!iov)
946                         return((struct iovec *)0);
947         } else
948                 iov = iov_buf;
949
950         ivp = iov;
951         for (i = 0; i < count; i++) {
952                 if (__get_user(len, &iov32->iov_len) ||
953                     __get_user(buf, &iov32->iov_base)) {
954                         if (iov != iov_buf)
955                                 kfree(iov);
956                         return((struct iovec *)0);
957                 }
958                 if (verify_area(type, (void *)A(buf), len)) {
959                         if (iov != iov_buf)
960                                 kfree(iov);
961                         return((struct iovec *)0);
962                 }
963                 ivp->iov_base = (void *)A(buf);
964                 ivp->iov_len = (__kernel_size_t)len;
965                 iov32++;
966                 ivp++;
967         }
968         return(iov);
969 }
970
971 asmlinkage long
972 sys32_readv(int fd, struct iovec32 *vector, u32 count)
973 {
974         struct iovec iovstack[UIO_FASTIOV];
975         struct iovec *iov;
976         int ret;
977         mm_segment_t old_fs = get_fs();
978
979         if ((iov = get_iovec32(vector, iovstack, count, VERIFY_WRITE)) == (struct iovec *)0)
980                 return -EFAULT;
981         set_fs(KERNEL_DS);
982         ret = sys_readv(fd, iov, count);
983         set_fs(old_fs);
984         if (iov != iovstack)
985                 kfree(iov);
986         return ret;
987 }
988
989 asmlinkage long
990 sys32_writev(int fd, struct iovec32 *vector, u32 count)
991 {
992         struct iovec iovstack[UIO_FASTIOV];
993         struct iovec *iov;
994         int ret;
995         mm_segment_t old_fs = get_fs();
996
997         if ((iov = get_iovec32(vector, iovstack, count, VERIFY_READ)) == (struct iovec *)0)
998                 return -EFAULT;
999         set_fs(KERNEL_DS);
1000         ret = sys_writev(fd, iov, count);
1001         set_fs(old_fs);
1002         if (iov != iovstack)
1003                 kfree(iov);
1004         return ret;
1005 }
1006
1007 #define RLIM_INFINITY32 0xffffffff
1008 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
1009
1010 struct rlimit32 {
1011         int     rlim_cur;
1012         int     rlim_max;
1013 };
1014
1015 extern asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim);
1016
1017 asmlinkage long
1018 sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
1019 {
1020         struct rlimit r;
1021         int ret;
1022         mm_segment_t old_fs;
1023
1024         old_fs = get_fs();
1025         set_fs(KERNEL_DS);
1026         ret = sys_getrlimit(resource, &r);
1027         set_fs(old_fs);
1028         if (!ret) {
1029                 if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
1030                     __put_user(RESOURCE32(r.rlim_cur), &rlim->rlim_cur) ||
1031                     __put_user(RESOURCE32(r.rlim_max), &rlim->rlim_max))
1032                         ret = -EFAULT;
1033         }
1034         return ret;
1035 }
1036
1037 extern asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim);
1038
1039 asmlinkage long
1040 sys32_old_getrlimit(unsigned int resource, struct rlimit32 *rlim)
1041 {
1042         struct rlimit r;
1043         int ret;
1044         mm_segment_t old_fs;
1045         
1046         old_fs = get_fs();
1047         set_fs(KERNEL_DS);
1048         ret = sys_old_getrlimit(resource, &r);
1049         set_fs(old_fs);
1050         if (!ret) {
1051                 if (verify_area(VERIFY_WRITE, rlim, sizeof(struct rlimit32)) ||
1052                     __put_user(r.rlim_cur, &rlim->rlim_cur) ||
1053                     __put_user(r.rlim_max, &rlim->rlim_max))
1054                         ret = -EFAULT;
1055         }
1056         return ret;
1057 }
1058
1059 extern asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim);
1060
1061 asmlinkage long
1062 sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
1063 {
1064         struct rlimit r;
1065         int ret;
1066         mm_segment_t old_fs = get_fs ();
1067
1068         if (resource >= RLIM_NLIMITS) return -EINVAL;   
1069         if (verify_area(VERIFY_READ, rlim, sizeof(struct rlimit32)) ||
1070             __get_user (r.rlim_cur, &rlim->rlim_cur) ||
1071             __get_user (r.rlim_max, &rlim->rlim_max))
1072                 return -EFAULT;
1073         if (r.rlim_cur == RLIM_INFINITY32)
1074                 r.rlim_cur = RLIM_INFINITY;
1075         if (r.rlim_max == RLIM_INFINITY32)
1076                 r.rlim_max = RLIM_INFINITY;
1077         set_fs (KERNEL_DS);
1078         ret = sys_setrlimit(resource, &r);
1079         set_fs (old_fs);
1080         return ret;
1081 }
1082
1083 /*
1084  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
1085  *
1086  * This is really horribly ugly.
1087  */
1088
1089 struct msgbuf32 { s32 mtype; char mtext[1]; };
1090
1091 struct ipc_perm32
1092 {
1093         key_t             key;
1094         __kernel_uid_t32  uid;
1095         __kernel_gid_t32  gid;
1096         __kernel_uid_t32  cuid;
1097         __kernel_gid_t32  cgid;
1098         __kernel_mode_t32 mode;
1099         unsigned short  seq;
1100 };
1101
1102 struct semid_ds32 {
1103         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
1104         __kernel_time_t32 sem_otime;              /* last semop time */
1105         __kernel_time_t32 sem_ctime;              /* last change time */
1106         u32 sem_base;              /* ptr to first semaphore in array */
1107         u32 sem_pending;          /* pending operations to be processed */
1108         u32 sem_pending_last;    /* last pending operation */
1109         u32 undo;                  /* undo requests on this array */
1110         unsigned short  sem_nsems;              /* no. of semaphores in array */
1111 };
1112
1113 struct msqid_ds32
1114 {
1115         struct ipc_perm32 msg_perm;
1116         u32 msg_first;
1117         u32 msg_last;
1118         __kernel_time_t32 msg_stime;
1119         __kernel_time_t32 msg_rtime;
1120         __kernel_time_t32 msg_ctime;
1121         u32 wwait;
1122         u32 rwait;
1123         unsigned short msg_cbytes;
1124         unsigned short msg_qnum;  
1125         unsigned short msg_qbytes;
1126         __kernel_ipc_pid_t32 msg_lspid;
1127         __kernel_ipc_pid_t32 msg_lrpid;
1128 };
1129
1130 struct shmid_ds32 {
1131         struct ipc_perm32       shm_perm;
1132         int                     shm_segsz;
1133         __kernel_time_t32       shm_atime;
1134         __kernel_time_t32       shm_dtime;
1135         __kernel_time_t32       shm_ctime;
1136         __kernel_ipc_pid_t32    shm_cpid; 
1137         __kernel_ipc_pid_t32    shm_lpid; 
1138         unsigned short          shm_nattch;
1139 };
1140
1141 #define IPCOP_MASK(__x) (1UL << (__x))
1142
1143 static int
1144 do_sys32_semctl(int first, int second, int third, void *uptr)
1145 {
1146         union semun fourth;
1147         u32 pad;
1148         int err;
1149         struct semid64_ds s;
1150         struct semid_ds32 *usp;
1151         mm_segment_t old_fs;
1152
1153         if (!uptr)
1154                 return -EINVAL;
1155         err = -EFAULT;
1156         if (get_user (pad, (u32 *)uptr))
1157                 return err;
1158         if(third == SETVAL)
1159                 fourth.val = (int)pad;
1160         else
1161                 fourth.__pad = (void *)A(pad);
1162         switch (third) {
1163
1164         case IPC_INFO:
1165         case IPC_RMID:
1166         case IPC_SET:
1167         case SEM_INFO:
1168         case GETVAL:
1169         case GETPID:
1170         case GETNCNT:
1171         case GETZCNT:
1172         case GETALL:
1173         case SETVAL:
1174         case SETALL:
1175                 err = sys_semctl (first, second, third, fourth);
1176                 break;
1177
1178         case IPC_STAT:
1179         case SEM_STAT:
1180                 usp = (struct semid_ds32 *)A(pad);
1181                 fourth.__pad = &s;
1182                 old_fs = get_fs ();
1183                 set_fs (KERNEL_DS);
1184                 err = sys_semctl (first, second, third, fourth);
1185                 set_fs (old_fs);
1186                 if (verify_area(VERIFY_WRITE, usp, sizeof(struct semid_ds32)) ||
1187                     __put_user(s.sem_perm.key, &usp->sem_perm.key) ||
1188                     __put_user(s.sem_perm.uid, &usp->sem_perm.uid) ||
1189                     __put_user(s.sem_perm.gid, &usp->sem_perm.gid) ||
1190                     __put_user(s.sem_perm.cuid, &usp->sem_perm.cuid) ||
1191                     __put_user (s.sem_perm.cgid, &usp->sem_perm.cgid) ||
1192                     __put_user (s.sem_perm.mode, &usp->sem_perm.mode) ||
1193                     __put_user (s.sem_perm.seq, &usp->sem_perm.seq) ||
1194                     __put_user (s.sem_otime, &usp->sem_otime) ||
1195                     __put_user (s.sem_ctime, &usp->sem_ctime) ||
1196                     __put_user (s.sem_nsems, &usp->sem_nsems))
1197                         return -EFAULT;
1198                 break;
1199
1200         }
1201
1202         return err;
1203 }
1204
1205 static int
1206 do_sys32_msgsnd (int first, int second, int third, void *uptr)
1207 {
1208         struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
1209                                     + 4, GFP_USER);
1210         struct msgbuf32 *up = (struct msgbuf32 *)uptr;
1211         mm_segment_t old_fs;
1212         int err;
1213
1214         if (!p)
1215                 return -ENOMEM;
1216         err = verify_area(VERIFY_READ, up, sizeof(struct msgbuf32));
1217         if (err)
1218                 goto out;
1219         err = __get_user (p->mtype, &up->mtype);
1220         err |= __copy_from_user (p->mtext, &up->mtext, second);
1221         if (err)
1222                 goto out;
1223         old_fs = get_fs ();
1224         set_fs (KERNEL_DS);
1225         err = sys_msgsnd (first, p, second, third);
1226         set_fs (old_fs);
1227 out:
1228         kfree (p);
1229         return err;
1230 }
1231
1232 static int
1233 do_sys32_msgrcv (int first, int second, int msgtyp, int third,
1234                  int version, void *uptr)
1235 {
1236         struct msgbuf32 *up;
1237         struct msgbuf *p;
1238         mm_segment_t old_fs;
1239         int err;
1240
1241         if (!version) {
1242                 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
1243                 struct ipc_kludge ipck;
1244
1245                 err = -EINVAL;
1246                 if (!uptr)
1247                         goto out;
1248                 err = -EFAULT;
1249                 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
1250                         goto out;
1251                 uptr = (void *)A(ipck.msgp);
1252                 msgtyp = ipck.msgtyp;
1253         }
1254         err = -ENOMEM;
1255         p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
1256         if (!p)
1257                 goto out;
1258         old_fs = get_fs ();
1259         set_fs (KERNEL_DS);
1260         err = sys_msgrcv (first, p, second + 4, msgtyp, third);
1261         set_fs (old_fs);
1262         if (err < 0)
1263                 goto free_then_out;
1264         up = (struct msgbuf32 *)uptr;
1265         if (verify_area(VERIFY_WRITE, up, sizeof(struct msgbuf32)) ||
1266             __put_user (p->mtype, &up->mtype) ||
1267             __copy_to_user (&up->mtext, p->mtext, err))
1268                 err = -EFAULT;
1269 free_then_out:
1270         kfree (p);
1271 out:
1272         return err;
1273 }
1274
1275 static int
1276 do_sys32_msgctl (int first, int second, void *uptr)
1277 {
1278         int err = -EINVAL;
1279         struct msqid_ds m;
1280         struct msqid64_ds m64;
1281         struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
1282         mm_segment_t old_fs;
1283
1284         switch (second) {
1285
1286         case IPC_INFO:
1287         case IPC_RMID:
1288         case MSG_INFO:
1289                 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
1290                 break;
1291
1292         case IPC_SET:
1293                 err = verify_area(VERIFY_READ, up, sizeof(struct msqid_ds32));
1294                 if (err)
1295                         break;
1296                 err = __get_user (m.msg_perm.uid, &up->msg_perm.uid);
1297                 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
1298                 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
1299                 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
1300                 if (err)
1301                         break;
1302                 old_fs = get_fs ();
1303                 set_fs (KERNEL_DS);
1304                 err = sys_msgctl (first, second, &m);
1305                 set_fs (old_fs);
1306                 break;
1307
1308         case IPC_STAT:
1309         case MSG_STAT:
1310                 old_fs = get_fs ();
1311                 set_fs (KERNEL_DS);
1312                 err = sys_msgctl (first, second, (void *) &m64);
1313                 set_fs (old_fs);
1314                 if (verify_area(VERIFY_WRITE, up, sizeof(struct msqid_ds32)) ||
1315                     __put_user (m64.msg_perm.key, &up->msg_perm.key) ||
1316                     __put_user(m64.msg_perm.uid, &up->msg_perm.uid) ||
1317                     __put_user(m64.msg_perm.gid, &up->msg_perm.gid) ||
1318                     __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid) ||
1319                     __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid) ||
1320                     __put_user(m64.msg_perm.mode, &up->msg_perm.mode) ||
1321                     __put_user(m64.msg_perm.seq, &up->msg_perm.seq) ||
1322                     __put_user(m64.msg_stime, &up->msg_stime) ||
1323                     __put_user(m64.msg_rtime, &up->msg_rtime) ||
1324                     __put_user(m64.msg_ctime, &up->msg_ctime) ||
1325                     __put_user(m64.msg_cbytes, &up->msg_cbytes) ||
1326                     __put_user(m64.msg_qnum, &up->msg_qnum) ||
1327                     __put_user(m64.msg_qbytes, &up->msg_qbytes) ||
1328                     __put_user(m64.msg_lspid, &up->msg_lspid) ||
1329                     __put_user(m64.msg_lrpid, &up->msg_lrpid))
1330                         return -EFAULT;
1331                 break;
1332
1333         }
1334
1335         return err;
1336 }
1337
1338 static int
1339 do_sys32_shmat (int first, int second, int third, int version, void *uptr)
1340 {
1341         unsigned long raddr;
1342         u32 *uaddr = (u32 *)A((u32)third);
1343         int err = -EINVAL;
1344
1345         if (version == 1)
1346                 return err;
1347         err = sys_shmat (first, uptr, second, &raddr);
1348         if (err)
1349                 return err;
1350         err = put_user (raddr, uaddr);
1351         return err;
1352 }
1353
1354 static int
1355 do_sys32_shmctl (int first, int second, void *uptr)
1356 {
1357         int err = -EFAULT;
1358         struct shmid_ds s;
1359         struct shmid64_ds s64;
1360         struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
1361         mm_segment_t old_fs;
1362         struct shm_info32 {
1363                 int used_ids;
1364                 u32 shm_tot, shm_rss, shm_swp;
1365                 u32 swap_attempts, swap_successes;
1366         } *uip = (struct shm_info32 *)uptr;
1367         struct shm_info si;
1368
1369         switch (second) {
1370
1371         case IPC_INFO:
1372         case IPC_RMID:
1373         case SHM_LOCK:
1374         case SHM_UNLOCK:
1375                 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
1376                 break;
1377         case IPC_SET:
1378                 err = verify_area(VERIFY_READ, up, sizeof(struct shmid_ds32));
1379                 if (err)
1380                         break;
1381                 err = __get_user (s.shm_perm.uid, &up->shm_perm.uid);
1382                 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
1383                 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
1384                 if (err)
1385                         break;
1386                 old_fs = get_fs ();
1387                 set_fs (KERNEL_DS);
1388                 err = sys_shmctl (first, second, &s);
1389                 set_fs (old_fs);
1390                 break;
1391
1392         case IPC_STAT:
1393         case SHM_STAT:
1394                 old_fs = get_fs ();
1395                 set_fs (KERNEL_DS);
1396                 err = sys_shmctl (first, second, (void *) &s64);
1397                 set_fs (old_fs);
1398                 if (err < 0)
1399                         break;
1400                 if (verify_area(VERIFY_WRITE, up, sizeof(struct shmid_ds32)) ||
1401                     __put_user (s64.shm_perm.key, &up->shm_perm.key) ||
1402                     __put_user (s64.shm_perm.uid, &up->shm_perm.uid) ||
1403                     __put_user (s64.shm_perm.gid, &up->shm_perm.gid) ||
1404                     __put_user (s64.shm_perm.cuid, &up->shm_perm.cuid) ||
1405                     __put_user (s64.shm_perm.cgid, &up->shm_perm.cgid) ||
1406                     __put_user (s64.shm_perm.mode, &up->shm_perm.mode) ||
1407                     __put_user (s64.shm_perm.seq, &up->shm_perm.seq) ||
1408                     __put_user (s64.shm_atime, &up->shm_atime) ||
1409                     __put_user (s64.shm_dtime, &up->shm_dtime) ||
1410                     __put_user (s64.shm_ctime, &up->shm_ctime) ||
1411                     __put_user (s64.shm_segsz, &up->shm_segsz) ||
1412                     __put_user (s64.shm_nattch, &up->shm_nattch) ||
1413                     __put_user (s64.shm_cpid, &up->shm_cpid) ||
1414                     __put_user (s64.shm_lpid, &up->shm_lpid))
1415                         return -EFAULT;
1416                 break;
1417
1418         case SHM_INFO:
1419                 old_fs = get_fs ();
1420                 set_fs (KERNEL_DS);
1421                 err = sys_shmctl (first, second, (void *)&si);
1422                 set_fs (old_fs);
1423                 if (err < 0)
1424                         break;
1425                 if (verify_area(VERIFY_WRITE, uip, sizeof(struct shm_info32)) ||
1426                     __put_user (si.used_ids, &uip->used_ids) ||
1427                     __put_user (si.shm_tot, &uip->shm_tot) ||
1428                     __put_user (si.shm_rss, &uip->shm_rss) ||
1429                     __put_user (si.shm_swp, &uip->shm_swp) ||
1430                     __put_user (si.swap_attempts, &uip->swap_attempts) ||
1431                     __put_user (si.swap_successes, &uip->swap_successes))
1432                         return -EFAULT;
1433                 break;
1434
1435         }
1436         return err;
1437 }
1438
1439 asmlinkage long
1440 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
1441 {
1442         int version, err;
1443
1444         version = call >> 16; /* hack for backward compatibility */
1445         call &= 0xffff;
1446
1447         switch (call) {
1448
1449         case SEMOP:
1450                 /* struct sembuf is the same on 32 and 64bit :)) */
1451                 err = sys_semop (first, (struct sembuf *)AA(ptr),
1452                                  second);
1453                 break;
1454         case SEMGET:
1455                 err = sys_semget (first, second, third);
1456                 break;
1457         case SEMCTL:
1458                 err = do_sys32_semctl (first, second, third,
1459                                        (void *)AA(ptr));
1460                 break;
1461
1462         case MSGSND:
1463                 err = do_sys32_msgsnd (first, second, third,
1464                                        (void *)AA(ptr));
1465                 break;
1466         case MSGRCV:
1467                 err = do_sys32_msgrcv (first, second, fifth, third,
1468                                        version, (void *)AA(ptr));
1469                 break;
1470         case MSGGET:
1471                 err = sys_msgget ((key_t) first, second);
1472                 break;
1473         case MSGCTL:
1474                 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
1475                 break;
1476
1477         case SHMAT:
1478                 err = do_sys32_shmat (first, second, third,
1479                                       version, (void *)AA(ptr));
1480                 break;
1481         case SHMDT: 
1482                 err = sys_shmdt ((char *)AA(ptr));
1483                 break;
1484         case SHMGET:
1485                 err = sys_shmget (first, second, third);
1486                 break;
1487         case SHMCTL:
1488                 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
1489                 break;
1490         default:
1491                 err = -EINVAL;
1492                 break;
1493         }
1494
1495         return err;
1496 }
1497
1498 /*
1499  * sys_time() can be implemented in user-level using
1500  * sys_gettimeofday().  IA64 did this but i386 Linux did not
1501  * so we have to implement this system call here.
1502  */
1503 asmlinkage long sys32_time(int * tloc)
1504 {
1505         int i;
1506
1507         /* SMP: This is fairly trivial. We grab CURRENT_TIME and 
1508            stuff it to user space. No side effects */
1509         i = CURRENT_TIME;
1510         if (tloc) {
1511                 if (put_user(i,tloc))
1512                         i = -EFAULT;
1513         }
1514         return i;
1515 }
1516
1517 struct rusage32 {
1518         struct timeval32 ru_utime;
1519         struct timeval32 ru_stime;
1520         int    ru_maxrss;
1521         int    ru_ixrss;
1522         int    ru_idrss;
1523         int    ru_isrss;
1524         int    ru_minflt;
1525         int    ru_majflt;
1526         int    ru_nswap;
1527         int    ru_inblock;
1528         int    ru_oublock;
1529         int    ru_msgsnd; 
1530         int    ru_msgrcv; 
1531         int    ru_nsignals;
1532         int    ru_nvcsw;
1533         int    ru_nivcsw;
1534 };
1535
1536 static int
1537 put_rusage (struct rusage32 *ru, struct rusage *r)
1538 {
1539         if (verify_area(VERIFY_WRITE, ru, sizeof(struct rusage32)) ||
1540             __put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
1541             __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
1542             __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
1543             __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
1544             __put_user (r->ru_maxrss, &ru->ru_maxrss) ||
1545             __put_user (r->ru_ixrss, &ru->ru_ixrss) ||
1546             __put_user (r->ru_idrss, &ru->ru_idrss) ||
1547             __put_user (r->ru_isrss, &ru->ru_isrss) ||
1548             __put_user (r->ru_minflt, &ru->ru_minflt) ||
1549             __put_user (r->ru_majflt, &ru->ru_majflt) ||
1550             __put_user (r->ru_nswap, &ru->ru_nswap) ||
1551             __put_user (r->ru_inblock, &ru->ru_inblock) ||
1552             __put_user (r->ru_oublock, &ru->ru_oublock) ||
1553             __put_user (r->ru_msgsnd, &ru->ru_msgsnd) ||
1554             __put_user (r->ru_msgrcv, &ru->ru_msgrcv) ||
1555             __put_user (r->ru_nsignals, &ru->ru_nsignals) ||
1556             __put_user (r->ru_nvcsw, &ru->ru_nvcsw) ||
1557             __put_user (r->ru_nivcsw, &ru->ru_nivcsw))
1558                 return -EFAULT;
1559         return 0;
1560 }
1561
1562 extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
1563                                 int options, struct rusage * ru);
1564
1565 asmlinkage long
1566 sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,
1567             struct rusage32 *ru)
1568 {
1569         if (!ru)
1570                 return sys_wait4(pid, stat_addr, options, NULL);
1571         else {
1572                 struct rusage r;
1573                 int ret;
1574                 unsigned int status;
1575                 mm_segment_t old_fs = get_fs();
1576                 
1577                 set_fs (KERNEL_DS);
1578                 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1579                 set_fs (old_fs);
1580                 if (put_rusage (ru, &r)) return -EFAULT;
1581                 if (stat_addr && put_user (status, stat_addr))
1582                         return -EFAULT;
1583                 return ret;
1584         }
1585 }
1586
1587 asmlinkage long
1588 sys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options)
1589 {
1590         return sys32_wait4(pid, stat_addr, options, NULL);
1591 }
1592
1593
1594 extern asmlinkage long
1595 sys_getrusage(int who, struct rusage *ru);
1596
1597 asmlinkage long
1598 sys32_getrusage(int who, struct rusage32 *ru)
1599 {
1600         struct rusage r;
1601         int ret;
1602         mm_segment_t old_fs = get_fs();
1603                 
1604         set_fs (KERNEL_DS);
1605         ret = sys_getrusage(who, &r);
1606         set_fs (old_fs);
1607         if (put_rusage (ru, &r)) return -EFAULT;
1608         return ret;
1609 }
1610
1611 struct tms32 {
1612         __kernel_clock_t32 tms_utime;
1613         __kernel_clock_t32 tms_stime;
1614         __kernel_clock_t32 tms_cutime;
1615         __kernel_clock_t32 tms_cstime;
1616 };
1617                                 
1618 extern asmlinkage long sys_times(struct tms * tbuf);
1619
1620 asmlinkage long
1621 sys32_times(struct tms32 *tbuf)
1622 {
1623         struct tms t;
1624         long ret;
1625         mm_segment_t old_fs = get_fs ();
1626         
1627         set_fs (KERNEL_DS);
1628         ret = sys_times(tbuf ? &t : NULL);
1629         set_fs (old_fs);
1630         if (tbuf) {
1631                 if (verify_area(VERIFY_WRITE, tbuf, sizeof(struct tms32)) ||
1632                     __put_user (t.tms_utime, &tbuf->tms_utime) ||
1633                     __put_user (t.tms_stime, &tbuf->tms_stime) ||
1634                     __put_user (t.tms_cutime, &tbuf->tms_cutime) ||
1635                     __put_user (t.tms_cstime, &tbuf->tms_cstime))
1636                         return -EFAULT;
1637         }
1638         return ret;
1639 }
1640
1641 static inline int
1642 get_flock32(struct flock *kfl, struct flock32 *ufl)
1643 {
1644         if (verify_area(VERIFY_READ, ufl, sizeof(struct flock32)) ||
1645             __get_user(kfl->l_type, &ufl->l_type) ||
1646             __get_user(kfl->l_whence, &ufl->l_whence) ||
1647             __get_user(kfl->l_start, &ufl->l_start) ||
1648             __get_user(kfl->l_len, &ufl->l_len) ||
1649             __get_user(kfl->l_pid, &ufl->l_pid))
1650                 return -EFAULT;
1651         return 0;
1652 }
1653
1654 static inline int
1655 put_flock32(struct flock *kfl, struct flock32 *ufl)
1656 {
1657         if (verify_area(VERIFY_WRITE, ufl, sizeof(struct flock32)) ||
1658             __put_user(kfl->l_type, &ufl->l_type) ||
1659             __put_user(kfl->l_whence, &ufl->l_whence) ||
1660             __put_user(kfl->l_start, &ufl->l_start) ||
1661             __put_user(kfl->l_len, &ufl->l_len) ||
1662             __put_user(kfl->l_pid, &ufl->l_pid))
1663                 return -EFAULT;
1664         return 0;
1665 }
1666
1667 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd,
1668                                  unsigned long arg);
1669
1670 asmlinkage long
1671 sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
1672 {
1673         struct flock f;
1674         mm_segment_t old_fs;
1675         long ret;
1676
1677         switch (cmd) {
1678         case F_GETLK:
1679         case F_SETLK:
1680         case F_SETLKW:
1681                 if(cmd != F_GETLK && get_flock32(&f, (struct flock32 *)((long)arg)))
1682                         return -EFAULT;
1683                 old_fs = get_fs();
1684                 set_fs(KERNEL_DS);
1685                 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
1686                 set_fs(old_fs);
1687                 if(cmd == F_GETLK && put_flock32(&f, (struct flock32 *)((long)arg)))
1688                         return -EFAULT;
1689                 return ret;
1690         default:
1691                 /*
1692                  *  `sys_fcntl' lies about arg, for the F_SETOWN
1693                  *  sub-function arg can have a negative value.
1694                  */
1695                 return sys_fcntl(fd, cmd, (unsigned long)((long)arg));
1696         }
1697 }
1698
1699 static inline int
1700 get_flock64(struct flock *kfl, struct ia32_flock64 *ufl)
1701 {
1702         if (verify_area(VERIFY_READ, ufl, sizeof(struct ia32_flock64)) ||
1703             __get_user(kfl->l_type, &ufl->l_type) ||
1704             __get_user(kfl->l_whence, &ufl->l_whence) ||
1705             __copy_from_user(&kfl->l_start, &ufl->l_start, 8) ||
1706             __copy_from_user(&kfl->l_len, &ufl->l_len, 8) ||
1707             __get_user(kfl->l_pid, &ufl->l_pid))
1708                 return -EFAULT;
1709         return 0;
1710 }
1711
1712 static inline int
1713 put_flock64(struct flock *kfl, struct ia32_flock64 *ufl)
1714 {
1715         if (verify_area(VERIFY_WRITE, ufl, sizeof(struct ia32_flock64)) ||
1716             __put_user(kfl->l_type, &ufl->l_type) ||
1717             __put_user(kfl->l_whence, &ufl->l_whence) ||
1718             __copy_to_user(&ufl->l_start,&kfl->l_start, 8) ||
1719             __copy_to_user(&ufl->l_len,&kfl->l_len, 8) ||
1720             __put_user(kfl->l_pid, &ufl->l_pid))
1721                 return -EFAULT;
1722         return 0;
1723 }
1724
1725 asmlinkage long
1726 sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
1727 {
1728         struct flock f;
1729         mm_segment_t old_fs;
1730         long ret;
1731
1732         /* sys_fcntl() is by default 64 bit and so don't know anything
1733          * about F_xxxx64 commands
1734          */ 
1735         switch (cmd) {
1736         case F_GETLK64:
1737                 cmd = F_GETLK;
1738                 break;
1739         case F_SETLK64:
1740                 cmd = F_SETLK;
1741                 break;
1742         case F_SETLKW64:
1743                 cmd = F_SETLKW;
1744                 break;
1745         }
1746         
1747         switch (cmd) {
1748         case F_SETLKW:
1749         case F_SETLK:
1750                 if(get_flock64(&f, (struct ia32_flock64 *)arg))
1751                         return -EFAULT;
1752         case F_GETLK:
1753                 old_fs = get_fs();
1754                 set_fs(KERNEL_DS);
1755                 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
1756                 set_fs(old_fs);
1757                 if(cmd == F_GETLK64 && put_flock64(&f, (struct ia32_flock64 *)((long)arg)))
1758                         return -EFAULT;
1759                 return ret;
1760         default:
1761                 /*
1762                  *  `sys_fcntl' lies about arg, for the F_SETOWN
1763                  *  sub-function arg can have a negative value.
1764                  */
1765                 return sys_fcntl(fd, cmd, (unsigned long)((long)arg));
1766         }
1767 }
1768
1769 int sys32_ni_syscall(int call)
1770
1771         printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call,
1772                current->comm);
1773         return -ENOSYS;        
1774
1775
1776 /* In order to reduce some races, while at the same time doing additional
1777  * checking and hopefully speeding things up, we copy filenames to the
1778  * kernel data space before using them..
1779  *
1780  * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
1781  */
1782 static inline int
1783 do_getname32(const char *filename, char *page)
1784 {
1785         int retval;
1786
1787         /* 32bit pointer will be always far below TASK_SIZE :)) */
1788         retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
1789         if (retval > 0) {
1790                 if (retval < PAGE_SIZE)
1791                         return 0;
1792                 return -ENAMETOOLONG;
1793         } else if (!retval)
1794                 retval = -ENOENT;
1795         return retval;
1796 }
1797
1798 char *
1799 getname32(const char *filename)
1800 {
1801         char *tmp, *result;
1802
1803         result = ERR_PTR(-ENOMEM);
1804         tmp = (char *)__get_free_page(GFP_KERNEL);
1805         if (tmp)  {
1806                 int retval = do_getname32(filename, tmp);
1807
1808                 result = tmp;
1809                 if (retval < 0) {
1810                         putname(tmp);
1811                         result = ERR_PTR(retval);
1812                 }
1813         }
1814         return result;
1815 }
1816
1817 /* 32-bit timeval and related flotsam.  */
1818
1819 extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);
1820
1821 struct utimbuf32 {
1822         __kernel_time_t32 actime, modtime;
1823 };
1824
1825 asmlinkage long
1826 sys32_utime(char * filename, struct utimbuf32 *times)
1827 {
1828         struct utimbuf t;
1829         mm_segment_t old_fs;
1830         int ret;
1831         char *filenam;
1832         
1833         if (!times)
1834                 return sys_utime(filename, NULL);
1835         if (verify_area(VERIFY_READ, times, sizeof(struct utimbuf32)) ||
1836             __get_user (t.actime, &times->actime) ||
1837             __get_user (t.modtime, &times->modtime))
1838                 return -EFAULT;
1839         filenam = getname32 (filename);
1840         ret = PTR_ERR(filenam);
1841         if (!IS_ERR(filenam)) {
1842                 old_fs = get_fs();
1843                 set_fs (KERNEL_DS); 
1844                 ret = sys_utime(filenam, &t);
1845                 set_fs (old_fs);
1846                 putname (filenam);
1847         }
1848         return ret;
1849 }
1850
1851 /*
1852  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
1853  * 64-bit unsigned longs.
1854  */
1855
1856 static inline int
1857 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1858 {
1859         if (ufdset) {
1860                 unsigned long odd;
1861
1862                 if (verify_area(VERIFY_READ, ufdset, n*sizeof(u32)))
1863                         return -EFAULT;
1864
1865                 odd = n & 1UL;
1866                 n &= ~1UL;
1867                 while (n) {
1868                         unsigned long h, l;
1869                         __get_user(l, ufdset);
1870                         __get_user(h, ufdset+1);
1871                         ufdset += 2;
1872                         *fdset++ = h << 32 | l;
1873                         n -= 2;
1874                 }
1875                 if (odd)
1876                         __get_user(*fdset, ufdset);
1877         } else {
1878                 /* Tricky, must clear full unsigned long in the
1879                  * kernel fdset at the end, this makes sure that
1880                  * actually happens.
1881                  */
1882                 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1883         }
1884         return 0;
1885 }
1886
1887 extern asmlinkage long sys_sysfs(int option, unsigned long arg1,
1888                                 unsigned long arg2);
1889
1890 asmlinkage long
1891 sys32_sysfs(int option, u32 arg1, u32 arg2)
1892 {
1893         return sys_sysfs(option, arg1, arg2);
1894 }
1895
1896 extern asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
1897                                 unsigned long new_flags, void *data);
1898
1899 static char *badfs[] = {
1900         "smbfs", "ncpfs", NULL
1901 };      
1902
1903 static int checktype(char *user_type) 
1904
1905         int err = 0; 
1906         char **s,*kernel_type = getname32(user_type); 
1907         if (!kernel_type) 
1908                 return -EFAULT; 
1909         for (s = badfs; *s; ++s) 
1910                 if (!strcmp(kernel_type, *s)) { 
1911                         printk(KERN_ERR "mount32: unsupported fs `%s' -- use 64bit mount\n", *s); 
1912                         err = -EINVAL; 
1913                         break;
1914                 }       
1915         putname(user_type); 
1916         return err;
1917
1918
1919 asmlinkage long
1920 sys32_mount(char *dev_name, char *dir_name, char *type,
1921             unsigned long new_flags, u32 data)
1922 {
1923         int err;
1924         if(!capable(CAP_SYS_ADMIN))
1925                 return -EPERM;
1926         err = checktype(type);
1927         if (err)
1928                 return err;
1929         return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data));
1930 }
1931
1932 struct sysinfo32 {
1933         s32 uptime;
1934         u32 loads[3];
1935         u32 totalram;
1936         u32 freeram;
1937         u32 sharedram;
1938         u32 bufferram;
1939         u32 totalswap;
1940         u32 freeswap;
1941         unsigned short procs;
1942         char _f[22];
1943 };
1944
1945 extern asmlinkage long sys_sysinfo(struct sysinfo *info);
1946
1947 asmlinkage long
1948 sys32_sysinfo(struct sysinfo32 *info)
1949 {
1950         struct sysinfo s;
1951         int ret;
1952         mm_segment_t old_fs = get_fs ();
1953         
1954         set_fs (KERNEL_DS);
1955         ret = sys_sysinfo(&s);
1956         set_fs (old_fs);
1957         if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) ||
1958             __put_user (s.uptime, &info->uptime) ||
1959             __put_user (s.loads[0], &info->loads[0]) ||
1960             __put_user (s.loads[1], &info->loads[1]) ||
1961             __put_user (s.loads[2], &info->loads[2]) ||
1962             __put_user (s.totalram, &info->totalram) ||
1963             __put_user (s.freeram, &info->freeram) ||
1964             __put_user (s.sharedram, &info->sharedram) ||
1965             __put_user (s.bufferram, &info->bufferram) ||
1966             __put_user (s.totalswap, &info->totalswap) ||
1967             __put_user (s.freeswap, &info->freeswap) ||
1968             __put_user (s.procs, &info->procs))
1969                 return -EFAULT;
1970         return 0;
1971 }
1972                 
1973 extern asmlinkage long sys_sched_rr_get_interval(pid_t pid,
1974                                                 struct timespec *interval);
1975
1976 asmlinkage long
1977 sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1978 {
1979         struct timespec t;
1980         int ret;
1981         mm_segment_t old_fs = get_fs ();
1982         
1983         set_fs (KERNEL_DS);
1984         ret = sys_sched_rr_get_interval(pid, &t);
1985         set_fs (old_fs);
1986         if (verify_area(VERIFY_WRITE, interval, sizeof(struct timespec32)) ||
1987             __put_user (t.tv_sec, &interval->tv_sec) ||
1988             __put_user (t.tv_nsec, &interval->tv_nsec))
1989                 return -EFAULT;
1990         return ret;
1991 }
1992
1993 extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
1994                                       old_sigset_t *oset);
1995
1996 asmlinkage long
1997 sys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset)
1998 {
1999         old_sigset_t s;
2000         int ret;
2001         mm_segment_t old_fs = get_fs();
2002         
2003         if (set && get_user (s, set)) return -EFAULT;
2004         set_fs (KERNEL_DS);
2005         ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
2006         set_fs (old_fs);
2007         if (ret) return ret;
2008         if (oset && put_user (s, oset)) return -EFAULT;
2009         return 0;
2010 }
2011
2012 extern asmlinkage long sys_sigpending(old_sigset_t *set);
2013
2014 asmlinkage long
2015 sys32_sigpending(old_sigset32_t *set)
2016 {
2017         old_sigset_t s;
2018         int ret;
2019         mm_segment_t old_fs = get_fs();
2020                 
2021         set_fs (KERNEL_DS);
2022         ret = sys_sigpending(&s);
2023         set_fs (old_fs);
2024         if (put_user (s, set)) return -EFAULT;
2025         return ret;
2026 }
2027
2028 extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
2029
2030 asmlinkage long
2031 sys32_rt_sigpending(sigset32_t *set, __kernel_size_t32 sigsetsize)
2032 {
2033         sigset_t s;
2034         sigset32_t s32;
2035         int ret;
2036         mm_segment_t old_fs = get_fs();
2037                 
2038         set_fs (KERNEL_DS);
2039         ret = sys_rt_sigpending(&s, sigsetsize);
2040         set_fs (old_fs);
2041         if (!ret) {
2042                 switch (_NSIG_WORDS) {
2043                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2044                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2045                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2046                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2047                 }
2048                 if (copy_to_user (set, &s32, sizeof(sigset32_t)))
2049                         return -EFAULT;
2050         }
2051         return ret;
2052 }
2053
2054 siginfo_t32 *
2055 siginfo64to32(siginfo_t32 *d, siginfo_t *s)
2056 {
2057         memset (d, 0, sizeof(siginfo_t32));
2058         d->si_signo = s->si_signo;
2059         d->si_errno = s->si_errno;
2060         d->si_code = s->si_code;
2061         if (s->si_signo >= SIGRTMIN) {
2062                 d->si_pid = s->si_pid;
2063                 d->si_uid = s->si_uid;
2064                 /* XXX: Ouch, how to find this out??? */
2065                 d->si_int = s->si_int;
2066         } else switch (s->si_signo) {
2067         /* XXX: What about POSIX1.b timers */
2068         case SIGCHLD:
2069                 d->si_pid = s->si_pid;
2070                 d->si_status = s->si_status;
2071                 d->si_utime = s->si_utime;
2072                 d->si_stime = s->si_stime;
2073                 break;
2074         case SIGSEGV:
2075         case SIGBUS:
2076         case SIGFPE:
2077         case SIGILL:
2078                 d->si_addr = (long)(s->si_addr);
2079 //              d->si_trapno = s->si_trapno;
2080                 break;
2081         case SIGPOLL:
2082                 d->si_band = s->si_band;
2083                 d->si_fd = s->si_fd;
2084                 break;
2085         default:
2086                 d->si_pid = s->si_pid;
2087                 d->si_uid = s->si_uid;
2088                 break;
2089         }
2090         return d;
2091 }
2092
2093 siginfo_t *
2094 siginfo32to64(siginfo_t *d, siginfo_t32 *s)
2095 {
2096         d->si_signo = s->si_signo;
2097         d->si_errno = s->si_errno;
2098         d->si_code = s->si_code;
2099         if (s->si_signo >= SIGRTMIN) {
2100                 d->si_pid = s->si_pid;
2101                 d->si_uid = s->si_uid;
2102                 /* XXX: Ouch, how to find this out??? */
2103                 d->si_int = s->si_int;
2104         } else switch (s->si_signo) {
2105         /* XXX: What about POSIX1.b timers */
2106         case SIGCHLD:
2107                 d->si_pid = s->si_pid;
2108                 d->si_status = s->si_status;
2109                 d->si_utime = s->si_utime;
2110                 d->si_stime = s->si_stime;
2111                 break;
2112         case SIGSEGV:
2113         case SIGBUS:
2114         case SIGFPE:
2115         case SIGILL:
2116                 d->si_addr = (void *)A(s->si_addr);
2117 //              d->si_trapno = s->si_trapno;
2118                 break;
2119         case SIGPOLL:
2120                 d->si_band = s->si_band;
2121                 d->si_fd = s->si_fd;
2122                 break;
2123         default:
2124                 d->si_pid = s->si_pid;
2125                 d->si_uid = s->si_uid;
2126                 break;
2127         }
2128         return d;
2129 }
2130
2131 extern asmlinkage long
2132 sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
2133                     const struct timespec *uts, size_t sigsetsize);
2134
2135 asmlinkage long
2136 sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
2137                       struct timespec32 *uts, __kernel_size_t32 sigsetsize)
2138 {
2139         sigset_t s;
2140         sigset32_t s32;
2141         struct timespec t;
2142         int ret;
2143         mm_segment_t old_fs = get_fs();
2144         siginfo_t info;
2145         siginfo_t32 info32;
2146                 
2147         if (copy_from_user (&s32, uthese, sizeof(sigset32_t)))
2148                 return -EFAULT;
2149         switch (_NSIG_WORDS) {
2150         case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
2151         case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
2152         case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
2153         case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
2154         }
2155         if (uts) {
2156                 if (verify_area(VERIFY_READ, uts, sizeof(struct timespec32)) ||
2157                     __get_user (t.tv_sec, &uts->tv_sec) ||
2158                     __get_user (t.tv_nsec, &uts->tv_nsec))
2159                         return -EFAULT;
2160         }
2161         set_fs (KERNEL_DS);
2162         ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
2163         set_fs (old_fs);
2164         if (ret >= 0 && uinfo) {
2165                 if (copy_to_user (uinfo, siginfo64to32(&info32, &info),
2166                                   sizeof(siginfo_t32)))
2167                         return -EFAULT;
2168         }
2169         return ret;
2170 }
2171
2172 extern asmlinkage long
2173 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2174
2175 asmlinkage long
2176 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2177 {
2178         siginfo_t info;
2179         siginfo_t32 info32;
2180         int ret;
2181         mm_segment_t old_fs = get_fs();
2182         
2183         if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))
2184                 return -EFAULT;
2185         /* XXX: Is this correct? */
2186         siginfo32to64(&info, &info32);
2187         set_fs (KERNEL_DS);
2188         ret = sys_rt_sigqueueinfo(pid, sig, &info);
2189         set_fs (old_fs);
2190         return ret;
2191 }
2192
2193 extern asmlinkage long sys_setreuid(uid_t ruid, uid_t euid);
2194
2195 asmlinkage long sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
2196 {
2197         uid_t sruid, seuid;
2198
2199         sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2200         seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
2201         return sys_setreuid(sruid, seuid);
2202 }
2203
2204 extern asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
2205
2206 asmlinkage long
2207 sys32_setresuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid,
2208                 __kernel_uid_t32 suid)
2209 {
2210         uid_t sruid, seuid, ssuid;
2211
2212         sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
2213         seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
2214         ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
2215         return sys_setresuid(sruid, seuid, ssuid);
2216 }
2217
2218 extern asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
2219
2220 asmlinkage long
2221 sys32_getresuid(__kernel_uid_t32 *ruid, __kernel_uid_t32 *euid,
2222                 __kernel_uid_t32 *suid)
2223 {
2224         uid_t a, b, c;
2225         int ret;
2226         mm_segment_t old_fs = get_fs();
2227                 
2228         set_fs (KERNEL_DS);
2229         ret = sys_getresuid(&a, &b, &c);
2230         set_fs (old_fs);
2231         if (put_user (a, ruid) || put_user (b, euid) || put_user (c, suid))
2232                 return -EFAULT;
2233         return ret;
2234 }
2235
2236 extern asmlinkage long sys_setregid(gid_t rgid, gid_t egid);
2237
2238 asmlinkage long
2239 sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
2240 {
2241         gid_t srgid, segid;
2242
2243         srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2244         segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
2245         return sys_setregid(srgid, segid);
2246 }
2247
2248 extern asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
2249
2250 asmlinkage long
2251 sys32_setresgid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid,
2252                 __kernel_gid_t32 sgid)
2253 {
2254         gid_t srgid, segid, ssgid;
2255
2256         srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
2257         segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
2258         ssgid = (sgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)sgid);
2259         return sys_setresgid(srgid, segid, ssgid);
2260 }
2261
2262 extern asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
2263
2264 asmlinkage long
2265 sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid,
2266                 __kernel_gid_t32 *sgid) 
2267 {
2268         gid_t a, b, c;
2269         int ret;
2270         mm_segment_t old_fs = get_fs();
2271                 
2272         set_fs (KERNEL_DS);
2273         ret = sys_getresgid(&a, &b, &c);
2274         set_fs (old_fs);
2275         if (!ret) {
2276                 ret = put_user (a, rgid);
2277                 ret |= put_user (b, egid);
2278                 ret |= put_user (c, sgid);
2279         }
2280         return ret;
2281 }
2282
2283 extern asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist);
2284
2285 asmlinkage long
2286 sys32_getgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
2287 {
2288         gid_t gl[NGROUPS];
2289         int ret, i;
2290         mm_segment_t old_fs = get_fs ();
2291         
2292         set_fs (KERNEL_DS);
2293         ret = sys_getgroups(gidsetsize, gl);
2294         set_fs (old_fs);
2295         if (gidsetsize && ret > 0 && ret <= NGROUPS)
2296                 for (i = 0; i < ret; i++, grouplist++)
2297                         if (put_user (gl[i], grouplist))
2298                                 return -EFAULT;
2299         return ret;
2300 }
2301
2302 extern asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist);
2303
2304 asmlinkage long
2305 sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
2306 {
2307         gid_t gl[NGROUPS];
2308         int ret, i;
2309         mm_segment_t old_fs = get_fs ();
2310         
2311         if ((unsigned) gidsetsize > NGROUPS)
2312                 return -EINVAL;
2313         for (i = 0; i < gidsetsize; i++, grouplist++)
2314                 if (get_user (gl[i], grouplist))
2315                         return -EFAULT;
2316         set_fs (KERNEL_DS);
2317         ret = sys_setgroups(gidsetsize, gl);
2318         set_fs (old_fs);
2319         return ret;
2320 }
2321
2322
2323 extern void check_pending(int signum);
2324
2325 asmlinkage long sys_utimes(char *, struct timeval *);
2326
2327 asmlinkage long
2328 sys32_utimes(char *filename, struct timeval32 *tvs)
2329 {
2330         char *kfilename;
2331         struct timeval ktvs[2];
2332         mm_segment_t old_fs;
2333         int ret;
2334
2335         kfilename = getname32(filename);
2336         ret = PTR_ERR(kfilename);
2337         if (!IS_ERR(kfilename)) {
2338                 if (tvs) {
2339                         if (get_tv32(&ktvs[0], tvs) ||
2340                             get_tv32(&ktvs[1], 1+tvs))
2341                                 return -EFAULT;
2342                 }
2343
2344                 old_fs = get_fs();
2345                 set_fs(KERNEL_DS);
2346                 ret = sys_utimes(kfilename, &ktvs[0]);
2347                 set_fs(old_fs);
2348
2349                 putname(kfilename);
2350         }
2351         return ret;
2352 }
2353
2354 /* These are here just in case some old ia32 binary calls it. */
2355 asmlinkage long
2356 sys32_pause(void)
2357 {
2358         current->state = TASK_INTERRUPTIBLE;
2359         schedule();
2360         return -ERESTARTNOHAND;
2361 }
2362
2363
2364 struct sysctl_ia32 {
2365         unsigned int    name;
2366         int             nlen;
2367         unsigned int    oldval;
2368         unsigned int    oldlenp;
2369         unsigned int    newval;
2370         unsigned int    newlen;
2371         unsigned int    __unused[4];
2372 };
2373
2374
2375 asmlinkage long
2376 sys32_sysctl(struct sysctl_ia32 *args32)
2377 {
2378 #ifndef CONFIG_SYSCTL
2379         return -ENOSYS; 
2380 #else
2381         struct sysctl_ia32 a32;
2382         mm_segment_t old_fs = get_fs ();
2383         void *oldvalp, *newvalp;
2384         size_t oldlen;
2385         int *namep;
2386         long ret;
2387         extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,
2388                      void *newval, size_t newlen);
2389
2390
2391         if (copy_from_user(&a32, args32, sizeof (a32)))
2392                 return -EFAULT;
2393
2394         /*
2395          * We need to pre-validate these because we have to disable address checking
2396          * before calling do_sysctl() because of OLDLEN but we can't run the risk of the
2397          * user specifying bad addresses here.  Well, since we're dealing with 32 bit
2398          * addresses, we KNOW that access_ok() will always succeed, so this is an
2399          * expensive NOP, but so what...
2400          */
2401         namep = (int *) A(a32.name);
2402         oldvalp = (void *) A(a32.oldval);
2403         newvalp = (void *) A(a32.newval);
2404
2405         if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))
2406             || !access_ok(VERIFY_WRITE, namep, 0)
2407             || !access_ok(VERIFY_WRITE, oldvalp, 0)
2408             || !access_ok(VERIFY_WRITE, newvalp, 0))
2409                 return -EFAULT;
2410
2411         set_fs(KERNEL_DS);
2412         lock_kernel();
2413         ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);
2414         unlock_kernel();
2415         set_fs(old_fs);
2416
2417         if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))
2418                 return -EFAULT;
2419
2420         return ret;
2421 #endif
2422 }
2423
2424 extern asmlinkage long sys_newuname(struct new_utsname * name);
2425
2426 asmlinkage long
2427 sys32_newuname(struct new_utsname * name)
2428 {
2429         int ret = sys_newuname(name);
2430         
2431         if (current->personality == PER_LINUX32 && !ret) {
2432                 ret = copy_to_user(name->machine, "i386\0\0", 8);
2433         }
2434         return ret;
2435 }
2436
2437 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
2438                                     size_t count, loff_t pos);
2439
2440 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
2441                                      size_t count, loff_t pos);
2442
2443 typedef __kernel_ssize_t32 ssize_t32;
2444
2445 asmlinkage ssize_t32
2446 sys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,
2447             u32 poshi, u32 poslo)
2448 {
2449         return sys_pread(fd, ubuf, count,
2450                          ((loff_t)AA(poshi) << 32) | AA(poslo));
2451 }
2452
2453 asmlinkage ssize_t32
2454 sys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count,
2455              u32 poshi, u32 poslo)
2456 {
2457         return sys_pwrite(fd, ubuf, count,
2458                           ((loff_t)AA(poshi) << 32) | AA(poslo));
2459 }
2460
2461
2462 extern asmlinkage long sys_personality(unsigned long);
2463
2464 asmlinkage long
2465 sys32_personality(unsigned long personality)
2466 {
2467         int ret;
2468         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
2469                 personality = PER_LINUX32;
2470         ret = sys_personality(personality);
2471         if (ret == PER_LINUX32)
2472                 ret = PER_LINUX;
2473         return ret;
2474 }
2475
2476 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,
2477                                        size_t count); 
2478
2479 asmlinkage long
2480 sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
2481 {
2482         mm_segment_t old_fs = get_fs();
2483         int ret;
2484         off_t of;
2485         
2486         if (offset && get_user(of, offset))
2487                 return -EFAULT;
2488                 
2489         set_fs(KERNEL_DS);
2490         ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
2491         set_fs(old_fs);
2492         
2493         if (!ret && offset && put_user(of, offset))
2494                 return -EFAULT;
2495                 
2496         return ret;
2497 }
2498
2499 /* Handle adjtimex compatability. */
2500
2501 struct timex32 {
2502         u32 modes;
2503         s32 offset, freq, maxerror, esterror;
2504         s32 status, constant, precision, tolerance;
2505         struct timeval32 time;
2506         s32 tick;
2507         s32 ppsfreq, jitter, shift, stabil;
2508         s32 jitcnt, calcnt, errcnt, stbcnt;
2509         s32  :32; s32  :32; s32  :32; s32  :32;
2510         s32  :32; s32  :32; s32  :32; s32  :32;
2511         s32  :32; s32  :32; s32  :32; s32  :32;
2512 };
2513
2514 extern int do_adjtimex(struct timex *);
2515
2516 asmlinkage long
2517 sys32_adjtimex(struct timex32 *utp)
2518 {
2519         struct timex txc;
2520         int ret;
2521
2522         memset(&txc, 0, sizeof(struct timex));
2523
2524         if(verify_area(VERIFY_READ, utp, sizeof(struct timex32)) ||
2525            __get_user(txc.modes, &utp->modes) ||
2526            __get_user(txc.offset, &utp->offset) ||
2527            __get_user(txc.freq, &utp->freq) ||
2528            __get_user(txc.maxerror, &utp->maxerror) ||
2529            __get_user(txc.esterror, &utp->esterror) ||
2530            __get_user(txc.status, &utp->status) ||
2531            __get_user(txc.constant, &utp->constant) ||
2532            __get_user(txc.precision, &utp->precision) ||
2533            __get_user(txc.tolerance, &utp->tolerance) ||
2534            __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
2535            __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
2536            __get_user(txc.tick, &utp->tick) ||
2537            __get_user(txc.ppsfreq, &utp->ppsfreq) ||
2538            __get_user(txc.jitter, &utp->jitter) ||
2539            __get_user(txc.shift, &utp->shift) ||
2540            __get_user(txc.stabil, &utp->stabil) ||
2541            __get_user(txc.jitcnt, &utp->jitcnt) ||
2542            __get_user(txc.calcnt, &utp->calcnt) ||
2543            __get_user(txc.errcnt, &utp->errcnt) ||
2544            __get_user(txc.stbcnt, &utp->stbcnt))
2545                 return -EFAULT;
2546
2547         ret = do_adjtimex(&txc);
2548
2549         if(verify_area(VERIFY_WRITE, utp, sizeof(struct timex32)) ||
2550            __put_user(txc.modes, &utp->modes) ||
2551            __put_user(txc.offset, &utp->offset) ||
2552            __put_user(txc.freq, &utp->freq) ||
2553            __put_user(txc.maxerror, &utp->maxerror) ||
2554            __put_user(txc.esterror, &utp->esterror) ||
2555            __put_user(txc.status, &utp->status) ||
2556            __put_user(txc.constant, &utp->constant) ||
2557            __put_user(txc.precision, &utp->precision) ||
2558            __put_user(txc.tolerance, &utp->tolerance) ||
2559            __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
2560            __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
2561            __put_user(txc.tick, &utp->tick) ||
2562            __put_user(txc.ppsfreq, &utp->ppsfreq) ||
2563            __put_user(txc.jitter, &utp->jitter) ||
2564            __put_user(txc.shift, &utp->shift) ||
2565            __put_user(txc.stabil, &utp->stabil) ||
2566            __put_user(txc.jitcnt, &utp->jitcnt) ||
2567            __put_user(txc.calcnt, &utp->calcnt) ||
2568            __put_user(txc.errcnt, &utp->errcnt) ||
2569            __put_user(txc.stbcnt, &utp->stbcnt))
2570                 ret = -EFAULT;
2571
2572         return ret;
2573 }
2574
2575
2576 /* common code for old and new mmaps */
2577 static inline long do_mmap2(
2578         unsigned long addr, unsigned long len,
2579         unsigned long prot, unsigned long flags,
2580         unsigned long fd, unsigned long pgoff)
2581 {
2582         int error = -EBADF;
2583         struct file * file = NULL;
2584
2585         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
2586         if (!(flags & MAP_ANONYMOUS)) {
2587                 file = fget(fd);
2588                 if (!file)
2589                         goto out;
2590         }
2591
2592         down_write(&current->mm->mmap_sem);
2593         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
2594         up_write(&current->mm->mmap_sem);
2595
2596         if (file)
2597                 fput(file);
2598 out:
2599         return error;
2600 }
2601
2602 asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
2603         unsigned long prot, unsigned long flags,
2604         unsigned long fd, unsigned long pgoff)
2605 {
2606         return do_mmap2(addr, len, prot, flags, fd, pgoff);
2607 }
2608
2609
2610 asmlinkage int sys32_olduname(struct oldold_utsname * name)
2611 {
2612         int error;
2613
2614         if (!name)
2615                 return -EFAULT;
2616         if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
2617                 return -EFAULT;
2618   
2619         down_read(&uts_sem);
2620         
2621         error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
2622          __put_user(0,name->sysname+__OLD_UTS_LEN);
2623          __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
2624          __put_user(0,name->nodename+__OLD_UTS_LEN);
2625          __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
2626          __put_user(0,name->release+__OLD_UTS_LEN);
2627          __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
2628          __put_user(0,name->version+__OLD_UTS_LEN);
2629          { 
2630                  char *arch = current->personality == PER_LINUX32
2631                          ? "i386" : "x86_64"; 
2632                  
2633                  __copy_to_user(&name->machine,arch,strlen(arch)+1);
2634          }
2635         
2636          up_read(&uts_sem);
2637          
2638          error = error ? -EFAULT : 0;
2639          
2640          return error;
2641 }
2642
2643 int sys32_uname(struct old_utsname * name)
2644 {
2645         int err;
2646         if (!name)
2647                 return -EFAULT;
2648         down_read(&uts_sem);
2649         err=copy_to_user(name, &system_utsname, sizeof (*name));
2650         up_read(&uts_sem);
2651         return err?-EFAULT:0;
2652 }
2653
2654 extern int sys_ustat(dev_t, struct ustat *);
2655
2656 int sys32_ustat(dev_t dev, struct ustat32 *u32p)
2657 {
2658         struct ustat u;
2659         mm_segment_t seg;
2660         int ret;
2661         
2662         seg = get_fs(); 
2663         set_fs(KERNEL_DS); 
2664         ret = sys_ustat(dev,&u); 
2665         set_fs(seg);
2666         if (ret >= 0) { 
2667                 if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || 
2668                     __put_user((__u32) u.f_tfree, &u32p->f_tfree) ||
2669                     __put_user((__u32) u.f_tinode, &u32p->f_tfree) ||
2670                     __copy_to_user(&u32p->f_fname, u.f_fname, sizeof(u.f_fname)) ||
2671                     __copy_to_user(&u32p->f_fpack, u.f_fpack, sizeof(u.f_fpack)))
2672                         ret = -EFAULT;
2673         }
2674         return ret;
2675
2676
2677 static int nargs(u32 src, char **dst) 
2678
2679         int cnt;
2680         u32 val; 
2681
2682         cnt = 0; 
2683         do {            
2684                 int ret = get_user(val, (__u32 *)(u64)src); 
2685                 if (ret)  {
2686                         return ret;
2687                 }       
2688                 if (dst)
2689                         dst[cnt] = (char *)(u64)val; 
2690                 cnt++;
2691                 src += 4;       
2692         } while(val && cnt < 1023);  // XXX: fix limit.
2693         if (dst)
2694                 dst[cnt-1] = 0; 
2695         return cnt; 
2696
2697
2698 int sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs)
2699
2700         mm_segment_t oldseg; 
2701         char **buf; 
2702         int na,ne;
2703         int ret;
2704
2705         na = nargs(argv, NULL); 
2706         if (na < 0) 
2707                 return -EFAULT; 
2708         ne = nargs(envp, NULL); 
2709         if (ne < 0) 
2710                 return -EFAULT; 
2711
2712         buf = kmalloc((na+ne)*sizeof(char*), GFP_KERNEL); 
2713         if (!buf)
2714                 return -ENOMEM; 
2715         
2716         ret = nargs(argv, buf);
2717         if (ret < 0)
2718                 goto free;
2719
2720         ret = nargs(envp, buf + na); 
2721         if (ret < 0)
2722                 goto free; 
2723
2724         name = getname(name); 
2725         ret = PTR_ERR(name); 
2726         if (IS_ERR(name))
2727                 goto free; 
2728
2729         oldseg = get_fs(); 
2730         set_fs(KERNEL_DS);
2731         ret = do_execve(name, buf, buf+na, &regs);  
2732         set_fs(oldseg); 
2733
2734         if (ret == 0)
2735                 current->ptrace &= ~PT_DTRACE;
2736
2737         putname(name);
2738  
2739 free:
2740         kfree(buf);
2741         return ret; 
2742
2743
2744 asmlinkage int sys32_fork(struct pt_regs regs)
2745 {
2746         return do_fork(SIGCHLD, regs.rsp, &regs, 0);
2747 }
2748
2749 asmlinkage int sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
2750 {
2751         if (!newsp)
2752                 newsp = regs.rsp;
2753         return do_fork(clone_flags, newsp, &regs, 0);
2754 }
2755
2756 /*
2757  * This is trivial, and on the face of it looks like it
2758  * could equally well be done in user mode.
2759  *
2760  * Not so, for quite unobvious reasons - register pressure.
2761  * In user mode vfork() cannot have a stack frame, and if
2762  * done by calling the "clone()" system call directly, you
2763  * do not have enough call-clobbered registers to hold all
2764  * the information you need.
2765  */
2766 asmlinkage int sys32_vfork(struct pt_regs regs)
2767 {
2768         return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, &regs, 0);
2769 }
2770
2771 /*
2772  * Some system calls that need sign extended arguments. This could be done by a generic wrapper.
2773  */ 
2774
2775 extern off_t sys_lseek (unsigned int fd, off_t offset, unsigned int origin);
2776
2777 int sys32_lseek (unsigned int fd, int offset, unsigned int whence)
2778 {
2779         return sys_lseek(fd, offset, whence);
2780 }
2781
2782 extern int sys_kill(pid_t pid, int sig); 
2783
2784 int sys32_kill(int pid, int sig)
2785 {
2786         return sys_kill(pid, sig);
2787 }
2788