ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / s390 / kernel / compat_linux.c
1 /*
2  *  arch/s390x/kernel/linux32.c
3  *
4  *  S390 version
5  *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7  *               Gerhard Tonn (ton@de.ibm.com)   
8  *               Thomas Spatzier (tspat@de.ibm.com)
9  *
10  *  Conversion between 31bit and 64bit native syscalls.
11  *
12  * Heavily inspired by the 32-bit Sparc compat code which is 
13  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
14  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
15  *
16  */
17
18
19 #include <linux/config.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/fs.h> 
23 #include <linux/mm.h> 
24 #include <linux/file.h> 
25 #include <linux/signal.h>
26 #include <linux/resource.h>
27 #include <linux/times.h>
28 #include <linux/utsname.h>
29 #include <linux/timex.h>
30 #include <linux/smp.h>
31 #include <linux/smp_lock.h>
32 #include <linux/sem.h>
33 #include <linux/msg.h>
34 #include <linux/shm.h>
35 #include <linux/slab.h>
36 #include <linux/uio.h>
37 #include <linux/nfs_fs.h>
38 #include <linux/quota.h>
39 #include <linux/module.h>
40 #include <linux/sunrpc/svc.h>
41 #include <linux/nfsd/nfsd.h>
42 #include <linux/nfsd/cache.h>
43 #include <linux/nfsd/xdr.h>
44 #include <linux/nfsd/syscall.h>
45 #include <linux/poll.h>
46 #include <linux/personality.h>
47 #include <linux/stat.h>
48 #include <linux/filter.h>
49 #include <linux/highmem.h>
50 #include <linux/highuid.h>
51 #include <linux/mman.h>
52 #include <linux/ipv6.h>
53 #include <linux/in.h>
54 #include <linux/icmpv6.h>
55 #include <linux/syscalls.h>
56 #include <linux/sysctl.h>
57 #include <linux/binfmts.h>
58 #include <linux/compat.h>
59 #include <linux/vfs.h>
60 #include <linux/ptrace.h>
61
62 #include <asm/types.h>
63 #include <asm/ipc.h>
64 #include <asm/uaccess.h>
65 #include <asm/semaphore.h>
66
67 #include <net/scm.h>
68 #include <net/sock.h>
69
70 #include "compat_linux.h"
71
72  
73 /* For this source file, we want overflow handling. */
74
75 #undef high2lowuid
76 #undef high2lowgid
77 #undef low2highuid
78 #undef low2highgid
79 #undef SET_UID16
80 #undef SET_GID16
81 #undef NEW_TO_OLD_UID
82 #undef NEW_TO_OLD_GID
83 #undef SET_OLDSTAT_UID
84 #undef SET_OLDSTAT_GID
85 #undef SET_STAT_UID
86 #undef SET_STAT_GID
87
88 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
89 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
90 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
91 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
92 #define SET_UID16(var, uid)     var = high2lowuid(uid)
93 #define SET_GID16(var, gid)     var = high2lowgid(gid)
94 #define NEW_TO_OLD_UID(uid)     high2lowuid(uid)
95 #define NEW_TO_OLD_GID(gid)     high2lowgid(gid)
96 #define SET_OLDSTAT_UID(stat, uid)      (stat).st_uid = high2lowuid(uid)
97 #define SET_OLDSTAT_GID(stat, gid)      (stat).st_gid = high2lowgid(gid)
98 #define SET_STAT_UID(stat, uid)         (stat).st_uid = high2lowuid(uid)
99 #define SET_STAT_GID(stat, gid)         (stat).st_gid = high2lowgid(gid)
100
101 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
102 {
103         return sys_chown(filename, low2highuid(user), low2highgid(group));
104 }
105
106 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
107 {
108         return sys_lchown(filename, low2highuid(user), low2highgid(group));
109 }
110
111 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
112 {
113         return sys_fchown(fd, low2highuid(user), low2highgid(group));
114 }
115
116 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
117 {
118         return sys_setregid(low2highgid(rgid), low2highgid(egid));
119 }
120
121 asmlinkage long sys32_setgid16(u16 gid)
122 {
123         return sys_setgid((gid_t)gid);
124 }
125
126 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
127 {
128         return sys_setreuid(low2highuid(ruid), low2highuid(euid));
129 }
130
131 asmlinkage long sys32_setuid16(u16 uid)
132 {
133         return sys_setuid((uid_t)uid);
134 }
135
136 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
137 {
138         return sys_setresuid(low2highuid(ruid), low2highuid(euid),
139                 low2highuid(suid));
140 }
141
142 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
143 {
144         int retval;
145
146         if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
147             !(retval = put_user(high2lowuid(current->euid), euid)))
148                 retval = put_user(high2lowuid(current->suid), suid);
149
150         return retval;
151 }
152
153 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
154 {
155         return sys_setresgid(low2highgid(rgid), low2highgid(egid),
156                 low2highgid(sgid));
157 }
158
159 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
160 {
161         int retval;
162
163         if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
164             !(retval = put_user(high2lowgid(current->egid), egid)))
165                 retval = put_user(high2lowgid(current->sgid), sgid);
166
167         return retval;
168 }
169
170 asmlinkage long sys32_setfsuid16(u16 uid)
171 {
172         return sys_setfsuid((uid_t)uid);
173 }
174
175 asmlinkage long sys32_setfsgid16(u16 gid)
176 {
177         return sys_setfsgid((gid_t)gid);
178 }
179
180 static int groups16_to_user(u16 *grouplist, struct group_info *group_info)
181 {
182         int i;
183         u16 group;
184
185         for (i = 0; i < group_info->ngroups; i++) {
186                 group = (u16)GROUP_AT(group_info, i);
187                 if (put_user(group, grouplist+i))
188                         return -EFAULT;
189         }
190
191         return 0;
192 }
193
194 static int groups16_from_user(struct group_info *group_info, u16 *grouplist)
195 {
196         int i;
197         u16 group;
198
199         for (i = 0; i < group_info->ngroups; i++) {
200                 if (get_user(group, grouplist+i))
201                         return  -EFAULT;
202                 GROUP_AT(group_info, i) = (gid_t)group;
203         }
204
205         return 0;
206 }
207
208 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
209 {
210         int i;
211
212         if (gidsetsize < 0)
213                 return -EINVAL;
214
215         get_group_info(current->group_info);
216         i = current->group_info->ngroups;
217         if (gidsetsize) {
218                 if (i > gidsetsize) {
219                         i = -EINVAL;
220                         goto out;
221                 }
222                 if (groups16_to_user(grouplist, current->group_info)) {
223                         i = -EFAULT;
224                         goto out;
225                 }
226         }
227 out:
228         put_group_info(current->group_info);
229         return i;
230 }
231
232 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
233 {
234         struct group_info *group_info;
235         int retval;
236
237         if (!capable(CAP_SETGID))
238                 return -EPERM;
239         if ((unsigned)gidsetsize > NGROUPS_MAX)
240                 return -EINVAL;
241
242         group_info = groups_alloc(gidsetsize);
243         if (!group_info)
244                 return -ENOMEM;
245         retval = groups16_from_user(group_info, grouplist);
246         if (retval) {
247                 put_group_info(group_info);
248                 return retval;
249         }
250
251         retval = set_current_groups(group_info);
252         put_group_info(group_info);
253
254         return retval;
255 }
256
257 asmlinkage long sys32_getuid16(void)
258 {
259         return high2lowuid(current->uid);
260 }
261
262 asmlinkage long sys32_geteuid16(void)
263 {
264         return high2lowuid(current->euid);
265 }
266
267 asmlinkage long sys32_getgid16(void)
268 {
269         return high2lowgid(current->gid);
270 }
271
272 asmlinkage long sys32_getegid16(void)
273 {
274         return high2lowgid(current->egid);
275 }
276
277 /* 32-bit timeval and related flotsam.  */
278
279 static inline long get_tv32(struct timeval *o, struct compat_timeval *i)
280 {
281         return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
282                 (__get_user(o->tv_sec, &i->tv_sec) ||
283                  __get_user(o->tv_usec, &i->tv_usec)));
284 }
285
286 static inline long put_tv32(struct compat_timeval *o, struct timeval *i)
287 {
288         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
289                 (__put_user(i->tv_sec, &o->tv_sec) ||
290                  __put_user(i->tv_usec, &o->tv_usec)));
291 }
292
293 /*
294  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.
295  *
296  * This is really horribly ugly.
297  */
298 asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
299 {
300         if (call >> 16)         /* hack for backward compatibility */
301                 return -EINVAL;
302
303         call &= 0xffff;
304
305         switch (call) {
306         case SEMTIMEDOP:
307                 return compat_sys_semtimedop(first, compat_ptr(ptr),
308                                              second, compat_ptr(third));
309         case SEMOP:
310                 /* struct sembuf is the same on 32 and 64bit :)) */
311                 return sys_semtimedop(first, compat_ptr(ptr),
312                                       second, NULL);
313         case SEMGET:
314                 return sys_semget(first, second, third);
315         case SEMCTL:
316                 return compat_sys_semctl(first, second, third,
317                                          compat_ptr(ptr));
318         case MSGSND:
319                 return compat_sys_msgsnd(first, second, third,
320                                          compat_ptr(ptr));
321         case MSGRCV:
322                 return compat_sys_msgrcv(first, second, 0, third,
323                                          0, compat_ptr(ptr));
324         case MSGGET:
325                 return sys_msgget((key_t) first, second);
326         case MSGCTL:
327                 return compat_sys_msgctl(first, second, compat_ptr(ptr));
328         case SHMAT:
329                 return compat_sys_shmat(first, second, third,
330                                         0, compat_ptr(ptr));
331         case SHMDT:
332                 return sys_shmdt(compat_ptr(ptr));
333         case SHMGET:
334                 return sys_shmget(first, second, third);
335         case SHMCTL:
336                 return compat_sys_shmctl(first, second, compat_ptr(ptr));
337         }
338
339         return -ENOSYS;
340 }
341
342 asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low)
343 {
344         if ((int)high < 0)
345                 return -EINVAL;
346         else
347                 return sys_truncate(path, (high << 32) | low);
348 }
349
350 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
351 {
352         if ((int)high < 0)
353                 return -EINVAL;
354         else
355                 return sys_ftruncate(fd, (high << 32) | low);
356 }
357
358 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
359 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
360
361 static long do_readv_writev32(int type, struct file *file,
362                               const struct compat_iovec *vector, u32 count)
363 {
364         unsigned long tot_len;
365         struct iovec iovstack[UIO_FASTIOV];
366         struct iovec *iov=iovstack, *ivp;
367         struct inode *inode;
368         long retval, i;
369         io_fn_t fn;
370         iov_fn_t fnv;
371
372         /* First get the "struct iovec" from user memory and
373          * verify all the pointers
374          */
375         if (!count)
376                 return 0;
377         if (verify_area(VERIFY_READ, vector, sizeof(struct compat_iovec)*count))
378                 return -EFAULT;
379         if (count > UIO_MAXIOV)
380                 return -EINVAL;
381         if (count > UIO_FASTIOV) {
382                 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
383                 if (!iov)
384                         return -ENOMEM;
385         }
386
387         tot_len = 0;
388         i = count;
389         ivp = iov;
390         retval = -EINVAL;
391         while(i > 0) {
392                 compat_ssize_t tmp = tot_len;
393                 compat_ssize_t len;
394                 u32 buf;
395
396                 if (__get_user(len, &vector->iov_len) ||
397                     __get_user(buf, &vector->iov_base)) {
398                         retval = -EFAULT;
399                         goto out;
400                 }
401                 if (len < 0)    /* size_t not fitting an ssize_t32 .. */
402                         goto out;
403                 tot_len += len;
404                 if (tot_len < tmp) /* maths overflow on the compat_ssize_t */
405                         goto out;
406                 ivp->iov_base = (void *)A(buf);
407                 ivp->iov_len = (__kernel_size_t) len;
408                 vector++;
409                 ivp++;
410                 i--;
411         }
412         if (tot_len == 0) {
413                 retval = 0;
414                 goto out;
415         }
416
417         inode = file->f_dentry->d_inode;
418         /* VERIFY_WRITE actually means a read, as we write to user space */
419         retval = locks_verify_area((type == VERIFY_WRITE
420                                     ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
421                                    inode, file, file->f_pos, tot_len);
422         if (retval)
423                 goto out;
424
425         /* VERIFY_WRITE actually means a read, as we write to user space */
426         fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
427         if (fnv) {
428                 retval = fnv(file, iov, count, &file->f_pos);
429                 goto out;
430         }
431
432         fn = (type == VERIFY_WRITE ? file->f_op->read :
433               (io_fn_t) file->f_op->write);
434
435         ivp = iov;
436         while (count > 0) {
437                 void * base;
438                 int len, nr;
439
440                 base = ivp->iov_base;
441                 len = ivp->iov_len;
442                 ivp++;
443                 count--;
444                 nr = fn(file, base, len, &file->f_pos);
445                 if (nr < 0) {
446                         if (!retval)
447                                 retval = nr;
448                         break;
449                 }
450                 retval += nr;
451                 if (nr != len)
452                         break;
453         }
454 out:
455         if (iov != iovstack)
456                 kfree(iov);
457
458         return retval;
459 }
460
461 asmlinkage long sys32_readv(int fd, struct compat_iovec *vector, unsigned long count)
462 {
463         struct file *file;
464         long ret = -EBADF;
465
466         file = fget(fd);
467         if(!file)
468                 goto bad_file;
469
470         if (file->f_op && (file->f_mode & FMODE_READ) &&
471             (file->f_op->readv || file->f_op->read))
472                 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
473         fput(file);
474
475 bad_file:
476         return ret;
477 }
478
479 asmlinkage long sys32_writev(int fd, struct compat_iovec *vector, unsigned long count)
480 {
481         struct file *file;
482         int ret = -EBADF;
483
484         file = fget(fd);
485         if(!file)
486                 goto bad_file;
487         if (file->f_op && (file->f_mode & FMODE_WRITE) &&
488             (file->f_op->writev || file->f_op->write))
489                 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
490         fput(file);
491
492 bad_file:
493         return ret;
494 }
495
496 /* readdir & getdents */
497
498 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
499 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
500
501 struct old_linux_dirent32 {
502         u32             d_ino;
503         u32             d_offset;
504         unsigned short  d_namlen;
505         char            d_name[1];
506 };
507
508 struct readdir_callback32 {
509         struct old_linux_dirent32 * dirent;
510         int count;
511 };
512
513 static int fillonedir(void * __buf, const char * name, int namlen,
514                       loff_t offset, ino_t ino, unsigned int d_type)
515 {
516         struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
517         struct old_linux_dirent32 * dirent;
518
519         if (buf->count)
520                 return -EINVAL;
521         buf->count++;
522         dirent = buf->dirent;
523         put_user(ino, &dirent->d_ino);
524         put_user(offset, &dirent->d_offset);
525         put_user(namlen, &dirent->d_namlen);
526         copy_to_user(dirent->d_name, name, namlen);
527         put_user(0, dirent->d_name + namlen);
528         return 0;
529 }
530
531 asmlinkage long old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
532 {
533         int error = -EBADF;
534         struct file * file;
535         struct readdir_callback32 buf;
536
537         file = fget(fd);
538         if (!file)
539                 goto out;
540
541         buf.count = 0;
542         buf.dirent = dirent;
543
544         error = vfs_readdir(file, fillonedir, &buf);
545         if (error < 0)
546                 goto out_putf;
547         error = buf.count;
548
549 out_putf:
550         fput(file);
551 out:
552         return error;
553 }
554
555 struct linux_dirent32 {
556         u32             d_ino;
557         u32             d_off;
558         unsigned short  d_reclen;
559         char            d_name[1];
560 };
561
562 struct getdents_callback32 {
563         struct linux_dirent32 * current_dir;
564         struct linux_dirent32 * previous;
565         int count;
566         int error;
567 };
568
569 static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
570                    unsigned int d_type)
571 {
572         struct linux_dirent32 * dirent;
573         struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
574         int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
575
576         buf->error = -EINVAL;   /* only used if we fail.. */
577         if (reclen > buf->count)
578                 return -EINVAL;
579         dirent = buf->previous;
580         if (dirent)
581                 put_user(offset, &dirent->d_off);
582         dirent = buf->current_dir;
583         buf->previous = dirent;
584         put_user(ino, &dirent->d_ino);
585         put_user(reclen, &dirent->d_reclen);
586         copy_to_user(dirent->d_name, name, namlen);
587         put_user(0, dirent->d_name + namlen);
588         buf->current_dir = ((void *)dirent) + reclen;
589         buf->count -= reclen;
590         return 0;
591 }
592
593 asmlinkage long sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
594 {
595         struct file * file;
596         struct linux_dirent32 * lastdirent;
597         struct getdents_callback32 buf;
598         int error = -EBADF;
599
600         file = fget(fd);
601         if (!file)
602                 goto out;
603
604         buf.current_dir = dirent;
605         buf.previous = NULL;
606         buf.count = count;
607         buf.error = 0;
608
609         error = vfs_readdir(file, filldir, &buf);
610         if (error < 0)
611                 goto out_putf;
612         lastdirent = buf.previous;
613         error = buf.error;
614         if(lastdirent) {
615                 put_user(file->f_pos, &lastdirent->d_off);
616                 error = count - buf.count;
617         }
618 out_putf:
619         fput(file);
620 out:
621         return error;
622 }
623
624 /* end of readdir & getdents */
625
626 /*
627  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
628  * 64-bit unsigned longs.
629  */
630
631 static inline int
632 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
633 {
634         if (ufdset) {
635                 unsigned long odd;
636
637                 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
638                         return -EFAULT;
639
640                 odd = n & 1UL;
641                 n &= ~1UL;
642                 while (n) {
643                         unsigned long h, l;
644                         __get_user(l, ufdset);
645                         __get_user(h, ufdset+1);
646                         ufdset += 2;
647                         *fdset++ = h << 32 | l;
648                         n -= 2;
649                 }
650                 if (odd)
651                         __get_user(*fdset, ufdset);
652         } else {
653                 /* Tricky, must clear full unsigned long in the
654                  * kernel fdset at the end, this makes sure that
655                  * actually happens.
656                  */
657                 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
658         }
659         return 0;
660 }
661
662 static inline void
663 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
664 {
665         unsigned long odd;
666
667         if (!ufdset)
668                 return;
669
670         odd = n & 1UL;
671         n &= ~1UL;
672         while (n) {
673                 unsigned long h, l;
674                 l = *fdset++;
675                 h = l >> 32;
676                 __put_user(l, ufdset);
677                 __put_user(h, ufdset+1);
678                 ufdset += 2;
679                 n -= 2;
680         }
681         if (odd)
682                 __put_user(*fdset, ufdset);
683 }
684
685 #define MAX_SELECT_SECONDS \
686         ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
687
688 asmlinkage long sys32_select(int n, u32 *inp, u32 *outp, u32 *exp,
689                                 struct compat_timeval *tvp)
690 {
691         fd_set_bits fds;
692         char *bits;
693         unsigned long nn;
694         long timeout;
695         int ret, size;
696
697         timeout = MAX_SCHEDULE_TIMEOUT;
698         if (tvp) {
699                 int sec, usec;
700
701                 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
702                     || (ret = __get_user(sec, &tvp->tv_sec))
703                     || (ret = __get_user(usec, &tvp->tv_usec)))
704                         goto out_nofds;
705
706                 ret = -EINVAL;
707                 if(sec < 0 || usec < 0)
708                         goto out_nofds;
709
710                 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
711                         timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
712                         timeout += sec * (unsigned long) HZ;
713                 }
714         }
715
716         ret = -EINVAL;
717         if (n < 0)
718                 goto out_nofds;
719         if (n > current->files->max_fdset)
720                 n = current->files->max_fdset;
721
722         /*
723          * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
724          * since we used fdset we need to allocate memory in units of
725          * long-words. 
726          */
727         ret = -ENOMEM;
728         size = FDS_BYTES(n);
729         bits = kmalloc(6 * size, GFP_KERNEL);
730         if (!bits)
731                 goto out_nofds;
732         fds.in      = (unsigned long *)  bits;
733         fds.out     = (unsigned long *) (bits +   size);
734         fds.ex      = (unsigned long *) (bits + 2*size);
735         fds.res_in  = (unsigned long *) (bits + 3*size);
736         fds.res_out = (unsigned long *) (bits + 4*size);
737         fds.res_ex  = (unsigned long *) (bits + 5*size);
738
739         nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
740         if ((ret = get_fd_set32(nn, fds.in, inp)) ||
741             (ret = get_fd_set32(nn, fds.out, outp)) ||
742             (ret = get_fd_set32(nn, fds.ex, exp)))
743                 goto out;
744         zero_fd_set(n, fds.res_in);
745         zero_fd_set(n, fds.res_out);
746         zero_fd_set(n, fds.res_ex);
747
748         ret = do_select(n, &fds, &timeout);
749
750         if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
751                 int sec = 0, usec = 0;
752                 if (timeout) {
753                         sec = timeout / HZ;
754                         usec = timeout % HZ;
755                         usec *= (1000000/HZ);
756                 }
757                 put_user(sec, &tvp->tv_sec);
758                 put_user(usec, &tvp->tv_usec);
759         }
760
761         if (ret < 0)
762                 goto out;
763         if (!ret) {
764                 ret = -ERESTARTNOHAND;
765                 if (signal_pending(current))
766                         goto out;
767                 ret = 0;
768         }
769
770         set_fd_set32(nn, inp, fds.res_in);
771         set_fd_set32(nn, outp, fds.res_out);
772         set_fd_set32(nn, exp, fds.res_ex);
773
774 out:
775         kfree(bits);
776 out_nofds:
777         return ret;
778 }
779
780 int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf)
781 {
782         int err;
783
784         if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
785                 return -EOVERFLOW;
786
787         err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
788         err |= put_user(stat->ino, &statbuf->st_ino);
789         err |= put_user(stat->mode, &statbuf->st_mode);
790         err |= put_user(stat->nlink, &statbuf->st_nlink);
791         err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
792         err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
793         err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
794         err |= put_user(stat->size, &statbuf->st_size);
795         err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
796         err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
797         err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
798         err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
799         err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
800         err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
801         err |= put_user(stat->blksize, &statbuf->st_blksize);
802         err |= put_user(stat->blocks, &statbuf->st_blocks);
803 /* fixme
804         err |= put_user(0, &statbuf->__unused4[0]);
805         err |= put_user(0, &statbuf->__unused4[1]);
806 */
807         return err;
808 }
809
810 struct sysinfo32 {
811         s32 uptime;
812         u32 loads[3];
813         u32 totalram;
814         u32 freeram;
815         u32 sharedram;
816         u32 bufferram;
817         u32 totalswap;
818         u32 freeswap;
819         unsigned short procs;
820         unsigned short pads;
821         u32 totalhigh;
822         u32 freehigh;
823         unsigned int mem_unit;
824         char _f[8];
825 };
826
827 asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
828 {
829         struct sysinfo s;
830         int ret, err;
831         mm_segment_t old_fs = get_fs ();
832         
833         set_fs (KERNEL_DS);
834         ret = sys_sysinfo(&s);
835         set_fs (old_fs);
836         err = put_user (s.uptime, &info->uptime);
837         err |= __put_user (s.loads[0], &info->loads[0]);
838         err |= __put_user (s.loads[1], &info->loads[1]);
839         err |= __put_user (s.loads[2], &info->loads[2]);
840         err |= __put_user (s.totalram, &info->totalram);
841         err |= __put_user (s.freeram, &info->freeram);
842         err |= __put_user (s.sharedram, &info->sharedram);
843         err |= __put_user (s.bufferram, &info->bufferram);
844         err |= __put_user (s.totalswap, &info->totalswap);
845         err |= __put_user (s.freeswap, &info->freeswap);
846         err |= __put_user (s.procs, &info->procs);
847         err |= __put_user (s.totalhigh, &info->totalhigh);
848         err |= __put_user (s.freehigh, &info->freehigh);
849         err |= __put_user (s.mem_unit, &info->mem_unit);
850         if (err)
851                 return -EFAULT;
852         return ret;
853 }
854
855 asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid,
856                                 struct compat_timespec __user *interval)
857 {
858         struct timespec t;
859         int ret;
860         mm_segment_t old_fs = get_fs ();
861         
862         set_fs (KERNEL_DS);
863         ret = sys_sched_rr_get_interval(pid, &t);
864         set_fs (old_fs);
865         if (put_compat_timespec(&t, interval))
866                 return -EFAULT;
867         return ret;
868 }
869
870 asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
871                         compat_sigset_t __user *oset, size_t sigsetsize)
872 {
873         sigset_t s;
874         compat_sigset_t s32;
875         int ret;
876         mm_segment_t old_fs = get_fs();
877         
878         if (set) {
879                 if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
880                         return -EFAULT;
881                 switch (_NSIG_WORDS) {
882                 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
883                 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
884                 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
885                 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
886                 }
887         }
888         set_fs (KERNEL_DS);
889         ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
890         set_fs (old_fs);
891         if (ret) return ret;
892         if (oset) {
893                 switch (_NSIG_WORDS) {
894                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
895                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
896                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
897                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
898                 }
899                 if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
900                         return -EFAULT;
901         }
902         return 0;
903 }
904
905 asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
906                                 size_t sigsetsize)
907 {
908         sigset_t s;
909         compat_sigset_t s32;
910         int ret;
911         mm_segment_t old_fs = get_fs();
912                 
913         set_fs (KERNEL_DS);
914         ret = sys_rt_sigpending(&s, sigsetsize);
915         set_fs (old_fs);
916         if (!ret) {
917                 switch (_NSIG_WORDS) {
918                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
919                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
920                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
921                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
922                 }
923                 if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
924                         return -EFAULT;
925         }
926         return ret;
927 }
928
929 extern int
930 copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from);
931
932 asmlinkage long
933 sys32_rt_sigtimedwait(compat_sigset_t *uthese, siginfo_t32 *uinfo,
934                       struct compat_timespec *uts, size_t sigsetsize)
935 {
936         int ret, sig;
937         sigset_t these;
938         compat_sigset_t these32;
939         struct timespec ts;
940         siginfo_t info;
941         long timeout = 0;
942
943         /* XXX: Don't preclude handling different sized sigset_t's.  */
944         if (sigsetsize != sizeof(sigset_t))
945                 return -EINVAL;
946
947         if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t)))
948                 return -EFAULT;
949
950         switch (_NSIG_WORDS) {
951         case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
952         case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
953         case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
954         case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
955         }
956                 
957         /*
958          * Invert the set of allowed signals to get those we
959          * want to block.
960          */
961         sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
962         signotset(&these);
963
964         if (uts) {
965                 if (get_compat_timespec(&ts, uts))
966                         return -EINVAL;
967                 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
968                     || ts.tv_sec < 0)
969                         return -EINVAL;
970         }
971
972         spin_lock_irq(&current->sighand->siglock);
973         sig = dequeue_signal(current, &these, &info);
974         if (!sig) {
975                 /* None ready -- temporarily unblock those we're interested
976                    in so that we'll be awakened when they arrive.  */
977                 current->real_blocked = current->blocked;
978                 sigandsets(&current->blocked, &current->blocked, &these);
979                 recalc_sigpending();
980                 spin_unlock_irq(&current->sighand->siglock);
981
982                 timeout = MAX_SCHEDULE_TIMEOUT;
983                 if (uts)
984                         timeout = (timespec_to_jiffies(&ts)
985                                    + (ts.tv_sec || ts.tv_nsec));
986
987                 current->state = TASK_INTERRUPTIBLE;
988                 timeout = schedule_timeout(timeout);
989
990                 spin_lock_irq(&current->sighand->siglock);
991                 sig = dequeue_signal(current, &these, &info);
992                 current->blocked = current->real_blocked;
993                 siginitset(&current->real_blocked, 0);
994                 recalc_sigpending();
995         }
996         spin_unlock_irq(&current->sighand->siglock);
997
998         if (sig) {
999                 ret = sig;
1000                 if (uinfo) {
1001                         if (copy_siginfo_to_user32(uinfo, &info))
1002                                 ret = -EFAULT;
1003                 }
1004         } else {
1005                 ret = -EAGAIN;
1006                 if (timeout)
1007                         ret = -EINTR;
1008         }
1009
1010         return ret;
1011 }
1012
1013 asmlinkage long
1014 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo)
1015 {
1016         siginfo_t info;
1017         int ret;
1018         mm_segment_t old_fs = get_fs();
1019         
1020         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
1021             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
1022                 return -EFAULT;
1023         set_fs (KERNEL_DS);
1024         ret = sys_rt_sigqueueinfo(pid, sig, &info);
1025         set_fs (old_fs);
1026         return ret;
1027 }
1028
1029 extern void check_pending(int signum);
1030
1031 /*
1032  * count32() counts the number of arguments/envelopes
1033  */
1034 static int count32(u32 * argv)
1035 {
1036         int i = 0;
1037
1038         if (argv != NULL) {
1039                 for (;;) {
1040                         u32 p; int error;
1041
1042                         error = get_user(p,argv);
1043                         if (error) return error;
1044                         if (!p) break;
1045                         argv++; i++;
1046                 }
1047         }
1048         return i;
1049 }
1050
1051 /*
1052  * 'copy_string32()' copies argument/envelope strings from user
1053  * memory to free pages in kernel mem. These are in a format ready
1054  * to be put directly into the top of new user memory.
1055  */
1056 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
1057 {
1058         while (argc-- > 0) {
1059                 u32 str;
1060                 int len;
1061                 unsigned long pos;
1062
1063                 if (get_user(str, argv + argc) ||
1064                     !str ||
1065                     !(len = strnlen_user((char *)A(str), bprm->p)))
1066                         return -EFAULT;
1067
1068                 if (bprm->p < len)
1069                         return -E2BIG;
1070
1071                 bprm->p -= len;
1072
1073                 pos = bprm->p;
1074                 while (len) {
1075                         char *kaddr;
1076                         struct page *page;
1077                         int offset, bytes_to_copy, new, err;
1078
1079                         offset = pos % PAGE_SIZE;
1080                         page = bprm->page[pos / PAGE_SIZE];
1081                         new = 0;
1082                         if (!page) {
1083                                 page = alloc_page(GFP_USER);
1084                                 bprm->page[pos / PAGE_SIZE] = page;
1085                                 if (!page)
1086                                         return -ENOMEM;
1087                                 new = 1;
1088                         }
1089                         kaddr = (char *)kmap(page);
1090
1091                         if (new && offset)
1092                                 memset(kaddr, 0, offset);
1093                         bytes_to_copy = PAGE_SIZE - offset;
1094                         if (bytes_to_copy > len) {
1095                                 bytes_to_copy = len;
1096                                 if (new)
1097                                         memset(kaddr+offset+len, 0,
1098                                                PAGE_SIZE-offset-len);
1099                         }
1100
1101                         err = copy_from_user(kaddr + offset, (char *)A(str),
1102                                              bytes_to_copy);
1103                         kunmap(page);
1104
1105                         if (err)
1106                                 return -EFAULT;
1107
1108                         pos += bytes_to_copy;
1109                         str += bytes_to_copy;
1110                         len -= bytes_to_copy;
1111                 }
1112         }
1113         return 0;
1114 }
1115
1116 /*
1117  * sys32_execve() executes a new program.
1118  */
1119 static inline int 
1120 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
1121 {
1122         struct linux_binprm bprm;
1123         struct file * file;
1124         int retval;
1125         int i;
1126
1127         sched_balance_exec();
1128
1129         file = open_exec(filename);
1130
1131         retval = PTR_ERR(file);
1132         if (IS_ERR(file))
1133                 return retval;
1134
1135         bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
1136         memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
1137
1138         bprm.file = file;
1139         bprm.filename = filename;
1140         bprm.interp = filename;
1141         bprm.sh_bang = 0;
1142         bprm.loader = 0;
1143         bprm.exec = 0;
1144         bprm.mm = mm_alloc();
1145         retval = -ENOMEM;
1146         if (!bprm.mm)
1147                 goto out_file;
1148
1149         /* init_new_context is empty for s390x. */
1150
1151         bprm.argc = count32(argv);
1152         if ((retval = bprm.argc) < 0)
1153                 goto out_mm;
1154
1155         bprm.envc = count32(envp);
1156         if ((retval = bprm.envc) < 0)
1157                 goto out_mm;
1158
1159         retval = security_bprm_alloc(&bprm);
1160         if (retval)
1161                 goto out;
1162
1163         retval = prepare_binprm(&bprm);
1164         if (retval < 0)
1165                 goto out;
1166         
1167         retval = copy_strings_kernel(1, &bprm.filename, &bprm);
1168         if (retval < 0)
1169                 goto out;
1170
1171         bprm.exec = bprm.p;
1172         retval = copy_strings32(bprm.envc, envp, &bprm);
1173         if (retval < 0)
1174                 goto out;
1175
1176         retval = copy_strings32(bprm.argc, argv, &bprm);
1177         if (retval < 0)
1178                 goto out;
1179
1180         retval = search_binary_handler(&bprm, regs);
1181         if (retval >= 0) {
1182                 /* execve success */
1183                 security_bprm_free(&bprm);
1184                 return retval;
1185         }
1186
1187 out:
1188         /* Something went wrong, return the inode and free the argument pages*/
1189         for (i=0 ; i<MAX_ARG_PAGES ; i++) {
1190                 struct page * page = bprm.page[i];
1191                 if (page)
1192                         __free_page(page);
1193         }
1194
1195         if (bprm.security)
1196                 security_bprm_free(&bprm);
1197
1198 out_mm:
1199         if (bprm.mm)
1200                 mmdrop(bprm.mm);
1201
1202 out_file:
1203         if (bprm.file) {
1204                 allow_write_access(bprm.file);
1205                 fput(bprm.file);
1206         }
1207
1208         return retval;
1209 }
1210
1211 /*
1212  * sys32_execve() executes a new program after the asm stub has set
1213  * things up for us.  This should basically do what I want it to.
1214  */
1215 asmlinkage long
1216 sys32_execve(struct pt_regs regs)
1217 {
1218         int error;
1219         char * filename;
1220
1221         filename = getname((char *)A(regs.orig_gpr2));
1222         error = PTR_ERR(filename);
1223         if (IS_ERR(filename))
1224                 goto out;
1225         error = do_execve32(filename, (u32 *)A(regs.gprs[3]), (u32 *)A(regs.gprs[4]), &regs);
1226         if (error == 0)
1227         {
1228                 current->ptrace &= ~PT_DTRACE;
1229                 current->thread.fp_regs.fpc=0;
1230                 __asm__ __volatile__
1231                         ("sr  0,0\n\t"
1232                          "sfpc 0,0\n\t"
1233                          : : :"0");
1234         }
1235         putname(filename);
1236 out:
1237         return error;
1238 }
1239
1240
1241 #ifdef CONFIG_MODULES
1242
1243 asmlinkage long
1244 sys32_init_module(void __user *umod, unsigned long len,
1245                 const char __user *uargs)
1246 {
1247         return sys_init_module(umod, len, uargs);
1248 }
1249
1250 asmlinkage long
1251 sys32_delete_module(const char __user *name_user, unsigned int flags)
1252 {
1253         return sys_delete_module(name_user, flags);
1254 }
1255
1256 #else /* CONFIG_MODULES */
1257
1258 asmlinkage long
1259 sys32_init_module(void __user *umod, unsigned long len,
1260                 const char __user *uargs)
1261 {
1262         return -ENOSYS;
1263 }
1264
1265 asmlinkage long
1266 sys32_delete_module(const char __user *name_user, unsigned int flags)
1267 {
1268         return -ENOSYS;
1269 }
1270
1271 #endif  /* CONFIG_MODULES */
1272
1273 /* Stuff for NFS server syscalls... */
1274 struct nfsctl_svc32 {
1275         u16                     svc32_port;
1276         s32                     svc32_nthreads;
1277 };
1278
1279 struct nfsctl_client32 {
1280         s8                      cl32_ident[NFSCLNT_IDMAX+1];
1281         s32                     cl32_naddr;
1282         struct in_addr          cl32_addrlist[NFSCLNT_ADDRMAX];
1283         s32                     cl32_fhkeytype;
1284         s32                     cl32_fhkeylen;
1285         u8                      cl32_fhkey[NFSCLNT_KEYMAX];
1286 };
1287
1288 struct nfsctl_export32 {
1289         s8                      ex32_client[NFSCLNT_IDMAX+1];
1290         s8                      ex32_path[NFS_MAXPATHLEN+1];
1291         compat_dev_t    ex32_dev;
1292         compat_ino_t    ex32_ino;
1293         s32                     ex32_flags;
1294         compat_uid_t    ex32_anon_uid;
1295         compat_gid_t    ex32_anon_gid;
1296 };
1297
1298 struct nfsctl_fdparm32 {
1299         struct sockaddr         gd32_addr;
1300         s8                      gd32_path[NFS_MAXPATHLEN+1];
1301         s32                     gd32_version;
1302 };
1303
1304 struct nfsctl_fsparm32 {
1305         struct sockaddr         gd32_addr;
1306         s8                      gd32_path[NFS_MAXPATHLEN+1];
1307         s32                     gd32_maxlen;
1308 };
1309
1310 struct nfsctl_arg32 {
1311         s32                     ca32_version;   /* safeguard */
1312         union {
1313                 struct nfsctl_svc32     u32_svc;
1314                 struct nfsctl_client32  u32_client;
1315                 struct nfsctl_export32  u32_export;
1316                 struct nfsctl_fdparm32  u32_getfd;
1317                 struct nfsctl_fsparm32  u32_getfs;
1318         } u;
1319 #define ca32_svc        u.u32_svc
1320 #define ca32_client     u.u32_client
1321 #define ca32_export     u.u32_export
1322 #define ca32_getfd      u.u32_getfd
1323 #define ca32_getfs      u.u32_getfs
1324 #define ca32_authd      u.u32_authd
1325 };
1326
1327 union nfsctl_res32 {
1328         __u8                    cr32_getfh[NFS_FHSIZE];
1329         struct knfsd_fh         cr32_getfs;
1330 };
1331
1332 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
1333 {
1334         int err;
1335         
1336         err = __get_user(karg->ca_version, &arg32->ca32_version);
1337         err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
1338         err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
1339         return err;
1340 }
1341
1342 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
1343 {
1344         int err;
1345         
1346         err = __get_user(karg->ca_version, &arg32->ca32_version);
1347         err |= copy_from_user(&karg->ca_client.cl_ident[0],
1348                           &arg32->ca32_client.cl32_ident[0],
1349                           NFSCLNT_IDMAX);
1350         err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
1351         err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
1352                           &arg32->ca32_client.cl32_addrlist[0],
1353                           (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
1354         err |= __get_user(karg->ca_client.cl_fhkeytype,
1355                       &arg32->ca32_client.cl32_fhkeytype);
1356         err |= __get_user(karg->ca_client.cl_fhkeylen,
1357                       &arg32->ca32_client.cl32_fhkeylen);
1358         err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
1359                           &arg32->ca32_client.cl32_fhkey[0],
1360                           NFSCLNT_KEYMAX);
1361         return err;
1362 }
1363
1364 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
1365 {
1366         int err;
1367         
1368         err = __get_user(karg->ca_version, &arg32->ca32_version);
1369         err |= copy_from_user(&karg->ca_export.ex_client[0],
1370                           &arg32->ca32_export.ex32_client[0],
1371                           NFSCLNT_IDMAX);
1372         err |= copy_from_user(&karg->ca_export.ex_path[0],
1373                           &arg32->ca32_export.ex32_path[0],
1374                           NFS_MAXPATHLEN);
1375         err |= __get_user(karg->ca_export.ex_dev,
1376                       &arg32->ca32_export.ex32_dev);
1377         err |= __get_user(karg->ca_export.ex_ino,
1378                       &arg32->ca32_export.ex32_ino);
1379         err |= __get_user(karg->ca_export.ex_flags,
1380                       &arg32->ca32_export.ex32_flags);
1381         err |= __get_user(karg->ca_export.ex_anon_uid,
1382                       &arg32->ca32_export.ex32_anon_uid);
1383         err |= __get_user(karg->ca_export.ex_anon_gid,
1384                       &arg32->ca32_export.ex32_anon_gid);
1385         karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
1386         karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
1387         return err;
1388 }
1389
1390 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
1391 {
1392         int err;
1393         
1394         err = __get_user(karg->ca_version, &arg32->ca32_version);
1395         err |= copy_from_user(&karg->ca_getfd.gd_addr,
1396                           &arg32->ca32_getfd.gd32_addr,
1397                           (sizeof(struct sockaddr)));
1398         err |= copy_from_user(&karg->ca_getfd.gd_path,
1399                           &arg32->ca32_getfd.gd32_path,
1400                           (NFS_MAXPATHLEN+1));
1401         err |= __get_user(karg->ca_getfd.gd_version,
1402                       &arg32->ca32_getfd.gd32_version);
1403         return err;
1404 }
1405
1406 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
1407 {
1408         int err;
1409         
1410         err = __get_user(karg->ca_version, &arg32->ca32_version);
1411         err |= copy_from_user(&karg->ca_getfs.gd_addr,
1412                           &arg32->ca32_getfs.gd32_addr,
1413                           (sizeof(struct sockaddr)));
1414         err |= copy_from_user(&karg->ca_getfs.gd_path,
1415                           &arg32->ca32_getfs.gd32_path,
1416                           (NFS_MAXPATHLEN+1));
1417         err |= __get_user(karg->ca_getfs.gd_maxlen,
1418                       &arg32->ca32_getfs.gd32_maxlen);
1419         return err;
1420 }
1421
1422 /* This really doesn't need translations, we are only passing
1423  * back a union which contains opaque nfs file handle data.
1424  */
1425 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
1426 {
1427         return copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0;
1428 }
1429
1430 long asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
1431 {
1432         struct nfsctl_arg *karg = NULL;
1433         union nfsctl_res *kres = NULL;
1434         mm_segment_t oldfs;
1435         int err;
1436
1437         karg = kmalloc(sizeof(*karg), GFP_USER);
1438         if(!karg)
1439                 return -ENOMEM;
1440         if(res32) {
1441                 kres = kmalloc(sizeof(*kres), GFP_USER);
1442                 if(!kres) {
1443                         kfree(karg);
1444                         return -ENOMEM;
1445                 }
1446         }
1447         switch(cmd) {
1448         case NFSCTL_SVC:
1449                 err = nfs_svc32_trans(karg, arg32);
1450                 break;
1451         case NFSCTL_ADDCLIENT:
1452                 err = nfs_clnt32_trans(karg, arg32);
1453                 break;
1454         case NFSCTL_DELCLIENT:
1455                 err = nfs_clnt32_trans(karg, arg32);
1456                 break;
1457         case NFSCTL_EXPORT:
1458         case NFSCTL_UNEXPORT:
1459                 err = nfs_exp32_trans(karg, arg32);
1460                 break;
1461         case NFSCTL_GETFD:
1462                 err = nfs_getfd32_trans(karg, arg32);
1463                 break;
1464         case NFSCTL_GETFS:
1465                 err = nfs_getfs32_trans(karg, arg32);
1466                 break;
1467         default:
1468                 err = -EINVAL;
1469                 break;
1470         }
1471         if(err)
1472                 goto done;
1473         oldfs = get_fs();
1474         set_fs(KERNEL_DS);
1475         err = sys_nfsservctl(cmd, karg, kres);
1476         set_fs(oldfs);
1477
1478         if (err)
1479                 goto done;
1480
1481         if((cmd == NFSCTL_GETFD) ||
1482            (cmd == NFSCTL_GETFS))
1483                 err = nfs_getfh32_res_trans(kres, res32);
1484
1485 done:
1486         if(karg)
1487                 kfree(karg);
1488         if(kres)
1489                 kfree(kres);
1490         return err;
1491 }
1492
1493 /* Translations due to time_t size differences.  Which affects all
1494    sorts of things, like timeval and itimerval.  */
1495
1496 extern struct timezone sys_tz;
1497
1498 asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz)
1499 {
1500         if (tv) {
1501                 struct timeval ktv;
1502                 do_gettimeofday(&ktv);
1503                 if (put_tv32(tv, &ktv))
1504                         return -EFAULT;
1505         }
1506         if (tz) {
1507                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
1508                         return -EFAULT;
1509         }
1510         return 0;
1511 }
1512
1513 static inline long get_ts32(struct timespec *o, struct compat_timeval *i)
1514 {
1515         long usec;
1516
1517         if (!access_ok(VERIFY_READ, i, sizeof(*i)))
1518                 return -EFAULT;
1519         if (__get_user(o->tv_sec, &i->tv_sec))
1520                 return -EFAULT;
1521         if (__get_user(usec, &i->tv_usec))
1522                 return -EFAULT;
1523         o->tv_nsec = usec * 1000;
1524         return 0;
1525 }
1526
1527 asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz)
1528 {
1529         struct timespec kts;
1530         struct timezone ktz;
1531
1532         if (tv) {
1533                 if (get_ts32(&kts, tv))
1534                         return -EFAULT;
1535         }
1536         if (tz) {
1537                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
1538                         return -EFAULT;
1539         }
1540
1541         return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
1542 }
1543
1544 /* These are here just in case some old sparc32 binary calls it. */
1545 asmlinkage long sys32_pause(void)
1546 {
1547         current->state = TASK_INTERRUPTIBLE;
1548         schedule();
1549         return -ERESTARTNOHAND;
1550 }
1551
1552 asmlinkage long sys32_pread64(unsigned int fd, char *ubuf,
1553                                 size_t count, u32 poshi, u32 poslo)
1554 {
1555         if ((compat_ssize_t) count < 0)
1556                 return -EINVAL;
1557         return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
1558 }
1559
1560 asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf,
1561                                 size_t count, u32 poshi, u32 poslo)
1562 {
1563         if ((compat_ssize_t) count < 0)
1564                 return -EINVAL;
1565         return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
1566 }
1567
1568 asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
1569 {
1570         return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
1571 }
1572
1573 asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count)
1574 {
1575         mm_segment_t old_fs = get_fs();
1576         int ret;
1577         off_t of;
1578         
1579         if (offset && get_user(of, offset))
1580                 return -EFAULT;
1581                 
1582         set_fs(KERNEL_DS);
1583         ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
1584         set_fs(old_fs);
1585         
1586         if (!ret && offset && put_user(of, offset))
1587                 return -EFAULT;
1588                 
1589         return ret;
1590 }
1591
1592 asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
1593                                 compat_loff_t *offset, s32 count)
1594 {
1595         mm_segment_t old_fs = get_fs();
1596         int ret;
1597         loff_t lof;
1598         
1599         if (offset && get_user(lof, offset))
1600                 return -EFAULT;
1601                 
1602         set_fs(KERNEL_DS);
1603         ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count);
1604         set_fs(old_fs);
1605         
1606         if (offset && put_user(lof, offset))
1607                 return -EFAULT;
1608                 
1609         return ret;
1610 }
1611
1612 /* Handle adjtimex compatibility. */
1613
1614 struct timex32 {
1615         u32 modes;
1616         s32 offset, freq, maxerror, esterror;
1617         s32 status, constant, precision, tolerance;
1618         struct compat_timeval time;
1619         s32 tick;
1620         s32 ppsfreq, jitter, shift, stabil;
1621         s32 jitcnt, calcnt, errcnt, stbcnt;
1622         s32  :32; s32  :32; s32  :32; s32  :32;
1623         s32  :32; s32  :32; s32  :32; s32  :32;
1624         s32  :32; s32  :32; s32  :32; s32  :32;
1625 };
1626
1627 extern int do_adjtimex(struct timex *);
1628
1629 asmlinkage long sys32_adjtimex(struct timex32 *utp)
1630 {
1631         struct timex txc;
1632         int ret;
1633
1634         memset(&txc, 0, sizeof(struct timex));
1635
1636         if(get_user(txc.modes, &utp->modes) ||
1637            __get_user(txc.offset, &utp->offset) ||
1638            __get_user(txc.freq, &utp->freq) ||
1639            __get_user(txc.maxerror, &utp->maxerror) ||
1640            __get_user(txc.esterror, &utp->esterror) ||
1641            __get_user(txc.status, &utp->status) ||
1642            __get_user(txc.constant, &utp->constant) ||
1643            __get_user(txc.precision, &utp->precision) ||
1644            __get_user(txc.tolerance, &utp->tolerance) ||
1645            __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
1646            __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
1647            __get_user(txc.tick, &utp->tick) ||
1648            __get_user(txc.ppsfreq, &utp->ppsfreq) ||
1649            __get_user(txc.jitter, &utp->jitter) ||
1650            __get_user(txc.shift, &utp->shift) ||
1651            __get_user(txc.stabil, &utp->stabil) ||
1652            __get_user(txc.jitcnt, &utp->jitcnt) ||
1653            __get_user(txc.calcnt, &utp->calcnt) ||
1654            __get_user(txc.errcnt, &utp->errcnt) ||
1655            __get_user(txc.stbcnt, &utp->stbcnt))
1656                 return -EFAULT;
1657
1658         ret = do_adjtimex(&txc);
1659
1660         if(put_user(txc.modes, &utp->modes) ||
1661            __put_user(txc.offset, &utp->offset) ||
1662            __put_user(txc.freq, &utp->freq) ||
1663            __put_user(txc.maxerror, &utp->maxerror) ||
1664            __put_user(txc.esterror, &utp->esterror) ||
1665            __put_user(txc.status, &utp->status) ||
1666            __put_user(txc.constant, &utp->constant) ||
1667            __put_user(txc.precision, &utp->precision) ||
1668            __put_user(txc.tolerance, &utp->tolerance) ||
1669            __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
1670            __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
1671            __put_user(txc.tick, &utp->tick) ||
1672            __put_user(txc.ppsfreq, &utp->ppsfreq) ||
1673            __put_user(txc.jitter, &utp->jitter) ||
1674            __put_user(txc.shift, &utp->shift) ||
1675            __put_user(txc.stabil, &utp->stabil) ||
1676            __put_user(txc.jitcnt, &utp->jitcnt) ||
1677            __put_user(txc.calcnt, &utp->calcnt) ||
1678            __put_user(txc.errcnt, &utp->errcnt) ||
1679            __put_user(txc.stbcnt, &utp->stbcnt))
1680                 ret = -EFAULT;
1681
1682         return ret;
1683 }
1684
1685 struct __sysctl_args32 {
1686         u32 name;
1687         int nlen;
1688         u32 oldval;
1689         u32 oldlenp;
1690         u32 newval;
1691         u32 newlen;
1692         u32 __unused[4];
1693 };
1694
1695 asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
1696 {
1697         struct __sysctl_args32 tmp;
1698         int error;
1699         size_t oldlen, *oldlenp = NULL;
1700         unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
1701
1702         if (copy_from_user(&tmp, args, sizeof(tmp)))
1703                 return -EFAULT;
1704
1705         if (tmp.oldval && tmp.oldlenp) {
1706                 /* Duh, this is ugly and might not work if sysctl_args
1707                    is in read-only memory, but do_sysctl does indirectly
1708                    a lot of uaccess in both directions and we'd have to
1709                    basically copy the whole sysctl.c here, and
1710                    glibc's __sysctl uses rw memory for the structure
1711                    anyway.  */
1712                 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
1713                     put_user(oldlen, (size_t *)addr))
1714                         return -EFAULT;
1715                 oldlenp = (size_t *)addr;
1716         }
1717
1718         lock_kernel();
1719         error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
1720                           oldlenp, (void *)A(tmp.newval), tmp.newlen);
1721         unlock_kernel();
1722         if (oldlenp) {
1723                 if (!error) {
1724                         if (get_user(oldlen, (size_t *)addr) ||
1725                             put_user(oldlen, (u32 *)A(tmp.oldlenp)))
1726                                 error = -EFAULT;
1727                 }
1728                 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
1729         }
1730         return error;
1731 }
1732
1733 struct stat64_emu31 {
1734         unsigned long long  st_dev;
1735         unsigned int    __pad1;
1736 #define STAT64_HAS_BROKEN_ST_INO        1
1737         u32             __st_ino;
1738         unsigned int    st_mode;
1739         unsigned int    st_nlink;
1740         u32             st_uid;
1741         u32             st_gid;
1742         unsigned long long  st_rdev;
1743         unsigned int    __pad3;
1744         long            st_size;
1745         u32             st_blksize;
1746         unsigned char   __pad4[4];
1747         u32             __pad5;     /* future possible st_blocks high bits */
1748         u32             st_blocks;  /* Number 512-byte blocks allocated. */
1749         u32             st_atime;
1750         u32             __pad6;
1751         u32             st_mtime;
1752         u32             __pad7;
1753         u32             st_ctime;
1754         u32             __pad8;     /* will be high 32 bits of ctime someday */
1755         unsigned long   st_ino;
1756 };      
1757
1758 static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
1759 {
1760         struct stat64_emu31 tmp;
1761
1762         memset(&tmp, 0, sizeof(tmp));
1763
1764         tmp.st_dev = huge_encode_dev(stat->dev);
1765         tmp.st_ino = stat->ino;
1766         tmp.__st_ino = (u32)stat->ino;
1767         tmp.st_mode = stat->mode;
1768         tmp.st_nlink = (unsigned int)stat->nlink;
1769         tmp.st_uid = stat->uid;
1770         tmp.st_gid = stat->gid;
1771         tmp.st_rdev = huge_encode_dev(stat->rdev);
1772         tmp.st_size = stat->size;
1773         tmp.st_blksize = (u32)stat->blksize;
1774         tmp.st_blocks = (u32)stat->blocks;
1775         tmp.st_atime = (u32)stat->atime.tv_sec;
1776         tmp.st_mtime = (u32)stat->mtime.tv_sec;
1777         tmp.st_ctime = (u32)stat->ctime.tv_sec;
1778
1779         return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 
1780 }
1781
1782 asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf)
1783 {
1784         struct kstat stat;
1785         int ret = vfs_stat(filename, &stat);
1786         if (!ret)
1787                 ret = cp_stat64(statbuf, &stat);
1788         return ret;
1789 }
1790
1791 asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf)
1792 {
1793         struct kstat stat;
1794         int ret = vfs_lstat(filename, &stat);
1795         if (!ret)
1796                 ret = cp_stat64(statbuf, &stat);
1797         return ret;
1798 }
1799
1800 asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf)
1801 {
1802         struct kstat stat;
1803         int ret = vfs_fstat(fd, &stat);
1804         if (!ret)
1805                 ret = cp_stat64(statbuf, &stat);
1806         return ret;
1807 }
1808
1809 /*
1810  * Linux/i386 didn't use to be able to handle more than
1811  * 4 system call parameters, so these system calls used a memory
1812  * block for parameter passing..
1813  */
1814
1815 struct mmap_arg_struct_emu31 {
1816         u32     addr;
1817         u32     len;
1818         u32     prot;
1819         u32     flags;
1820         u32     fd;
1821         u32     offset;
1822 };
1823
1824 /* common code for old and new mmaps */
1825 static inline long do_mmap2(
1826         unsigned long addr, unsigned long len,
1827         unsigned long prot, unsigned long flags,
1828         unsigned long fd, unsigned long pgoff)
1829 {
1830         struct file * file = NULL;
1831         unsigned long error = -EBADF;
1832
1833         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1834         if (!(flags & MAP_ANONYMOUS)) {
1835                 file = fget(fd);
1836                 if (!file)
1837                         goto out;
1838         }
1839
1840         down_write(&current->mm->mmap_sem);
1841         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1842         if (!IS_ERR((void *) error) && error + len >= 0x80000000ULL) {
1843                 /* Result is out of bounds.  */
1844                 do_munmap(current->mm, addr, len);
1845                 error = -ENOMEM;
1846         }
1847         up_write(&current->mm->mmap_sem);
1848
1849         if (file)
1850                 fput(file);
1851 out:    
1852         return error;
1853 }
1854
1855
1856 asmlinkage unsigned long
1857 old32_mmap(struct mmap_arg_struct_emu31 *arg)
1858 {
1859         struct mmap_arg_struct_emu31 a;
1860         int error = -EFAULT;
1861
1862         if (copy_from_user(&a, arg, sizeof(a)))
1863                 goto out;
1864
1865         error = -EINVAL;
1866         if (a.offset & ~PAGE_MASK)
1867                 goto out;
1868
1869         error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT); 
1870 out:
1871         return error;
1872 }
1873
1874 asmlinkage long 
1875 sys32_mmap2(struct mmap_arg_struct_emu31 *arg)
1876 {
1877         struct mmap_arg_struct_emu31 a;
1878         int error = -EFAULT;
1879
1880         if (copy_from_user(&a, arg, sizeof(a)))
1881                 goto out;
1882         error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
1883 out:
1884         return error;
1885 }
1886
1887 asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count)
1888 {
1889         if ((compat_ssize_t) count < 0)
1890                 return -EINVAL; 
1891
1892         return sys_read(fd, buf, count);
1893 }
1894
1895 asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count)
1896 {
1897         if ((compat_ssize_t) count < 0)
1898                 return -EINVAL; 
1899
1900         return sys_write(fd, buf, count);
1901 }
1902
1903 asmlinkage long sys32_clone(struct pt_regs regs)
1904 {
1905         unsigned long clone_flags;
1906         unsigned long newsp;
1907         int *parent_tidptr, *child_tidptr;
1908
1909         clone_flags = regs.gprs[3] & 0xffffffffUL;
1910         newsp = regs.orig_gpr2 & 0x7fffffffUL;
1911         parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL);
1912         child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
1913         if (!newsp)
1914                 newsp = regs.gprs[15];
1915         return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
1916                        parent_tidptr, child_tidptr);
1917 }
1918
1919 /*
1920  * Wrapper function for sys_timer_create.
1921  */
1922 extern asmlinkage long
1923 sys_timer_create(clockid_t, struct sigevent *, timer_t *);
1924
1925 asmlinkage long
1926 sys32_timer_create(clockid_t which_clock, struct sigevent32 *se32,
1927                 timer_t *timer_id)
1928 {
1929         struct sigevent se;
1930         timer_t ktimer_id;
1931         mm_segment_t old_fs;
1932         long ret;
1933
1934         if (se32 == NULL)
1935                 return sys_timer_create(which_clock, NULL, timer_id);
1936
1937         /* XXX: converting se32 to se is filthy because of the
1938          * two union members. For now it is ok, because the pointers
1939          * are not touched in kernel.
1940          */
1941         memset(&se, 0, sizeof(se));
1942         if (get_user(se.sigev_value.sival_int,  &se32->sigev_value.sival_int) ||
1943             get_user(se.sigev_signo, &se32->sigev_signo) ||
1944             get_user(se.sigev_notify, &se32->sigev_notify) ||
1945             copy_from_user(&se._sigev_un._pad, &se32->_sigev_un._pad,
1946             sizeof(se._sigev_un._pad)))
1947                 return -EFAULT;
1948
1949         old_fs = get_fs();
1950         set_fs(KERNEL_DS);
1951         ret = sys_timer_create(which_clock, &se, &ktimer_id);
1952         set_fs(old_fs);
1953
1954         if (!ret)
1955                 ret = put_user (ktimer_id, timer_id);
1956
1957         return ret;
1958 }