Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / arch / mips / kernel / linux32.c
1 /*
2  * Conversion between 32-bit and 64-bit native system calls.
3  *
4  * Copyright (C) 2000 Silicon Graphics, Inc.
5  * Written by Ulf Carlsson (ulfc@engr.sgi.com)
6  * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
7  */
8 #include <linux/compiler.h>
9 #include <linux/mm.h>
10 #include <linux/errno.h>
11 #include <linux/file.h>
12 #include <linux/smp_lock.h>
13 #include <linux/highuid.h>
14 #include <linux/dirent.h>
15 #include <linux/resource.h>
16 #include <linux/highmem.h>
17 #include <linux/time.h>
18 #include <linux/times.h>
19 #include <linux/poll.h>
20 #include <linux/slab.h>
21 #include <linux/skbuff.h>
22 #include <linux/filter.h>
23 #include <linux/shm.h>
24 #include <linux/sem.h>
25 #include <linux/msg.h>
26 #include <linux/icmpv6.h>
27 #include <linux/syscalls.h>
28 #include <linux/sysctl.h>
29 #include <linux/utime.h>
30 #include <linux/utsname.h>
31 #include <linux/personality.h>
32 #include <linux/dnotify.h>
33 #include <linux/module.h>
34 #include <linux/binfmts.h>
35 #include <linux/security.h>
36 #include <linux/compat.h>
37 #include <linux/vfs.h>
38 #include <linux/vs_cvirt.h>
39
40 #include <net/sock.h>
41 #include <net/scm.h>
42
43 #include <asm/ipc.h>
44 #include <asm/sim.h>
45 #include <asm/uaccess.h>
46 #include <asm/mmu_context.h>
47 #include <asm/mman.h>
48
49 /* Use this to get at 32-bit user passed pointers. */
50 /* A() macro should be used for places where you e.g.
51    have some internal variable u32 and just want to get
52    rid of a compiler warning. AA() has to be used in
53    places where you want to convert a function argument
54    to 32bit pointer or when you e.g. access pt_regs
55    structure and want to consider 32bit registers only.
56  */
57 #define A(__x) ((unsigned long)(__x))
58 #define AA(__x) ((unsigned long)((int)__x))
59
60 #ifdef __MIPSEB__
61 #define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
62 #endif
63 #ifdef __MIPSEL__
64 #define merge_64(r1,r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
65 #endif
66
67 /*
68  * Revalidate the inode. This is required for proper NFS attribute caching.
69  */
70
71 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
72 {
73         struct compat_stat tmp;
74
75         if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
76                 return -EOVERFLOW;
77
78         memset(&tmp, 0, sizeof(tmp));
79         tmp.st_dev = new_encode_dev(stat->dev);
80         tmp.st_ino = stat->ino;
81         if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
82                 return -EOVERFLOW;
83         tmp.st_mode = stat->mode;
84         tmp.st_nlink = stat->nlink;
85         SET_UID(tmp.st_uid, stat->uid);
86         SET_GID(tmp.st_gid, stat->gid);
87         tmp.st_rdev = new_encode_dev(stat->rdev);
88         tmp.st_size = stat->size;
89         tmp.st_atime = stat->atime.tv_sec;
90         tmp.st_mtime = stat->mtime.tv_sec;
91         tmp.st_ctime = stat->ctime.tv_sec;
92 #ifdef STAT_HAVE_NSEC
93         tmp.st_atime_nsec = stat->atime.tv_nsec;
94         tmp.st_mtime_nsec = stat->mtime.tv_nsec;
95         tmp.st_ctime_nsec = stat->ctime.tv_nsec;
96 #endif
97         tmp.st_blocks = stat->blocks;
98         tmp.st_blksize = stat->blksize;
99         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
100 }
101
102 asmlinkage unsigned long
103 sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
104          unsigned long flags, unsigned long fd, unsigned long pgoff)
105 {
106         struct file * file = NULL;
107         unsigned long error;
108
109         error = -EINVAL;
110         if (pgoff & (~PAGE_MASK >> 12))
111                 goto out;
112         pgoff >>= PAGE_SHIFT-12;
113
114         if (!(flags & MAP_ANONYMOUS)) {
115                 error = -EBADF;
116                 file = fget(fd);
117                 if (!file)
118                         goto out;
119         }
120         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
121
122         down_write(&current->mm->mmap_sem);
123         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
124         up_write(&current->mm->mmap_sem);
125         if (file)
126                 fput(file);
127
128 out:
129         return error;
130 }
131
132
133 asmlinkage int sys_truncate64(const char __user *path, unsigned int high,
134                               unsigned int low)
135 {
136         if ((int)high < 0)
137                 return -EINVAL;
138         return sys_truncate(path, ((long) high << 32) | low);
139 }
140
141 asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
142                                unsigned int low)
143 {
144         if ((int)high < 0)
145                 return -EINVAL;
146         return sys_ftruncate(fd, ((long) high << 32) | low);
147 }
148
149 /*
150  * sys_execve() executes a new program.
151  */
152 asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
153 {
154         int error;
155         char * filename;
156
157         filename = getname(compat_ptr(regs.regs[4]));
158         error = PTR_ERR(filename);
159         if (IS_ERR(filename))
160                 goto out;
161         error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
162                                  compat_ptr(regs.regs[6]), &regs);
163         putname(filename);
164
165 out:
166         return error;
167 }
168
169 asmlinkage long
170 sysn32_waitid(int which, compat_pid_t pid,
171               siginfo_t __user *uinfo, int options,
172               struct compat_rusage __user *uru)
173 {
174         struct rusage ru;
175         long ret;
176         mm_segment_t old_fs = get_fs();
177         int si_signo;
178
179         if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo)))
180                 return -EFAULT;
181
182         set_fs (KERNEL_DS);
183         ret = sys_waitid(which, pid, uinfo, options,
184                          uru ? (struct rusage __user *) &ru : NULL);
185         set_fs (old_fs);
186
187         if (__get_user(si_signo, &uinfo->si_signo))
188                 return -EFAULT;
189         if (ret < 0 || si_signo == 0)
190                 return ret;
191
192         if (uru)
193                 ret = put_compat_rusage(&ru, uru);
194         return ret;
195 }
196
197 struct sysinfo32 {
198         s32 uptime;
199         u32 loads[3];
200         u32 totalram;
201         u32 freeram;
202         u32 sharedram;
203         u32 bufferram;
204         u32 totalswap;
205         u32 freeswap;
206         u16 procs;
207         u32 totalhigh;
208         u32 freehigh;
209         u32 mem_unit;
210         char _f[8];
211 };
212
213 asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info)
214 {
215         struct sysinfo s;
216         int ret, err;
217         mm_segment_t old_fs = get_fs ();
218
219         set_fs (KERNEL_DS);
220         ret = sys_sysinfo((struct sysinfo __user *)&s);
221         set_fs (old_fs);
222         err = put_user (s.uptime, &info->uptime);
223         err |= __put_user (s.loads[0], &info->loads[0]);
224         err |= __put_user (s.loads[1], &info->loads[1]);
225         err |= __put_user (s.loads[2], &info->loads[2]);
226         err |= __put_user (s.totalram, &info->totalram);
227         err |= __put_user (s.freeram, &info->freeram);
228         err |= __put_user (s.sharedram, &info->sharedram);
229         err |= __put_user (s.bufferram, &info->bufferram);
230         err |= __put_user (s.totalswap, &info->totalswap);
231         err |= __put_user (s.freeswap, &info->freeswap);
232         err |= __put_user (s.procs, &info->procs);
233         err |= __put_user (s.totalhigh, &info->totalhigh);
234         err |= __put_user (s.freehigh, &info->freehigh);
235         err |= __put_user (s.mem_unit, &info->mem_unit);
236         if (err)
237                 return -EFAULT;
238         return ret;
239 }
240
241 #define RLIM_INFINITY32 0x7fffffff
242 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
243
244 struct rlimit32 {
245         int     rlim_cur;
246         int     rlim_max;
247 };
248
249 #ifdef __MIPSEB__
250 asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
251         int length_hi, int length_lo)
252 #endif
253 #ifdef __MIPSEL__
254 asmlinkage long sys32_truncate64(const char __user * path, unsigned long __dummy,
255         int length_lo, int length_hi)
256 #endif
257 {
258         loff_t length;
259
260         length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
261
262         return sys_truncate(path, length);
263 }
264
265 #ifdef __MIPSEB__
266 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
267         int length_hi, int length_lo)
268 #endif
269 #ifdef __MIPSEL__
270 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
271         int length_lo, int length_hi)
272 #endif
273 {
274         loff_t length;
275
276         length = ((unsigned long) length_hi << 32) | (unsigned int) length_lo;
277
278         return sys_ftruncate(fd, length);
279 }
280
281 static inline long
282 get_tv32(struct timeval *o, struct compat_timeval __user *i)
283 {
284         return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
285                 (__get_user(o->tv_sec, &i->tv_sec) |
286                  __get_user(o->tv_usec, &i->tv_usec)));
287 }
288
289 static inline long
290 put_tv32(struct compat_timeval __user *o, struct timeval *i)
291 {
292         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
293                 (__put_user(i->tv_sec, &o->tv_sec) |
294                  __put_user(i->tv_usec, &o->tv_usec)));
295 }
296
297 extern struct timezone sys_tz;
298
299 asmlinkage int
300 sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
301 {
302         if (tv) {
303                 struct timeval ktv;
304                 do_gettimeofday(&ktv);
305                 if (put_tv32(tv, &ktv))
306                         return -EFAULT;
307         }
308         if (tz) {
309                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
310                         return -EFAULT;
311         }
312         return 0;
313 }
314
315 static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
316 {
317         long usec;
318
319         if (!access_ok(VERIFY_READ, i, sizeof(*i)))
320                 return -EFAULT;
321         if (__get_user(o->tv_sec, &i->tv_sec))
322                 return -EFAULT;
323         if (__get_user(usec, &i->tv_usec))
324                 return -EFAULT;
325         o->tv_nsec = usec * 1000;
326                 return 0;
327 }
328
329 asmlinkage int
330 sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
331 {
332         struct timespec kts;
333         struct timezone ktz;
334
335         if (tv) {
336                 if (get_ts32(&kts, tv))
337                         return -EFAULT;
338         }
339         if (tz) {
340                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
341                         return -EFAULT;
342         }
343
344         return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
345 }
346
347 asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
348                             unsigned int offset_low, loff_t __user * result,
349                             unsigned int origin)
350 {
351         return sys_llseek(fd, offset_high, offset_low, result, origin);
352 }
353
354 /* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
355    lseek back to original location.  They fail just like lseek does on
356    non-seekable files.  */
357
358 asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf,
359                                size_t count, u32 unused, u64 a4, u64 a5)
360 {
361         return sys_pread64(fd, buf, count, merge_64(a4, a5));
362 }
363
364 asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf,
365                                 size_t count, u32 unused, u64 a4, u64 a5)
366 {
367         return sys_pwrite64(fd, buf, count, merge_64(a4, a5));
368 }
369
370 asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
371         struct compat_timespec __user *interval)
372 {
373         struct timespec t;
374         int ret;
375         mm_segment_t old_fs = get_fs ();
376
377         set_fs (KERNEL_DS);
378         ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
379         set_fs (old_fs);
380         if (put_user (t.tv_sec, &interval->tv_sec) ||
381             __put_user (t.tv_nsec, &interval->tv_nsec))
382                 return -EFAULT;
383         return ret;
384 }
385
386 struct msgbuf32 { s32 mtype; char mtext[1]; };
387
388 struct ipc_perm32
389 {
390         key_t             key;
391         __compat_uid_t  uid;
392         __compat_gid_t  gid;
393         __compat_uid_t  cuid;
394         __compat_gid_t  cgid;
395         compat_mode_t   mode;
396         unsigned short  seq;
397 };
398
399 struct ipc64_perm32 {
400         key_t key;
401         __compat_uid_t uid;
402         __compat_gid_t gid;
403         __compat_uid_t cuid;
404         __compat_gid_t cgid;
405         compat_mode_t   mode;
406         unsigned short  seq;
407         unsigned short __pad1;
408         unsigned int __unused1;
409         unsigned int __unused2;
410 };
411
412 struct semid_ds32 {
413         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
414         compat_time_t   sem_otime;              /* last semop time */
415         compat_time_t   sem_ctime;              /* last change time */
416         u32 sem_base;              /* ptr to first semaphore in array */
417         u32 sem_pending;          /* pending operations to be processed */
418         u32 sem_pending_last;    /* last pending operation */
419         u32 undo;                  /* undo requests on this array */
420         unsigned short  sem_nsems;              /* no. of semaphores in array */
421 };
422
423 struct semid64_ds32 {
424         struct ipc64_perm32     sem_perm;
425         compat_time_t   sem_otime;
426         compat_time_t   sem_ctime;
427         unsigned int            sem_nsems;
428         unsigned int            __unused1;
429         unsigned int            __unused2;
430 };
431
432 struct msqid_ds32
433 {
434         struct ipc_perm32 msg_perm;
435         u32 msg_first;
436         u32 msg_last;
437         compat_time_t   msg_stime;
438         compat_time_t   msg_rtime;
439         compat_time_t   msg_ctime;
440         u32 wwait;
441         u32 rwait;
442         unsigned short msg_cbytes;
443         unsigned short msg_qnum;
444         unsigned short msg_qbytes;
445         compat_ipc_pid_t msg_lspid;
446         compat_ipc_pid_t msg_lrpid;
447 };
448
449 struct msqid64_ds32 {
450         struct ipc64_perm32 msg_perm;
451         compat_time_t msg_stime;
452         unsigned int __unused1;
453         compat_time_t msg_rtime;
454         unsigned int __unused2;
455         compat_time_t msg_ctime;
456         unsigned int __unused3;
457         unsigned int msg_cbytes;
458         unsigned int msg_qnum;
459         unsigned int msg_qbytes;
460         compat_pid_t msg_lspid;
461         compat_pid_t msg_lrpid;
462         unsigned int __unused4;
463         unsigned int __unused5;
464 };
465
466 struct shmid_ds32 {
467         struct ipc_perm32       shm_perm;
468         int                     shm_segsz;
469         compat_time_t           shm_atime;
470         compat_time_t           shm_dtime;
471         compat_time_t           shm_ctime;
472         compat_ipc_pid_t    shm_cpid;
473         compat_ipc_pid_t    shm_lpid;
474         unsigned short          shm_nattch;
475 };
476
477 struct shmid64_ds32 {
478         struct ipc64_perm32     shm_perm;
479         compat_size_t           shm_segsz;
480         compat_time_t           shm_atime;
481         compat_time_t           shm_dtime;
482         compat_time_t shm_ctime;
483         compat_pid_t shm_cpid;
484         compat_pid_t shm_lpid;
485         unsigned int shm_nattch;
486         unsigned int __unused1;
487         unsigned int __unused2;
488 };
489
490 struct ipc_kludge32 {
491         u32 msgp;
492         s32 msgtyp;
493 };
494
495 static int
496 do_sys32_semctl(int first, int second, int third, void __user *uptr)
497 {
498         union semun fourth;
499         u32 pad;
500         int err, err2;
501         struct semid64_ds s;
502         mm_segment_t old_fs;
503
504         if (!uptr)
505                 return -EINVAL;
506         err = -EFAULT;
507         if (get_user (pad, (u32 __user *)uptr))
508                 return err;
509         if ((third & ~IPC_64) == SETVAL)
510                 fourth.val = (int)pad;
511         else
512                 fourth.__pad = (void __user *)A(pad);
513         switch (third & ~IPC_64) {
514         case IPC_INFO:
515         case IPC_RMID:
516         case IPC_SET:
517         case SEM_INFO:
518         case GETVAL:
519         case GETPID:
520         case GETNCNT:
521         case GETZCNT:
522         case GETALL:
523         case SETVAL:
524         case SETALL:
525                 err = sys_semctl (first, second, third, fourth);
526                 break;
527
528         case IPC_STAT:
529         case SEM_STAT:
530                 fourth.__pad = (struct semid64_ds __user *)&s;
531                 old_fs = get_fs();
532                 set_fs(KERNEL_DS);
533                 err = sys_semctl(first, second, third | IPC_64, fourth);
534                 set_fs(old_fs);
535
536                 if (third & IPC_64) {
537                         struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad);
538
539                         if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
540                                 err = -EFAULT;
541                                 break;
542                         }
543                         err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
544                         err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
545                         err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
546                         err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
547                         err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
548                         err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
549                         err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
550                         err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
551                         err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
552                         err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
553                 } else {
554                         struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad);
555
556                         if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
557                                 err = -EFAULT;
558                                 break;
559                         }
560                         err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
561                         err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
562                         err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
563                         err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
564                         err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
565                         err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
566                         err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
567                         err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
568                         err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
569                         err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
570                 }
571                 if (err2)
572                         err = -EFAULT;
573                 break;
574
575         default:
576                 err = - EINVAL;
577                 break;
578         }
579
580         return err;
581 }
582
583 static int
584 do_sys32_msgsnd (int first, int second, int third, void __user *uptr)
585 {
586         struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr;
587         struct msgbuf *p;
588         mm_segment_t old_fs;
589         int err;
590
591         if (second < 0)
592                 return -EINVAL;
593         p = kmalloc (second + sizeof (struct msgbuf)
594                                     + 4, GFP_USER);
595         if (!p)
596                 return -ENOMEM;
597         err = get_user (p->mtype, &up->mtype);
598         if (err)
599                 goto out;
600         err |= __copy_from_user (p->mtext, &up->mtext, second);
601         if (err)
602                 goto out;
603         old_fs = get_fs ();
604         set_fs (KERNEL_DS);
605         err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third);
606         set_fs (old_fs);
607 out:
608         kfree (p);
609
610         return err;
611 }
612
613 static int
614 do_sys32_msgrcv (int first, int second, int msgtyp, int third,
615                  int version, void __user *uptr)
616 {
617         struct msgbuf32 __user *up;
618         struct msgbuf *p;
619         mm_segment_t old_fs;
620         int err;
621
622         if (!version) {
623                 struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr;
624                 struct ipc_kludge32 ipck;
625
626                 err = -EINVAL;
627                 if (!uptr)
628                         goto out;
629                 err = -EFAULT;
630                 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
631                         goto out;
632                 uptr = (void __user *)AA(ipck.msgp);
633                 msgtyp = ipck.msgtyp;
634         }
635
636         if (second < 0)
637                 return -EINVAL;
638         err = -ENOMEM;
639         p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
640         if (!p)
641                 goto out;
642         old_fs = get_fs ();
643         set_fs (KERNEL_DS);
644         err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third);
645         set_fs (old_fs);
646         if (err < 0)
647                 goto free_then_out;
648         up = (struct msgbuf32 __user *)uptr;
649         if (put_user (p->mtype, &up->mtype) ||
650             __copy_to_user (&up->mtext, p->mtext, err))
651                 err = -EFAULT;
652 free_then_out:
653         kfree (p);
654 out:
655         return err;
656 }
657
658 static int
659 do_sys32_msgctl (int first, int second, void __user *uptr)
660 {
661         int err = -EINVAL, err2;
662         struct msqid64_ds m;
663         struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr;
664         struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr;
665         mm_segment_t old_fs;
666
667         switch (second & ~IPC_64) {
668         case IPC_INFO:
669         case IPC_RMID:
670         case MSG_INFO:
671                 err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr);
672                 break;
673
674         case IPC_SET:
675                 if (second & IPC_64) {
676                         if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
677                                 err = -EFAULT;
678                                 break;
679                         }
680                         err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
681                         err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
682                         err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
683                         err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
684                 } else {
685                         if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
686                                 err = -EFAULT;
687                                 break;
688                         }
689                         err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
690                         err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
691                         err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
692                         err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
693                 }
694                 if (err)
695                         break;
696                 old_fs = get_fs();
697                 set_fs(KERNEL_DS);
698                 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
699                 set_fs(old_fs);
700                 break;
701
702         case IPC_STAT:
703         case MSG_STAT:
704                 old_fs = get_fs();
705                 set_fs(KERNEL_DS);
706                 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
707                 set_fs(old_fs);
708                 if (second & IPC_64) {
709                         if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
710                                 err = -EFAULT;
711                                 break;
712                         }
713                         err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
714                         err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
715                         err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
716                         err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
717                         err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
718                         err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
719                         err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
720                         err2 |= __put_user(m.msg_stime, &up64->msg_stime);
721                         err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
722                         err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
723                         err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
724                         err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
725                         err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
726                         err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
727                         err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
728                         if (err2)
729                                 err = -EFAULT;
730                 } else {
731                         if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
732                                 err = -EFAULT;
733                                 break;
734                         }
735                         err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
736                         err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
737                         err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
738                         err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
739                         err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
740                         err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
741                         err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
742                         err2 |= __put_user(m.msg_stime, &up32->msg_stime);
743                         err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
744                         err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
745                         err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
746                         err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
747                         err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
748                         err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
749                         err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
750                         if (err2)
751                                 err = -EFAULT;
752                 }
753                 break;
754         }
755
756         return err;
757 }
758
759 static int
760 do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
761 {
762         unsigned long raddr;
763         u32 __user *uaddr = (u32 __user *)A((u32)third);
764         int err = -EINVAL;
765
766         if (version == 1)
767                 return err;
768         err = do_shmat (first, uptr, second, &raddr);
769         if (err)
770                 return err;
771         err = put_user (raddr, uaddr);
772         return err;
773 }
774
775 struct shm_info32 {
776         int used_ids;
777         u32 shm_tot, shm_rss, shm_swp;
778         u32 swap_attempts, swap_successes;
779 };
780
781 static int
782 do_sys32_shmctl (int first, int second, void __user *uptr)
783 {
784         struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr;
785         struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr;
786         struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr;
787         int err = -EFAULT, err2;
788         struct shmid64_ds s64;
789         mm_segment_t old_fs;
790         struct shm_info si;
791         struct shmid_ds s;
792
793         switch (second & ~IPC_64) {
794         case IPC_INFO:
795                 second = IPC_INFO; /* So that we don't have to translate it */
796         case IPC_RMID:
797         case SHM_LOCK:
798         case SHM_UNLOCK:
799                 err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr);
800                 break;
801         case IPC_SET:
802                 if (second & IPC_64) {
803                         err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
804                         err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
805                         err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
806                 } else {
807                         err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
808                         err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
809                         err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
810                 }
811                 if (err)
812                         break;
813                 old_fs = get_fs();
814                 set_fs(KERNEL_DS);
815                 err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s);
816                 set_fs(old_fs);
817                 break;
818
819         case IPC_STAT:
820         case SHM_STAT:
821                 old_fs = get_fs();
822                 set_fs(KERNEL_DS);
823                 err = sys_shmctl(first, second | IPC_64, (void __user *) &s64);
824                 set_fs(old_fs);
825                 if (err < 0)
826                         break;
827                 if (second & IPC_64) {
828                         if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
829                                 err = -EFAULT;
830                                 break;
831                         }
832                         err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
833                         err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
834                         err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
835                         err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
836                         err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
837                         err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
838                         err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
839                         err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
840                         err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
841                         err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
842                         err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
843                         err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
844                         err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
845                         err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
846                 } else {
847                         if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
848                                 err = -EFAULT;
849                                 break;
850                         }
851                         err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
852                         err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
853                         err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
854                         err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
855                         err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
856                         err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
857                         err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
858                         err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
859                         err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
860                         err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
861                         err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
862                         err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
863                         err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
864                         err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
865                 }
866                 if (err2)
867                         err = -EFAULT;
868                 break;
869
870         case SHM_INFO:
871                 old_fs = get_fs();
872                 set_fs(KERNEL_DS);
873                 err = sys_shmctl(first, second, (void __user *)&si);
874                 set_fs(old_fs);
875                 if (err < 0)
876                         break;
877                 err2 = put_user(si.used_ids, &uip->used_ids);
878                 err2 |= __put_user(si.shm_tot, &uip->shm_tot);
879                 err2 |= __put_user(si.shm_rss, &uip->shm_rss);
880                 err2 |= __put_user(si.shm_swp, &uip->shm_swp);
881                 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
882                 err2 |= __put_user (si.swap_successes, &uip->swap_successes);
883                 if (err2)
884                         err = -EFAULT;
885                 break;
886
887         default:
888                 err = -EINVAL;
889                 break;
890         }
891
892         return err;
893 }
894
895 static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems,
896                             const struct compat_timespec __user *timeout32)
897 {
898         struct compat_timespec t32;
899         struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64));
900
901         if (copy_from_user(&t32, timeout32, sizeof(t32)))
902                 return -EFAULT;
903
904         if (put_user(t32.tv_sec, &t64->tv_sec) ||
905             put_user(t32.tv_nsec, &t64->tv_nsec))
906                 return -EFAULT;
907
908         return sys_semtimedop(semid, tsems, nsems, t64);
909 }
910
911 asmlinkage long
912 sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
913 {
914         int version, err;
915
916         version = call >> 16; /* hack for backward compatibility */
917         call &= 0xffff;
918
919         switch (call) {
920         case SEMOP:
921                 /* struct sembuf is the same on 32 and 64bit :)) */
922                 err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
923                                       NULL);
924                 break;
925         case SEMTIMEDOP:
926                 err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second,
927                                       (const struct compat_timespec __user *)AA(fifth));
928                 break;
929         case SEMGET:
930                 err = sys_semget (first, second, third);
931                 break;
932         case SEMCTL:
933                 err = do_sys32_semctl (first, second, third,
934                                        (void __user *)AA(ptr));
935                 break;
936
937         case MSGSND:
938                 err = do_sys32_msgsnd (first, second, third,
939                                        (void __user *)AA(ptr));
940                 break;
941         case MSGRCV:
942                 err = do_sys32_msgrcv (first, second, fifth, third,
943                                        version, (void __user *)AA(ptr));
944                 break;
945         case MSGGET:
946                 err = sys_msgget ((key_t) first, second);
947                 break;
948         case MSGCTL:
949                 err = do_sys32_msgctl (first, second, (void __user *)AA(ptr));
950                 break;
951
952         case SHMAT:
953                 err = do_sys32_shmat (first, second, third,
954                                       version, (void __user *)AA(ptr));
955                 break;
956         case SHMDT:
957                 err = sys_shmdt ((char __user *)A(ptr));
958                 break;
959         case SHMGET:
960                 err = sys_shmget (first, (unsigned)second, third);
961                 break;
962         case SHMCTL:
963                 err = do_sys32_shmctl (first, second, (void __user *)AA(ptr));
964                 break;
965         default:
966                 err = -EINVAL;
967                 break;
968         }
969
970         return err;
971 }
972
973 asmlinkage long sys32_shmat(int shmid, char __user *shmaddr,
974                           int shmflg, int32_t __user *addr)
975 {
976         unsigned long raddr;
977         int err;
978
979         err = do_shmat(shmid, shmaddr, shmflg, &raddr);
980         if (err)
981                 return err;
982
983         return put_user(raddr, addr);
984 }
985
986 struct sysctl_args32
987 {
988         compat_caddr_t name;
989         int nlen;
990         compat_caddr_t oldval;
991         compat_caddr_t oldlenp;
992         compat_caddr_t newval;
993         compat_size_t newlen;
994         unsigned int __unused[4];
995 };
996
997 #ifdef CONFIG_SYSCTL
998
999 asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args)
1000 {
1001         struct sysctl_args32 tmp;
1002         int error;
1003         size_t oldlen;
1004         size_t __user *oldlenp = NULL;
1005         unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7;
1006
1007         if (copy_from_user(&tmp, args, sizeof(tmp)))
1008                 return -EFAULT;
1009
1010         if (tmp.oldval && tmp.oldlenp) {
1011                 /* Duh, this is ugly and might not work if sysctl_args
1012                    is in read-only memory, but do_sysctl does indirectly
1013                    a lot of uaccess in both directions and we'd have to
1014                    basically copy the whole sysctl.c here, and
1015                    glibc's __sysctl uses rw memory for the structure
1016                    anyway.  */
1017                 if (get_user(oldlen, (u32 __user *)A(tmp.oldlenp)) ||
1018                     put_user(oldlen, (size_t __user *)addr))
1019                         return -EFAULT;
1020                 oldlenp = (size_t __user *)addr;
1021         }
1022
1023         lock_kernel();
1024         error = do_sysctl((int __user *)A(tmp.name), tmp.nlen, (void __user *)A(tmp.oldval),
1025                           oldlenp, (void __user *)A(tmp.newval), tmp.newlen);
1026         unlock_kernel();
1027         if (oldlenp) {
1028                 if (!error) {
1029                         if (get_user(oldlen, (size_t __user *)addr) ||
1030                             put_user(oldlen, (u32 __user *)A(tmp.oldlenp)))
1031                                 error = -EFAULT;
1032                 }
1033                 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
1034         }
1035         return error;
1036 }
1037
1038 #endif /* CONFIG_SYSCTL */
1039
1040 asmlinkage long sys32_newuname(struct new_utsname __user * name)
1041 {
1042         int ret = 0;
1043
1044         down_read(&uts_sem);
1045         if (copy_to_user(name, vx_new_utsname(), sizeof *name))
1046                 ret = -EFAULT;
1047         up_read(&uts_sem);
1048
1049         if (current->personality == PER_LINUX32 && !ret)
1050                 if (copy_to_user(name->machine, "mips\0\0\0", 8))
1051                         ret = -EFAULT;
1052
1053         return ret;
1054 }
1055
1056 asmlinkage int sys32_personality(unsigned long personality)
1057 {
1058         int ret;
1059         if (current->personality == PER_LINUX32 && personality == PER_LINUX)
1060                 personality = PER_LINUX32;
1061         ret = sys_personality(personality);
1062         if (ret == PER_LINUX32)
1063                 ret = PER_LINUX;
1064         return ret;
1065 }
1066
1067 /* ustat compatibility */
1068 struct ustat32 {
1069         compat_daddr_t  f_tfree;
1070         compat_ino_t    f_tinode;
1071         char            f_fname[6];
1072         char            f_fpack[6];
1073 };
1074
1075 extern asmlinkage long sys_ustat(dev_t dev, struct ustat __user * ubuf);
1076
1077 asmlinkage int sys32_ustat(dev_t dev, struct ustat32 __user * ubuf32)
1078 {
1079         int err;
1080         struct ustat tmp;
1081         struct ustat32 tmp32;
1082         mm_segment_t old_fs = get_fs();
1083
1084         set_fs(KERNEL_DS);
1085         err = sys_ustat(dev, (struct ustat __user *)&tmp);
1086         set_fs (old_fs);
1087
1088         if (err)
1089                 goto out;
1090
1091         memset(&tmp32,0,sizeof(struct ustat32));
1092         tmp32.f_tfree = tmp.f_tfree;
1093         tmp32.f_tinode = tmp.f_tinode;
1094
1095         err = copy_to_user(ubuf32,&tmp32,sizeof(struct ustat32)) ? -EFAULT : 0;
1096
1097 out:
1098         return err;
1099 }
1100
1101 asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset,
1102         s32 count)
1103 {
1104         mm_segment_t old_fs = get_fs();
1105         int ret;
1106         off_t of;
1107
1108         if (offset && get_user(of, offset))
1109                 return -EFAULT;
1110
1111         set_fs(KERNEL_DS);
1112         ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, count);
1113         set_fs(old_fs);
1114
1115         if (offset && put_user(of, offset))
1116                 return -EFAULT;
1117
1118         return ret;
1119 }
1120
1121 asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3,
1122                                    size_t count)
1123 {
1124         return sys_readahead(fd, merge_64(a2, a3), count);
1125 }
1126
1127 asmlinkage long sys32_sync_file_range(int fd, int __pad,
1128         unsigned long a2, unsigned long a3,
1129         unsigned long a4, unsigned long a5,
1130         int flags)
1131 {
1132         return sys_sync_file_range(fd,
1133                         merge_64(a2, a3), merge_64(a4, a5),
1134                         flags);
1135 }
1136
1137 /* Argument list sizes for sys_socketcall */
1138 #define AL(x) ((x) * sizeof(unsigned int))
1139 static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
1140                                 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
1141                                 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
1142 #undef AL
1143
1144 /*
1145  *      System call vectors.
1146  *
1147  *      Argument checking cleaned up. Saved 20% in size.
1148  *  This function doesn't need to set the kernel lock because
1149  *  it is set by the callees.
1150  */
1151
1152 asmlinkage long sys32_socketcall(int call, unsigned int __user *args32)
1153 {
1154         unsigned int a[6];
1155         unsigned int a0,a1;
1156         int err;
1157
1158         extern asmlinkage long sys_socket(int family, int type, int protocol);
1159         extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
1160         extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen);
1161         extern asmlinkage long sys_listen(int fd, int backlog);
1162         extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen);
1163         extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
1164         extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len);
1165         extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec);
1166         extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags);
1167         extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,
1168                                           struct sockaddr __user *addr, int addr_len);
1169         extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags);
1170         extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags,
1171                                             struct sockaddr __user *addr, int __user *addr_len);
1172         extern asmlinkage long sys_shutdown(int fd, int how);
1173         extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen);
1174         extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen);
1175         extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
1176         extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags);
1177
1178
1179         if(call<1||call>SYS_RECVMSG)
1180                 return -EINVAL;
1181
1182         /* copy_from_user should be SMP safe. */
1183         if (copy_from_user(a, args32, socketcall_nargs[call]))
1184                 return -EFAULT;
1185
1186         a0=a[0];
1187         a1=a[1];
1188
1189         switch(call)
1190         {
1191                 case SYS_SOCKET:
1192                         err = sys_socket(a0,a1,a[2]);
1193                         break;
1194                 case SYS_BIND:
1195                         err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]);
1196                         break;
1197                 case SYS_CONNECT:
1198                         err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]);
1199                         break;
1200                 case SYS_LISTEN:
1201                         err = sys_listen(a0,a1);
1202                         break;
1203                 case SYS_ACCEPT:
1204                         err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
1205                         break;
1206                 case SYS_GETSOCKNAME:
1207                         err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
1208                         break;
1209                 case SYS_GETPEERNAME:
1210                         err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2]));
1211                         break;
1212                 case SYS_SOCKETPAIR:
1213                         err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3]));
1214                         break;
1215                 case SYS_SEND:
1216                         err = sys_send(a0, (void __user *)A(a1), a[2], a[3]);
1217                         break;
1218                 case SYS_SENDTO:
1219                         err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3],
1220                                          (struct sockaddr __user *)A(a[4]), a[5]);
1221                         break;
1222                 case SYS_RECV:
1223                         err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]);
1224                         break;
1225                 case SYS_RECVFROM:
1226                         err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3],
1227                                            (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5]));
1228                         break;
1229                 case SYS_SHUTDOWN:
1230                         err = sys_shutdown(a0,a1);
1231                         break;
1232                 case SYS_SETSOCKOPT:
1233                         err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]);
1234                         break;
1235                 case SYS_GETSOCKOPT:
1236                         err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4]));
1237                         break;
1238                 case SYS_SENDMSG:
1239                         err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]);
1240                         break;
1241                 case SYS_RECVMSG:
1242                         err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]);
1243                         break;
1244                 default:
1245                         err = -EINVAL;
1246                         break;
1247         }
1248         return err;
1249 }
1250
1251 struct sigevent32 {
1252         u32 sigev_value;
1253         u32 sigev_signo;
1254         u32 sigev_notify;
1255         u32 payload[(64 / 4) - 3];
1256 };
1257
1258 extern asmlinkage long
1259 sys_timer_create(clockid_t which_clock,
1260                  struct sigevent __user *timer_event_spec,
1261                  timer_t __user * created_timer_id);
1262
1263 long
1264 sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id)
1265 {
1266         struct sigevent __user *p = NULL;
1267         if (se32) {
1268                 struct sigevent se;
1269                 p = compat_alloc_user_space(sizeof(struct sigevent));
1270                 memset(&se, 0, sizeof(struct sigevent));
1271                 if (get_user(se.sigev_value.sival_int,  &se32->sigev_value) ||
1272                     __get_user(se.sigev_signo, &se32->sigev_signo) ||
1273                     __get_user(se.sigev_notify, &se32->sigev_notify) ||
1274                     __copy_from_user(&se._sigev_un._pad, &se32->payload,
1275                                      sizeof(se32->payload)) ||
1276                     copy_to_user(p, &se, sizeof(se)))
1277                         return -EFAULT;
1278         }
1279         return sys_timer_create(clock, p, timer_id);
1280 }
1281
1282 save_static_function(sys32_clone);
1283 __attribute_used__ noinline static int
1284 _sys32_clone(nabi_no_regargs struct pt_regs regs)
1285 {
1286         unsigned long clone_flags;
1287         unsigned long newsp;
1288         int __user *parent_tidptr, *child_tidptr;
1289
1290         clone_flags = regs.regs[4];
1291         newsp = regs.regs[5];
1292         if (!newsp)
1293                 newsp = regs.regs[29];
1294         parent_tidptr = (int __user *) regs.regs[6];
1295
1296         /* Use __dummy4 instead of getting it off the stack, so that
1297            syscall() works.  */
1298         child_tidptr = (int __user *) __dummy4;
1299         return do_fork(clone_flags, newsp, &regs, 0,
1300                        parent_tidptr, child_tidptr);
1301 }
1302
1303 extern asmlinkage void sys_set_thread_area(u32 addr);
1304 asmlinkage void sys32_set_thread_area(u32 addr)
1305 {
1306         sys_set_thread_area(AA(addr));
1307 }