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