VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / sparc64 / kernel / sys_sparc32.c
1 /* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $
2  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
3  *
4  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6  *
7  * These routines maintain argument size conversion between 32bit and 64bit
8  * environment.
9  */
10
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 #include <linux/fs.h> 
15 #include <linux/mm.h> 
16 #include <linux/file.h> 
17 #include <linux/signal.h>
18 #include <linux/resource.h>
19 #include <linux/times.h>
20 #include <linux/utsname.h>
21 #include <linux/timex.h>
22 #include <linux/smp.h>
23 #include <linux/smp_lock.h>
24 #include <linux/sem.h>
25 #include <linux/msg.h>
26 #include <linux/shm.h>
27 #include <linux/slab.h>
28 #include <linux/uio.h>
29 #include <linux/nfs_fs.h>
30 #include <linux/quota.h>
31 #include <linux/module.h>
32 #include <linux/sunrpc/svc.h>
33 #include <linux/nfsd/nfsd.h>
34 #include <linux/nfsd/cache.h>
35 #include <linux/nfsd/xdr.h>
36 #include <linux/nfsd/syscall.h>
37 #include <linux/poll.h>
38 #include <linux/personality.h>
39 #include <linux/stat.h>
40 #include <linux/filter.h>
41 #include <linux/highmem.h>
42 #include <linux/highuid.h>
43 #include <linux/mman.h>
44 #include <linux/ipv6.h>
45 #include <linux/in.h>
46 #include <linux/icmpv6.h>
47 #include <linux/syscalls.h>
48 #include <linux/sysctl.h>
49 #include <linux/binfmts.h>
50 #include <linux/dnotify.h>
51 #include <linux/security.h>
52 #include <linux/compat.h>
53 #include <linux/vfs.h>
54 #include <linux/netfilter_ipv4/ip_tables.h>
55 #include <linux/ptrace.h>
56 #include <linux/highuid.h>
57
58 #include <asm/types.h>
59 #include <asm/ipc.h>
60 #include <asm/uaccess.h>
61 #include <asm/fpumacro.h>
62 #include <asm/semaphore.h>
63 #include <asm/mmu_context.h>
64
65 asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group)
66 {
67         return sys_chown(filename, low2highuid(user), low2highgid(group));
68 }
69
70 asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group)
71 {
72         return sys_lchown(filename, low2highuid(user), low2highgid(group));
73 }
74
75 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
76 {
77         return sys_fchown(fd, low2highuid(user), low2highgid(group));
78 }
79
80 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
81 {
82         return sys_setregid(low2highgid(rgid), low2highgid(egid));
83 }
84
85 asmlinkage long sys32_setgid16(u16 gid)
86 {
87         return sys_setgid((gid_t)gid);
88 }
89
90 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
91 {
92         return sys_setreuid(low2highuid(ruid), low2highuid(euid));
93 }
94
95 asmlinkage long sys32_setuid16(u16 uid)
96 {
97         return sys_setuid((uid_t)uid);
98 }
99
100 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
101 {
102         return sys_setresuid(low2highuid(ruid), low2highuid(euid),
103                 low2highuid(suid));
104 }
105
106 asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid)
107 {
108         int retval;
109
110         if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
111             !(retval = put_user(high2lowuid(current->euid), euid)))
112                 retval = put_user(high2lowuid(current->suid), suid);
113
114         return retval;
115 }
116
117 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
118 {
119         return sys_setresgid(low2highgid(rgid), low2highgid(egid),
120                 low2highgid(sgid));
121 }
122
123 asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid)
124 {
125         int retval;
126
127         if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
128             !(retval = put_user(high2lowgid(current->egid), egid)))
129                 retval = put_user(high2lowgid(current->sgid), sgid);
130
131         return retval;
132 }
133
134 asmlinkage long sys32_setfsuid16(u16 uid)
135 {
136         return sys_setfsuid((uid_t)uid);
137 }
138
139 asmlinkage long sys32_setfsgid16(u16 gid)
140 {
141         return sys_setfsgid((gid_t)gid);
142 }
143
144 static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)
145 {
146         int i;
147         u16 group;
148
149         for (i = 0; i < group_info->ngroups; i++) {
150                 group = (u16)GROUP_AT(group_info, i);
151                 if (put_user(group, grouplist+i))
152                         return -EFAULT;
153         }
154
155         return 0;
156 }
157
158 static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)
159 {
160         int i;
161         u16 group;
162
163         for (i = 0; i < group_info->ngroups; i++) {
164                 if (get_user(group, grouplist+i))
165                         return  -EFAULT;
166                 GROUP_AT(group_info, i) = (gid_t)group;
167         }
168
169         return 0;
170 }
171
172 asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
173 {
174         int i;
175
176         if (gidsetsize < 0)
177                 return -EINVAL;
178
179         get_group_info(current->group_info);
180         i = current->group_info->ngroups;
181         if (gidsetsize) {
182                 if (i > gidsetsize) {
183                         i = -EINVAL;
184                         goto out;
185                 }
186                 if (groups16_to_user(grouplist, current->group_info)) {
187                         i = -EFAULT;
188                         goto out;
189                 }
190         }
191 out:
192         put_group_info(current->group_info);
193         return i;
194 }
195
196 asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)
197 {
198         struct group_info *group_info;
199         int retval;
200
201         if (!capable(CAP_SETGID))
202                 return -EPERM;
203         if ((unsigned)gidsetsize > NGROUPS_MAX)
204                 return -EINVAL;
205
206         group_info = groups_alloc(gidsetsize);
207         if (!group_info)
208                 return -ENOMEM;
209         retval = groups16_from_user(group_info, grouplist);
210         if (retval) {
211                 put_group_info(group_info);
212                 return retval;
213         }
214
215         retval = set_current_groups(group_info);
216         put_group_info(group_info);
217
218         return retval;
219 }
220
221 asmlinkage long sys32_getuid16(void)
222 {
223         return high2lowuid(current->uid);
224 }
225
226 asmlinkage long sys32_geteuid16(void)
227 {
228         return high2lowuid(current->euid);
229 }
230
231 asmlinkage long sys32_getgid16(void)
232 {
233         return high2lowgid(current->gid);
234 }
235
236 asmlinkage long sys32_getegid16(void)
237 {
238         return high2lowgid(current->egid);
239 }
240
241 /* 32-bit timeval and related flotsam.  */
242
243 static long get_tv32(struct timeval *o, struct compat_timeval __user *i)
244 {
245         return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
246                 (__get_user(o->tv_sec, &i->tv_sec) |
247                  __get_user(o->tv_usec, &i->tv_usec)));
248 }
249
250 static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
251 {
252         return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
253                 (__put_user(i->tv_sec, &o->tv_sec) |
254                  __put_user(i->tv_usec, &o->tv_usec)));
255 }
256
257 struct msgbuf32 { s32 mtype; char mtext[1]; };
258
259 struct ipc_perm32 {
260         key_t             key;
261         compat_uid_t  uid;
262         compat_gid_t  gid;
263         compat_uid_t  cuid;
264         compat_gid_t  cgid;
265         compat_mode_t mode;
266         unsigned short  seq;
267 };
268
269 struct semid_ds32 {
270         struct ipc_perm32 sem_perm;               /* permissions .. see ipc.h */
271         compat_time_t   sem_otime;              /* last semop time */
272         compat_time_t   sem_ctime;              /* last change time */
273         u32 sem_base;              /* ptr to first semaphore in array */
274         u32 sem_pending;          /* pending operations to be processed */
275         u32 sem_pending_last;    /* last pending operation */
276         u32 undo;                  /* undo requests on this array */
277         unsigned short  sem_nsems;              /* no. of semaphores in array */
278 };
279
280 struct semid64_ds32 {
281         struct ipc64_perm sem_perm;               /* this structure is the same on sparc32 and sparc64 */
282         unsigned int      __pad1;
283         compat_time_t   sem_otime;
284         unsigned int      __pad2;
285         compat_time_t   sem_ctime;
286         u32 sem_nsems;
287         u32 __unused1;
288         u32 __unused2;
289 };
290
291 struct msqid_ds32
292 {
293         struct ipc_perm32 msg_perm;
294         u32 msg_first;
295         u32 msg_last;
296         compat_time_t   msg_stime;
297         compat_time_t   msg_rtime;
298         compat_time_t   msg_ctime;
299         u32 wwait;
300         u32 rwait;
301         unsigned short msg_cbytes;
302         unsigned short msg_qnum;  
303         unsigned short msg_qbytes;
304         compat_ipc_pid_t msg_lspid;
305         compat_ipc_pid_t msg_lrpid;
306 };
307
308 struct msqid64_ds32 {
309         struct ipc64_perm msg_perm;
310         unsigned int   __pad1;
311         compat_time_t   msg_stime;
312         unsigned int   __pad2;
313         compat_time_t   msg_rtime;
314         unsigned int   __pad3;
315         compat_time_t   msg_ctime;
316         unsigned int  msg_cbytes;
317         unsigned int  msg_qnum;
318         unsigned int  msg_qbytes;
319         compat_pid_t msg_lspid;
320         compat_pid_t msg_lrpid;
321         unsigned int  __unused1;
322         unsigned int  __unused2;
323 };
324
325
326 struct shmid_ds32 {
327         struct ipc_perm32       shm_perm;
328         int                     shm_segsz;
329         compat_time_t         shm_atime;
330         compat_time_t         shm_dtime;
331         compat_time_t         shm_ctime;
332         compat_ipc_pid_t    shm_cpid; 
333         compat_ipc_pid_t    shm_lpid; 
334         unsigned short          shm_nattch;
335 };
336
337 struct shmid64_ds32 {
338         struct ipc64_perm       shm_perm;
339         unsigned int            __pad1;
340         compat_time_t   shm_atime;
341         unsigned int            __pad2;
342         compat_time_t   shm_dtime;
343         unsigned int            __pad3;
344         compat_time_t   shm_ctime;
345         compat_size_t   shm_segsz;
346         compat_pid_t    shm_cpid;
347         compat_pid_t    shm_lpid;
348         unsigned int            shm_nattch;
349         unsigned int            __unused1;
350         unsigned int            __unused2;
351 };
352
353                                                         
354 /*
355  * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
356  *
357  * This is really horribly ugly.
358  */
359 #define IPCOP_MASK(__x) (1UL << ((__x)&~IPC_64))
360 static int do_sys32_semctl(int first, int second, int third,
361                            compat_uptr_t __user *uptr)
362 {
363         union semun fourth;
364         compat_uptr_t pad;
365         int err = -EINVAL;
366
367         if (!uptr)
368                 goto out;
369         err = -EFAULT;
370         if (get_user(pad, uptr))
371                 goto out;
372         if ((third & ~IPC_64) == SETVAL)
373                 fourth.val = (int)pad;
374         else
375                 fourth.__pad = compat_ptr(pad);
376         if (IPCOP_MASK (third) &
377             (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
378              IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
379              IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
380                 err = sys_semctl (first, second, third, fourth);
381         } else if (third & IPC_64) {
382                 struct semid64_ds s;
383                 struct semid64_ds32 __user *usp = compat_ptr(pad);
384                 mm_segment_t old_fs;
385                 int need_back_translation;
386
387                 if (third == (IPC_SET|IPC_64)) {
388                         err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
389                         err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
390                         err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
391                         if (err)
392                                 goto out;
393                         fourth.__pad = (void __user *) &s;
394                 }
395                 need_back_translation =
396                         (IPCOP_MASK (third) &
397                          (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
398                 if (need_back_translation)
399                         fourth.__pad = (void __user *) &s;
400                 old_fs = get_fs ();
401                 set_fs (KERNEL_DS);
402                 err = sys_semctl (first, second, third, fourth);
403                 set_fs (old_fs);
404                 if (need_back_translation) {
405                         int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
406                         err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
407                         if (err2) err = -EFAULT;
408                 }
409         } else {
410                 struct semid_ds s;
411                 struct semid_ds32 __user *usp = compat_ptr(pad);
412                 mm_segment_t old_fs;
413                 int need_back_translation;
414
415                 if (third == IPC_SET) {
416                         err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
417                         err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
418                         err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
419                         if (err)
420                                 goto out;
421                         fourth.__pad = (void __user *) &s;
422                 }
423                 need_back_translation =
424                         (IPCOP_MASK (third) &
425                          (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
426                 if (need_back_translation)
427                         fourth.__pad = (void __user *) &s;
428                 old_fs = get_fs ();
429                 set_fs (KERNEL_DS);
430                 err = sys_semctl (first, second, third, fourth);
431                 set_fs (old_fs);
432                 if (need_back_translation) {
433                         int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
434                         err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
435                         err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
436                         err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
437                         err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
438                         err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
439                         err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
440                         err2 |= __put_user (s.sem_otime, &usp->sem_otime);
441                         err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
442                         err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
443                         if (err2) err = -EFAULT;
444                 }
445         }
446 out:
447         return err;
448 }
449
450 static int do_sys32_msgsnd(int first, int second, int third,
451                            void __user *uptr)
452 {
453         struct msgbuf32 __user *up = uptr;
454         struct msgbuf *p;
455         mm_segment_t old_fs;
456         int err;
457
458         p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);
459         if (!p)
460                 return -ENOMEM;
461         err = -EFAULT;
462         if (get_user (p->mtype, &up->mtype) ||
463             __copy_from_user (p->mtext, &up->mtext, second))
464                 goto out;
465         old_fs = get_fs ();
466         set_fs (KERNEL_DS);
467         err = sys_msgsnd (first, (struct msgbuf __user *) p,
468                           second, third);
469         set_fs (old_fs);
470 out:
471         kfree (p);
472         return err;
473 }
474
475 static int do_sys32_msgrcv(int first, int second, int msgtyp, int third,
476                            int version, void __user *uptr)
477 {
478         struct msgbuf32 __user *up;
479         struct msgbuf *p;
480         mm_segment_t old_fs;
481         int err;
482
483         if (!version) {
484                 struct ipc_kludge __user *uipck = uptr;
485                 struct ipc_kludge ipck;
486
487                 err = -EINVAL;
488                 if (!uptr)
489                         goto out;
490                 err = -EFAULT;
491                 if (copy_from_user (&ipck, uipck,
492                                     sizeof (struct ipc_kludge)))
493                         goto out;
494                 uptr = compat_ptr(ipck.msgp);
495                 msgtyp = ipck.msgtyp;
496         }
497         err = -ENOMEM;
498         p = kmalloc(second + sizeof (struct msgbuf), GFP_USER);
499         if (!p)
500                 goto out;
501         old_fs = get_fs ();
502         set_fs (KERNEL_DS);
503         err = sys_msgrcv (first, (struct msgbuf __user *) p, second,
504                           msgtyp, third);
505         set_fs (old_fs);
506         if (err < 0)
507                 goto free_then_out;
508         up = uptr;
509         if (put_user (p->mtype, &up->mtype) ||
510             __copy_to_user (&up->mtext, p->mtext, err))
511                 err = -EFAULT;
512 free_then_out:
513         kfree (p);
514 out:
515         return err;
516 }
517
518 static int do_sys32_msgctl(int first, int second, void __user *uptr)
519 {
520         int err;
521
522         if (IPCOP_MASK (second) &
523             (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
524              IPCOP_MASK (IPC_RMID))) {
525                 err = sys_msgctl (first, second, uptr);
526         } else if (second & IPC_64) {
527                 struct msqid64_ds m;
528                 struct msqid64_ds32 __user *up = uptr;
529                 mm_segment_t old_fs;
530
531                 if (second == (IPC_SET|IPC_64)) {
532                         err = get_user (m.msg_perm.uid,
533                                         &up->msg_perm.uid);
534                         err |= __get_user (m.msg_perm.gid,
535                                            &up->msg_perm.gid);
536                         err |= __get_user (m.msg_perm.mode,
537                                            &up->msg_perm.mode);
538                         err |= __get_user (m.msg_qbytes,
539                                            &up->msg_qbytes);
540                         if (err)
541                                 goto out;
542                 }
543                 old_fs = get_fs ();
544                 set_fs (KERNEL_DS);
545                 err = sys_msgctl(first, second,
546                                  (struct msqid_ds __user *)&m);
547                 set_fs (old_fs);
548                 if (IPCOP_MASK (second) &
549                     (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
550                         int err2 = copy_to_user(&up->msg_perm,
551                                                 &m.msg_perm,
552                                                 (sizeof(struct ipc64_perm) + 3*sizeof(time_t)));
553                         err2 |= __put_user (m.msg_cbytes,
554                                             &up->msg_cbytes);
555                         err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
556                         err2 |= __put_user (m.msg_qbytes,
557                                             &up->msg_qbytes);
558                         err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
559                         err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
560                         if (err2)
561                                 err = -EFAULT;
562                 }
563         } else {
564                 struct msqid_ds m;
565                 struct msqid_ds32 __user *up = uptr;
566                 mm_segment_t old_fs;
567
568                 if (second == IPC_SET) {
569                         err = get_user(m.msg_perm.uid,
570                                        &up->msg_perm.uid);
571                         err |= __get_user(m.msg_perm.gid,
572                                           &up->msg_perm.gid);
573                         err |= __get_user(m.msg_perm.mode,
574                                           &up->msg_perm.mode);
575                         err |= __get_user(m.msg_qbytes,
576                                           &up->msg_qbytes);
577                         if (err)
578                                 goto out;
579                 }
580                 old_fs = get_fs ();
581                 set_fs (KERNEL_DS);
582                 err = sys_msgctl(first, second,
583                                  (struct msqid_ds __user *) &m);
584                 set_fs (old_fs);
585                 if (IPCOP_MASK (second) &
586                     (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
587                         int err2 = put_user(m.msg_perm.key,
588                                             &up->msg_perm.key);
589                         err2 |= __put_user(high2lowuid(m.msg_perm.uid),
590                                            &up->msg_perm.uid);
591                         err2 |= __put_user(high2lowgid(m.msg_perm.gid),
592                                            &up->msg_perm.gid);
593                         err2 |= __put_user(high2lowuid(m.msg_perm.cuid),
594                                            &up->msg_perm.cuid);
595                         err2 |= __put_user(high2lowgid(m.msg_perm.cgid),
596                                            &up->msg_perm.cgid);
597                         err2 |= __put_user(m.msg_perm.mode,
598                                            &up->msg_perm.mode);
599                         err2 |= __put_user(m.msg_perm.seq,
600                                            &up->msg_perm.seq);
601                         err2 |= __put_user(m.msg_stime, &up->msg_stime);
602                         err2 |= __put_user(m.msg_rtime, &up->msg_rtime);
603                         err2 |= __put_user(m.msg_ctime, &up->msg_ctime);
604                         err2 |= __put_user(m.msg_cbytes,
605                                            &up->msg_cbytes);
606                         err2 |= __put_user(m.msg_qnum, &up->msg_qnum);
607                         err2 |= __put_user(m.msg_qbytes,
608                                            &up->msg_qbytes);
609                         err2 |= __put_user(m.msg_lspid, &up->msg_lspid);
610                         err2 |= __put_user(m.msg_lrpid, &up->msg_lrpid);
611                         if (err2)
612                                 err = -EFAULT;
613                 }
614         }
615
616 out:
617         return err;
618 }
619
620 static int do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
621 {
622         unsigned long raddr;
623         u32 __user *uaddr = compat_ptr((compat_uptr_t)third);
624         int err = -EINVAL;
625
626         if (version == 1)
627                 goto out;
628         err = do_shmat (first, uptr, second, &raddr);
629         if (err)
630                 goto out;
631         err = put_user (raddr, uaddr);
632 out:
633         return err;
634 }
635
636 static int do_sys32_shmctl(int first, int second, void __user *uptr)
637 {
638         int err;
639
640         if (IPCOP_MASK (second) &
641             (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) |
642              IPCOP_MASK (SHM_UNLOCK) | IPCOP_MASK (IPC_RMID))) {
643                 if (second == (IPC_INFO|IPC_64)) {
644                         /* So that we don't have to translate it */
645                         second = IPC_INFO;
646                 }
647                 err = sys_shmctl(first, second, uptr);
648         } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
649                 struct shmid64_ds s;
650                 struct shmid64_ds32 __user *up = uptr;
651                 mm_segment_t old_fs;
652
653                 if (second == (IPC_SET|IPC_64)) {
654                         err = get_user(s.shm_perm.uid,
655                                        &up->shm_perm.uid);
656                         err |= __get_user(s.shm_perm.gid,
657                                           &up->shm_perm.gid);
658                         err |= __get_user(s.shm_perm.mode,
659                                           &up->shm_perm.mode);
660                         if (err)
661                                 goto out;
662                 }
663                 old_fs = get_fs();
664                 set_fs(KERNEL_DS);
665                 err = sys_shmctl(first, second,
666                                  (struct shmid_ds __user *)&s);
667                 set_fs(old_fs);
668                 if (err < 0)
669                         goto out;
670
671                 /* Mask it even in this case so it becomes a CSE. */
672                 if (IPCOP_MASK (second) &
673                     (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
674                         int err2 = copy_to_user(&up->shm_perm,
675                                                 &s.shm_perm,
676                                                 sizeof(struct ipc64_perm) + 3*sizeof(time_t));
677                         err2 |= __put_user(s.shm_segsz, &up->shm_segsz);
678                         err2 |= __put_user(s.shm_nattch,&up->shm_nattch);
679                         err2 |= __put_user(s.shm_cpid, &up->shm_cpid);
680                         err2 |= __put_user(s.shm_lpid, &up->shm_lpid);
681                         if (err2)
682                                 err = -EFAULT;
683                 }
684         } else {
685                 struct shmid_ds s;
686                 struct shmid_ds32 __user *up = uptr;
687                 mm_segment_t old_fs;
688
689                 second &= ~IPC_64;
690                 if (second == IPC_SET) {
691                         err = get_user(s.shm_perm.uid,
692                                        &up->shm_perm.uid);
693                         err |= __get_user(s.shm_perm.gid,
694                                           &up->shm_perm.gid);
695                         err |= __get_user(s.shm_perm.mode,
696                                           &up->shm_perm.mode);
697                         if (err)
698                                 goto out;
699                 }
700                 old_fs = get_fs();
701                 set_fs(KERNEL_DS);
702                 err = sys_shmctl(first, second,
703                                  (struct shmid_ds __user *) &s);
704                 set_fs(old_fs);
705                 if (err < 0)
706                         goto out;
707
708                 /* Mask it even in this case so it becomes a CSE. */
709                 if (second == SHM_INFO) {
710                         struct shm_info32 {
711                                 int used_ids;
712                                 u32 shm_tot, shm_rss, shm_swp;
713                                 u32 swap_attempts, swap_successes;
714                         };
715                         struct shm_info32 __user *uip = uptr;
716                         struct shm_info *kp = (struct shm_info *) &s;
717                         int err2 = put_user(kp->used_ids,
718                                             &uip->used_ids);
719                         err2 |= __put_user(kp->shm_tot, &uip->shm_tot);
720                         err2 |= __put_user(kp->shm_rss, &uip->shm_rss);
721                         err2 |= __put_user(kp->shm_swp, &uip->shm_swp);
722                         err2 |= __put_user(kp->swap_attempts,
723                                            &uip->swap_attempts);
724                         err2 |= __put_user(kp->swap_successes,
725                                            &uip->swap_successes);
726                         if (err2)
727                                 err = -EFAULT;
728                 } else if (IPCOP_MASK (second) &
729                            (IPCOP_MASK (SHM_STAT) |
730                             IPCOP_MASK (IPC_STAT))) {
731                         int err2;
732
733                         err2  = put_user(s.shm_perm.key,
734                                          &up->shm_perm.key);
735                         err2 |= __put_user(high2lowuid(s.shm_perm.uid),
736                                            &up->shm_perm.uid);
737                         err2 |= __put_user(high2lowuid(s.shm_perm.gid),
738                                            &up->shm_perm.gid);
739                         err2 |= __put_user(high2lowuid(s.shm_perm.cuid),
740                                            &up->shm_perm.cuid);
741                         err2 |= __put_user(high2lowuid(s.shm_perm.cgid),
742                                            &up->shm_perm.cgid);
743                         err2 |= __put_user(s.shm_perm.mode,
744                                            &up->shm_perm.mode);
745                         err2 |= __put_user(s.shm_perm.seq,
746                                            &up->shm_perm.seq);
747                         err2 |= __put_user(s.shm_atime, &up->shm_atime);
748                         err2 |= __put_user(s.shm_dtime, &up->shm_dtime);
749                         err2 |= __put_user(s.shm_ctime, &up->shm_ctime);
750                         err2 |= __put_user(s.shm_segsz, &up->shm_segsz);
751                         err2 |= __put_user(s.shm_nattch,&up->shm_nattch);
752                         err2 |= __put_user(s.shm_cpid, &up->shm_cpid);
753                         err2 |= __put_user(s.shm_lpid, &up->shm_lpid);
754                         if (err2)
755                                 err = -EFAULT;
756                 }
757         }
758 out:
759         return err;
760 }
761
762 static int sys32_semtimedop(int semid, struct sembuf __user *tsems,
763                 int nsems,
764                 const struct compat_timespec __user *timeout32)
765 {
766         struct compat_timespec t32;
767         struct timespec __user *t64;
768
769         t64 = compat_alloc_user_space(sizeof(*t64));
770         if (copy_from_user(&t32, timeout32, sizeof(t32)))
771                 return -EFAULT;
772
773         if (put_user(t32.tv_sec, &t64->tv_sec) ||
774             put_user(t32.tv_nsec, &t64->tv_nsec))
775                 return -EFAULT;
776
777         return sys_semtimedop(semid, tsems, nsems, t64);
778 }
779
780 asmlinkage long compat_sys_ipc(u32 call, int first, int second, int third, compat_uptr_t __ptr, u32 fifth)
781 {
782         int version, err;
783         void __user *ptr = compat_ptr(__ptr);
784
785         version = call >> 16; /* hack for backward compatibility */
786         call &= 0xffff;
787
788         if (call <= SEMCTL) {
789                 switch (call) {
790                 case SEMOP:
791                         /* struct sembuf is the same on 32 and 64 :)) */
792                         err = sys_semtimedop (first, ptr, second, NULL);
793                         goto out;
794                 case SEMTIMEDOP:
795                         err = sys32_semtimedop(first, ptr, second,
796                                                compat_ptr(fifth));
797                 case SEMGET:
798                         err = sys_semget(first, second, third);
799                         goto out;
800                 case SEMCTL:
801                         err = do_sys32_semctl(first, second, third, ptr);
802                         goto out;
803                 default:
804                         err = -ENOSYS;
805                         goto out;
806                 };
807         }
808         if (call <= MSGCTL) {
809                 switch (call) {
810                 case MSGSND:
811                         err = do_sys32_msgsnd(first, second, third, ptr);
812                         goto out;
813                 case MSGRCV:
814                         err = do_sys32_msgrcv(first, second, fifth,
815                                               third, version, ptr);
816                         goto out;
817                 case MSGGET:
818                         err = sys_msgget((key_t) first, second);
819                         goto out;
820                 case MSGCTL:
821                         err = do_sys32_msgctl(first, second, ptr);
822                         goto out;
823                 default:
824                         err = -ENOSYS;
825                         goto out;
826                 };
827         }
828         if (call <= SHMCTL) {
829                 switch (call) {
830                 case SHMAT:
831                         err = do_sys32_shmat(first, second, third,
832                                              version, ptr);
833                         goto out;
834                 case SHMDT: 
835                         err = sys_shmdt(ptr);
836                         goto out;
837                 case SHMGET:
838                         err = sys_shmget(first, second, third);
839                         goto out;
840                 case SHMCTL:
841                         err = do_sys32_shmctl(first, second, ptr);
842                         goto out;
843                 default:
844                         err = -ENOSYS;
845                         goto out;
846                 };
847         }
848         err = -ENOSYS;
849
850 out:
851         return err;
852 }
853
854 asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low)
855 {
856         if ((int)high < 0)
857                 return -EINVAL;
858         else
859                 return sys_truncate(path, (high << 32) | low);
860 }
861
862 asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
863 {
864         if ((int)high < 0)
865                 return -EINVAL;
866         else
867                 return sys_ftruncate(fd, (high << 32) | low);
868 }
869
870 int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
871 {
872         int err;
873
874         if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
875             !old_valid_dev(stat->rdev))
876                 return -EOVERFLOW;
877
878         err  = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
879         err |= put_user(stat->ino, &statbuf->st_ino);
880         err |= put_user(stat->mode, &statbuf->st_mode);
881         err |= put_user(stat->nlink, &statbuf->st_nlink);
882         err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
883         err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
884         err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
885         err |= put_user(stat->size, &statbuf->st_size);
886         err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
887         err |= put_user(0, &statbuf->__unused1);
888         err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
889         err |= put_user(0, &statbuf->__unused2);
890         err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
891         err |= put_user(0, &statbuf->__unused3);
892         err |= put_user(stat->blksize, &statbuf->st_blksize);
893         err |= put_user(stat->blocks, &statbuf->st_blocks);
894         err |= put_user(0, &statbuf->__unused4[0]);
895         err |= put_user(0, &statbuf->__unused4[1]);
896
897         return err;
898 }
899
900 asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
901 {
902         return sys_sysfs(option, arg1, arg2);
903 }
904
905 struct sysinfo32 {
906         s32 uptime;
907         u32 loads[3];
908         u32 totalram;
909         u32 freeram;
910         u32 sharedram;
911         u32 bufferram;
912         u32 totalswap;
913         u32 freeswap;
914         unsigned short procs;
915         unsigned short pad;
916         u32 totalhigh;
917         u32 freehigh;
918         u32 mem_unit;
919         char _f[20-2*sizeof(int)-sizeof(int)];
920 };
921
922 asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
923 {
924         struct sysinfo s;
925         int ret, err;
926         int bitcount = 0;
927         mm_segment_t old_fs = get_fs ();
928         
929         set_fs(KERNEL_DS);
930         ret = sys_sysinfo((struct sysinfo __user *) &s);
931         set_fs(old_fs);
932         /* Check to see if any memory value is too large for 32-bit and
933          * scale down if needed.
934          */
935         if ((s.totalram >> 32) || (s.totalswap >> 32)) {
936                 while (s.mem_unit < PAGE_SIZE) {
937                         s.mem_unit <<= 1;
938                         bitcount++;
939                 }
940                 s.totalram >>= bitcount;
941                 s.freeram >>= bitcount;
942                 s.sharedram >>= bitcount;
943                 s.bufferram >>= bitcount;
944                 s.totalswap >>= bitcount;
945                 s.freeswap >>= bitcount;
946                 s.totalhigh >>= bitcount;
947                 s.freehigh >>= bitcount;
948         }
949
950         err = put_user (s.uptime, &info->uptime);
951         err |= __put_user (s.loads[0], &info->loads[0]);
952         err |= __put_user (s.loads[1], &info->loads[1]);
953         err |= __put_user (s.loads[2], &info->loads[2]);
954         err |= __put_user (s.totalram, &info->totalram);
955         err |= __put_user (s.freeram, &info->freeram);
956         err |= __put_user (s.sharedram, &info->sharedram);
957         err |= __put_user (s.bufferram, &info->bufferram);
958         err |= __put_user (s.totalswap, &info->totalswap);
959         err |= __put_user (s.freeswap, &info->freeswap);
960         err |= __put_user (s.procs, &info->procs);
961         err |= __put_user (s.totalhigh, &info->totalhigh);
962         err |= __put_user (s.freehigh, &info->freehigh);
963         err |= __put_user (s.mem_unit, &info->mem_unit);
964         if (err)
965                 return -EFAULT;
966         return ret;
967 }
968
969 asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval)
970 {
971         struct timespec t;
972         int ret;
973         mm_segment_t old_fs = get_fs ();
974         
975         set_fs (KERNEL_DS);
976         ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
977         set_fs (old_fs);
978         if (put_compat_timespec(&t, interval))
979                 return -EFAULT;
980         return ret;
981 }
982
983 asmlinkage long compat_sys_rt_sigprocmask(int how,
984                                           compat_sigset_t __user *set,
985                                           compat_sigset_t __user *oset,
986                                           compat_size_t sigsetsize)
987 {
988         sigset_t s;
989         compat_sigset_t s32;
990         int ret;
991         mm_segment_t old_fs = get_fs();
992         
993         if (set) {
994                 if (copy_from_user (&s32, set, sizeof(compat_sigset_t)))
995                         return -EFAULT;
996                 switch (_NSIG_WORDS) {
997                 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
998                 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
999                 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1000                 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1001                 }
1002         }
1003         set_fs (KERNEL_DS);
1004         ret = sys_rt_sigprocmask(how,
1005                                  set ? (sigset_t __user *) &s : NULL,
1006                                  oset ? (sigset_t __user *) &s : NULL,
1007                                  sigsetsize);
1008         set_fs (old_fs);
1009         if (ret) return ret;
1010         if (oset) {
1011                 switch (_NSIG_WORDS) {
1012                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1013                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1014                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1015                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1016                 }
1017                 if (copy_to_user (oset, &s32, sizeof(compat_sigset_t)))
1018                         return -EFAULT;
1019         }
1020         return 0;
1021 }
1022
1023 asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
1024                                     compat_size_t sigsetsize)
1025 {
1026         sigset_t s;
1027         compat_sigset_t s32;
1028         int ret;
1029         mm_segment_t old_fs = get_fs();
1030                 
1031         set_fs (KERNEL_DS);
1032         ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize);
1033         set_fs (old_fs);
1034         if (!ret) {
1035                 switch (_NSIG_WORDS) {
1036                 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1037                 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1038                 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1039                 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1040                 }
1041                 if (copy_to_user (set, &s32, sizeof(compat_sigset_t)))
1042                         return -EFAULT;
1043         }
1044         return ret;
1045 }
1046
1047 asmlinkage long sys32_rt_sigtimedwait(compat_sigset_t __user *uthese,
1048                                       siginfo_t32 __user *uinfo,
1049                                       struct compat_timespec __user *uts,
1050                                       compat_size_t sigsetsize)
1051 {
1052         int ret, sig;
1053         sigset_t these;
1054         compat_sigset_t these32;
1055         struct timespec ts;
1056         siginfo_t info;
1057         long timeout = 0;
1058
1059         /* XXX: Don't preclude handling different sized sigset_t's.  */
1060         if (sigsetsize != sizeof(sigset_t))
1061                 return -EINVAL;
1062
1063         if (copy_from_user (&these32, uthese, sizeof(compat_sigset_t)))
1064                 return -EFAULT;
1065
1066         switch (_NSIG_WORDS) {
1067         case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
1068         case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
1069         case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
1070         case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
1071         }
1072                 
1073         /*
1074          * Invert the set of allowed signals to get those we
1075          * want to block.
1076          */
1077         sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
1078         signotset(&these);
1079
1080         if (uts) {
1081                 if (get_compat_timespec(&ts, uts))
1082                         return -EINVAL;
1083                 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
1084                     || ts.tv_sec < 0)
1085                         return -EINVAL;
1086         }
1087
1088         spin_lock_irq(&current->sighand->siglock);
1089         sig = dequeue_signal(current, &these, &info);
1090         if (!sig) {
1091                 timeout = MAX_SCHEDULE_TIMEOUT;
1092                 if (uts)
1093                         timeout = (timespec_to_jiffies(&ts)
1094                                    + (ts.tv_sec || ts.tv_nsec));
1095
1096                 if (timeout) {
1097                         /* None ready -- temporarily unblock those we're
1098                          * interested while we are sleeping in so that we'll
1099                          * be awakened when they arrive.  */
1100                         current->real_blocked = current->blocked;
1101                         sigandsets(&current->blocked, &current->blocked, &these);
1102                         recalc_sigpending();
1103                         spin_unlock_irq(&current->sighand->siglock);
1104
1105                         current->state = TASK_INTERRUPTIBLE;
1106                         timeout = schedule_timeout(timeout);
1107
1108                         spin_lock_irq(&current->sighand->siglock);
1109                         sig = dequeue_signal(current, &these, &info);
1110                         current->blocked = current->real_blocked;
1111                         siginitset(&current->real_blocked, 0);
1112                         recalc_sigpending();
1113                 }
1114         }
1115         spin_unlock_irq(&current->sighand->siglock);
1116
1117         if (sig) {
1118                 ret = sig;
1119                 if (uinfo) {
1120                         if (copy_siginfo_to_user32(uinfo, &info))
1121                                 ret = -EFAULT;
1122                 }
1123         } else {
1124                 ret = -EAGAIN;
1125                 if (timeout)
1126                         ret = -EINTR;
1127         }
1128
1129         return ret;
1130 }
1131
1132 asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
1133                                            siginfo_t32 __user *uinfo)
1134 {
1135         siginfo_t info;
1136         int ret;
1137         mm_segment_t old_fs = get_fs();
1138         
1139         if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
1140             copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
1141                 return -EFAULT;
1142         set_fs (KERNEL_DS);
1143         ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
1144         set_fs (old_fs);
1145         return ret;
1146 }
1147
1148 asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act,
1149                                      struct old_sigaction32 __user *oact)
1150 {
1151         struct k_sigaction new_ka, old_ka;
1152         int ret;
1153
1154         if (sig < 0) {
1155                 set_thread_flag(TIF_NEWSIGNALS);
1156                 sig = -sig;
1157         }
1158
1159         if (act) {
1160                 compat_old_sigset_t mask;
1161                 u32 u_handler, u_restorer;
1162                 
1163                 ret = get_user(u_handler, &act->sa_handler);
1164                 new_ka.sa.sa_handler =  compat_ptr(u_handler);
1165                 ret |= __get_user(u_restorer, &act->sa_restorer);
1166                 new_ka.sa.sa_restorer = compat_ptr(u_restorer);
1167                 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
1168                 ret |= __get_user(mask, &act->sa_mask);
1169                 if (ret)
1170                         return ret;
1171                 new_ka.ka_restorer = NULL;
1172                 siginitset(&new_ka.sa.sa_mask, mask);
1173         }
1174
1175         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1176
1177         if (!ret && oact) {
1178                 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
1179                 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
1180                 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
1181                 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1182         }
1183
1184         return ret;
1185 }
1186
1187 asmlinkage long compat_sys_rt_sigaction(int sig,
1188                                         struct sigaction32 __user *act,
1189                                         struct sigaction32 __user *oact,
1190                                         void __user *restorer,
1191                                         compat_size_t sigsetsize)
1192 {
1193         struct k_sigaction new_ka, old_ka;
1194         int ret;
1195         compat_sigset_t set32;
1196
1197         /* XXX: Don't preclude handling different sized sigset_t's.  */
1198         if (sigsetsize != sizeof(compat_sigset_t))
1199                 return -EINVAL;
1200
1201         /* All tasks which use RT signals (effectively) use
1202          * new style signals.
1203          */
1204         set_thread_flag(TIF_NEWSIGNALS);
1205
1206         if (act) {
1207                 u32 u_handler, u_restorer;
1208
1209                 new_ka.ka_restorer = restorer;
1210                 ret = get_user(u_handler, &act->sa_handler);
1211                 new_ka.sa.sa_handler =  compat_ptr(u_handler);
1212                 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));
1213                 switch (_NSIG_WORDS) {
1214                 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
1215                 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
1216                 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
1217                 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
1218                 }
1219                 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
1220                 ret |= __get_user(u_restorer, &act->sa_restorer);
1221                 new_ka.sa.sa_restorer = compat_ptr(u_restorer);
1222                 if (ret)
1223                         return -EFAULT;
1224         }
1225
1226         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1227
1228         if (!ret && oact) {
1229                 switch (_NSIG_WORDS) {
1230                 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
1231                 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
1232                 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
1233                 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
1234                 }
1235                 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
1236                 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));
1237                 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
1238                 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
1239                 if (ret)
1240                         ret = -EFAULT;
1241         }
1242
1243         return ret;
1244 }
1245
1246 /*
1247  * sparc32_execve() executes a new program after the asm stub has set
1248  * things up for us.  This should basically do what I want it to.
1249  */
1250 asmlinkage long sparc32_execve(struct pt_regs *regs)
1251 {
1252         int error, base = 0;
1253         char *filename;
1254
1255         /* User register window flush is done by entry.S */
1256
1257         /* Check for indirect call. */
1258         if ((u32)regs->u_regs[UREG_G1] == 0)
1259                 base = 1;
1260
1261         filename = getname(compat_ptr(regs->u_regs[base + UREG_I0]));
1262         error = PTR_ERR(filename);
1263         if (IS_ERR(filename))
1264                 goto out;
1265
1266         error = compat_do_execve(filename,
1267                                  compat_ptr(regs->u_regs[base + UREG_I1]),
1268                                  compat_ptr(regs->u_regs[base + UREG_I2]), regs);
1269
1270         putname(filename);
1271
1272         if (!error) {
1273                 fprs_write(0);
1274                 current_thread_info()->xfsr[0] = 0;
1275                 current_thread_info()->fpsaved[0] = 0;
1276                 regs->tstate &= ~TSTATE_PEF;
1277                 current->ptrace &= ~PT_DTRACE;
1278         }
1279 out:
1280         return error;
1281 }
1282
1283 #ifdef CONFIG_MODULES
1284
1285 asmlinkage long sys32_init_module(void __user *umod, u32 len,
1286                                   const char __user *uargs)
1287 {
1288         return sys_init_module(umod, len, uargs);
1289 }
1290
1291 asmlinkage long sys32_delete_module(const char __user *name_user,
1292                                     unsigned int flags)
1293 {
1294         return sys_delete_module(name_user, flags);
1295 }
1296
1297 #else /* CONFIG_MODULES */
1298
1299 asmlinkage long sys32_init_module(const char __user *name_user,
1300                                   struct module __user *mod_user)
1301 {
1302         return -ENOSYS;
1303 }
1304
1305 asmlinkage long sys32_delete_module(const char __user *name_user)
1306 {
1307         return -ENOSYS;
1308 }
1309
1310 #endif  /* CONFIG_MODULES */
1311
1312 /* Translations due to time_t size differences.  Which affects all
1313    sorts of things, like timeval and itimerval.  */
1314
1315 extern struct timezone sys_tz;
1316
1317 asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
1318                                    struct timezone __user *tz)
1319 {
1320         if (tv) {
1321                 struct timeval ktv;
1322                 do_gettimeofday(&ktv);
1323                 if (put_tv32(tv, &ktv))
1324                         return -EFAULT;
1325         }
1326         if (tz) {
1327                 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
1328                         return -EFAULT;
1329         }
1330         return 0;
1331 }
1332
1333 static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
1334 {
1335         long usec;
1336
1337         if (!access_ok(VERIFY_READ, i, sizeof(*i)))
1338                 return -EFAULT;
1339         if (__get_user(o->tv_sec, &i->tv_sec))
1340                 return -EFAULT;
1341         if (__get_user(usec, &i->tv_usec))
1342                 return -EFAULT;
1343         o->tv_nsec = usec * 1000;
1344         return 0;
1345 }
1346
1347 asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
1348                                    struct timezone __user *tz)
1349 {
1350         struct timespec kts;
1351         struct timezone ktz;
1352
1353         if (tv) {
1354                 if (get_ts32(&kts, tv))
1355                         return -EFAULT;
1356         }
1357         if (tz) {
1358                 if (copy_from_user(&ktz, tz, sizeof(ktz)))
1359                         return -EFAULT;
1360         }
1361
1362         return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
1363 }
1364
1365 asmlinkage long sys32_utimes(char __user *filename,
1366                              struct compat_timeval __user *tvs)
1367 {
1368         struct timeval ktvs[2];
1369
1370         if (tvs) {
1371                 if (get_tv32(&ktvs[0], tvs) ||
1372                     get_tv32(&ktvs[1], 1+tvs))
1373                         return -EFAULT;
1374         }
1375
1376         return do_utimes(filename, (tvs ? &ktvs[0] : NULL));
1377 }
1378
1379 /* These are here just in case some old sparc32 binary calls it. */
1380 asmlinkage long sys32_pause(void)
1381 {
1382         current->state = TASK_INTERRUPTIBLE;
1383         schedule();
1384         return -ERESTARTNOHAND;
1385 }
1386
1387 asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
1388                                         char __user *ubuf,
1389                                         compat_size_t count,
1390                                         unsigned long poshi,
1391                                         unsigned long poslo)
1392 {
1393         return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo);
1394 }
1395
1396 asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd,
1397                                          char __user *ubuf,
1398                                          compat_size_t count,
1399                                          unsigned long poshi,
1400                                          unsigned long poslo)
1401 {
1402         return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo);
1403 }
1404
1405 asmlinkage long compat_sys_readahead(int fd,
1406                                      unsigned long offhi,
1407                                      unsigned long offlo,
1408                                      compat_size_t count)
1409 {
1410         return sys_readahead(fd, (offhi << 32) | offlo, count);
1411 }
1412
1413 long compat_sys_fadvise64(int fd,
1414                           unsigned long offhi,
1415                           unsigned long offlo,
1416                           compat_size_t len, int advice)
1417 {
1418         return sys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice);
1419 }
1420
1421 long compat_sys_fadvise64_64(int fd,
1422                              unsigned long offhi, unsigned long offlo,
1423                              unsigned long lenhi, unsigned long lenlo,
1424                              int advice)
1425 {
1426         return sys_fadvise64_64(fd,
1427                                 (offhi << 32) | offlo,
1428                                 (lenhi << 32) | lenlo,
1429                                 advice);
1430 }
1431
1432 asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
1433                                     compat_off_t __user *offset,
1434                                     compat_size_t count)
1435 {
1436         mm_segment_t old_fs = get_fs();
1437         int ret;
1438         off_t of;
1439         
1440         if (offset && get_user(of, offset))
1441                 return -EFAULT;
1442                 
1443         set_fs(KERNEL_DS);
1444         ret = sys_sendfile(out_fd, in_fd,
1445                            offset ? (off_t __user *) &of : NULL,
1446                            count);
1447         set_fs(old_fs);
1448         
1449         if (offset && put_user(of, offset))
1450                 return -EFAULT;
1451                 
1452         return ret;
1453 }
1454
1455 asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,
1456                                       compat_loff_t __user *offset,
1457                                       compat_size_t count)
1458 {
1459         mm_segment_t old_fs = get_fs();
1460         int ret;
1461         loff_t lof;
1462         
1463         if (offset && get_user(lof, offset))
1464                 return -EFAULT;
1465                 
1466         set_fs(KERNEL_DS);
1467         ret = sys_sendfile64(out_fd, in_fd,
1468                              offset ? (loff_t __user *) &lof : NULL,
1469                              count);
1470         set_fs(old_fs);
1471         
1472         if (offset && put_user(lof, offset))
1473                 return -EFAULT;
1474                 
1475         return ret;
1476 }
1477
1478 /* Handle adjtimex compatibility. */
1479
1480 struct timex32 {
1481         u32 modes;
1482         s32 offset, freq, maxerror, esterror;
1483         s32 status, constant, precision, tolerance;
1484         struct compat_timeval time;
1485         s32 tick;
1486         s32 ppsfreq, jitter, shift, stabil;
1487         s32 jitcnt, calcnt, errcnt, stbcnt;
1488         s32  :32; s32  :32; s32  :32; s32  :32;
1489         s32  :32; s32  :32; s32  :32; s32  :32;
1490         s32  :32; s32  :32; s32  :32; s32  :32;
1491 };
1492
1493 extern int do_adjtimex(struct timex *);
1494
1495 asmlinkage long sys32_adjtimex(struct timex32 __user *utp)
1496 {
1497         struct timex txc;
1498         int ret;
1499
1500         memset(&txc, 0, sizeof(struct timex));
1501
1502         if (get_user(txc.modes, &utp->modes) ||
1503             __get_user(txc.offset, &utp->offset) ||
1504             __get_user(txc.freq, &utp->freq) ||
1505             __get_user(txc.maxerror, &utp->maxerror) ||
1506             __get_user(txc.esterror, &utp->esterror) ||
1507             __get_user(txc.status, &utp->status) ||
1508             __get_user(txc.constant, &utp->constant) ||
1509             __get_user(txc.precision, &utp->precision) ||
1510             __get_user(txc.tolerance, &utp->tolerance) ||
1511             __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
1512             __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
1513             __get_user(txc.tick, &utp->tick) ||
1514             __get_user(txc.ppsfreq, &utp->ppsfreq) ||
1515             __get_user(txc.jitter, &utp->jitter) ||
1516             __get_user(txc.shift, &utp->shift) ||
1517             __get_user(txc.stabil, &utp->stabil) ||
1518             __get_user(txc.jitcnt, &utp->jitcnt) ||
1519             __get_user(txc.calcnt, &utp->calcnt) ||
1520             __get_user(txc.errcnt, &utp->errcnt) ||
1521             __get_user(txc.stbcnt, &utp->stbcnt))
1522                 return -EFAULT;
1523
1524         ret = do_adjtimex(&txc);
1525
1526         if (put_user(txc.modes, &utp->modes) ||
1527             __put_user(txc.offset, &utp->offset) ||
1528             __put_user(txc.freq, &utp->freq) ||
1529             __put_user(txc.maxerror, &utp->maxerror) ||
1530             __put_user(txc.esterror, &utp->esterror) ||
1531             __put_user(txc.status, &utp->status) ||
1532             __put_user(txc.constant, &utp->constant) ||
1533             __put_user(txc.precision, &utp->precision) ||
1534             __put_user(txc.tolerance, &utp->tolerance) ||
1535             __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
1536             __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
1537             __put_user(txc.tick, &utp->tick) ||
1538             __put_user(txc.ppsfreq, &utp->ppsfreq) ||
1539             __put_user(txc.jitter, &utp->jitter) ||
1540             __put_user(txc.shift, &utp->shift) ||
1541             __put_user(txc.stabil, &utp->stabil) ||
1542             __put_user(txc.jitcnt, &utp->jitcnt) ||
1543             __put_user(txc.calcnt, &utp->calcnt) ||
1544             __put_user(txc.errcnt, &utp->errcnt) ||
1545             __put_user(txc.stbcnt, &utp->stbcnt))
1546                 ret = -EFAULT;
1547
1548         return ret;
1549 }
1550
1551 /* This is just a version for 32-bit applications which does
1552  * not force O_LARGEFILE on.
1553  */
1554
1555 asmlinkage long sparc32_open(const char __user *filename,
1556                              int flags, int mode)
1557 {
1558         char * tmp;
1559         int fd, error;
1560
1561         tmp = getname(filename);
1562         fd = PTR_ERR(tmp);
1563         if (!IS_ERR(tmp)) {
1564                 fd = get_unused_fd();
1565                 if (fd >= 0) {
1566                         struct file * f = filp_open(tmp, flags, mode);
1567                         error = PTR_ERR(f);
1568                         if (IS_ERR(f))
1569                                 goto out_error;
1570                         fd_install(fd, f);
1571                 }
1572 out:
1573                 putname(tmp);
1574         }
1575         return fd;
1576
1577 out_error:
1578         put_unused_fd(fd);
1579         fd = error;
1580         goto out;
1581 }
1582
1583 extern unsigned long do_mremap(unsigned long addr,
1584         unsigned long old_len, unsigned long new_len,
1585         unsigned long flags, unsigned long new_addr);
1586                 
1587 asmlinkage unsigned long sys32_mremap(unsigned long addr,
1588         unsigned long old_len, unsigned long new_len,
1589         unsigned long flags, u32 __new_addr)
1590 {
1591         struct vm_area_struct *vma;
1592         unsigned long ret = -EINVAL;
1593         unsigned long new_addr = __new_addr;
1594
1595         if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
1596                 goto out;
1597         if (addr > 0xf0000000UL - old_len)
1598                 goto out;
1599         down_write(&current->mm->mmap_sem);
1600         if (flags & MREMAP_FIXED) {
1601                 if (new_addr > 0xf0000000UL - new_len)
1602                         goto out_sem;
1603         } else if (addr > 0xf0000000UL - new_len) {
1604                 unsigned long map_flags = 0;
1605                 struct file *file = NULL;
1606
1607                 ret = -ENOMEM;
1608                 if (!(flags & MREMAP_MAYMOVE))
1609                         goto out_sem;
1610
1611                 vma = find_vma(current->mm, addr);
1612                 if (vma) {
1613                         if (vma->vm_flags & VM_SHARED)
1614                                 map_flags |= MAP_SHARED;
1615                         file = vma->vm_file;
1616                 }
1617
1618                 /* MREMAP_FIXED checked above. */
1619                 new_addr = get_unmapped_area(file, addr, new_len,
1620                                     vma ? vma->vm_pgoff : 0,
1621                                     map_flags);
1622                 ret = new_addr;
1623                 if (new_addr & ~PAGE_MASK)
1624                         goto out_sem;
1625                 flags |= MREMAP_FIXED;
1626         }
1627         ret = do_mremap(addr, old_len, new_len, flags, new_addr);
1628 out_sem:
1629         up_write(&current->mm->mmap_sem);
1630 out:
1631         return ret;       
1632 }
1633
1634 struct __sysctl_args32 {
1635         u32 name;
1636         int nlen;
1637         u32 oldval;
1638         u32 oldlenp;
1639         u32 newval;
1640         u32 newlen;
1641         u32 __unused[4];
1642 };
1643
1644 asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args)
1645 {
1646 #ifndef CONFIG_SYSCTL
1647         return -ENOSYS;
1648 #else
1649         struct __sysctl_args32 tmp;
1650         int error;
1651         size_t oldlen, __user *oldlenp = NULL;
1652         unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL;
1653
1654         if (copy_from_user(&tmp, args, sizeof(tmp)))
1655                 return -EFAULT;
1656
1657         if (tmp.oldval && tmp.oldlenp) {
1658                 /* Duh, this is ugly and might not work if sysctl_args
1659                    is in read-only memory, but do_sysctl does indirectly
1660                    a lot of uaccess in both directions and we'd have to
1661                    basically copy the whole sysctl.c here, and
1662                    glibc's __sysctl uses rw memory for the structure
1663                    anyway.  */
1664                 if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) ||
1665                     put_user(oldlen, (size_t __user *)addr))
1666                         return -EFAULT;
1667                 oldlenp = (size_t __user *)addr;
1668         }
1669
1670         lock_kernel();
1671         error = do_sysctl((int __user *)(unsigned long) tmp.name,
1672                           tmp.nlen,
1673                           (void __user *)(unsigned long) tmp.oldval,
1674                           oldlenp,
1675                           (void __user *)(unsigned long) tmp.newval,
1676                           tmp.newlen);
1677         unlock_kernel();
1678         if (oldlenp) {
1679                 if (!error) {
1680                         if (get_user(oldlen, (size_t __user *)addr) ||
1681                             put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))
1682                                 error = -EFAULT;
1683                 }
1684                 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
1685         }
1686         return error;
1687 #endif
1688 }
1689
1690 long sys32_lookup_dcookie(unsigned long cookie_high,
1691                           unsigned long cookie_low,
1692                           char __user *buf, size_t len)
1693 {
1694         return sys_lookup_dcookie((cookie_high << 32) | cookie_low,
1695                                   buf, len);
1696 }
1697
1698 extern asmlinkage long
1699 sys_timer_create(clockid_t which_clock,
1700                  struct sigevent __user *timer_event_spec,
1701                  timer_t __user *created_timer_id);
1702
1703 long
1704 sys32_timer_create(u32 clock, struct sigevent32 __user *se32,
1705                    timer_t __user *timer_id)
1706 {
1707         struct sigevent se;
1708         mm_segment_t oldfs;
1709         timer_t t;
1710         long err;
1711
1712         if (se32 == NULL)
1713                 return sys_timer_create(clock, NULL, timer_id);
1714
1715         memset(&se, 0, sizeof(struct sigevent));
1716         if (get_user(se.sigev_value.sival_int,  &se32->sigev_value.sival_int) ||
1717             __get_user(se.sigev_signo, &se32->sigev_signo) ||
1718             __get_user(se.sigev_notify, &se32->sigev_notify) ||
1719             __copy_from_user(&se._sigev_un._pad, &se32->_sigev_un._pad,
1720             sizeof(se._sigev_un._pad)))
1721                 return -EFAULT;
1722
1723         if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))
1724                 return -EFAULT;
1725
1726         oldfs = get_fs();
1727         set_fs(KERNEL_DS);
1728         err = sys_timer_create(clock,
1729                                (struct sigevent __user *) &se,
1730                                (timer_t __user *) &t);
1731         set_fs(oldfs);
1732
1733         if (!err)
1734                 err = __put_user (t, timer_id);
1735
1736         return err;
1737 }
1738