Merge with Linux 2.5.48.
[linux-2.6/linux-mips.git] / arch / sparc64 / kernel / sys_sparc32.c
blobc54d028c681a2089206bfbf489fc9e826bdc3420
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.
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
7 * These routines maintain argument size conversion between 32bit and 64bit
8 * environment.
9 */
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/utime.h>
19 #include <linux/resource.h>
20 #include <linux/times.h>
21 #include <linux/utsname.h>
22 #include <linux/timex.h>
23 #include <linux/smp.h>
24 #include <linux/smp_lock.h>
25 #include <linux/sem.h>
26 #include <linux/msg.h>
27 #include <linux/shm.h>
28 #include <linux/slab.h>
29 #include <linux/uio.h>
30 #include <linux/nfs_fs.h>
31 #include <linux/smb_fs.h>
32 #include <linux/smb_mount.h>
33 #include <linux/ncp_fs.h>
34 #include <linux/quota.h>
35 #include <linux/module.h>
36 #include <linux/sunrpc/svc.h>
37 #include <linux/nfsd/nfsd.h>
38 #include <linux/nfsd/cache.h>
39 #include <linux/nfsd/xdr.h>
40 #include <linux/nfsd/syscall.h>
41 #include <linux/poll.h>
42 #include <linux/personality.h>
43 #include <linux/stat.h>
44 #include <linux/filter.h>
45 #include <linux/highmem.h>
46 #include <linux/highuid.h>
47 #include <linux/mman.h>
48 #include <linux/ipv6.h>
49 #include <linux/in.h>
50 #include <linux/icmpv6.h>
51 #include <linux/sysctl.h>
52 #include <linux/binfmts.h>
53 #include <linux/dnotify.h>
55 #include <asm/types.h>
56 #include <asm/ipc.h>
57 #include <asm/uaccess.h>
58 #include <asm/fpumacro.h>
59 #include <asm/semaphore.h>
60 #include <asm/mmu_context.h>
62 #include <net/scm.h>
64 /* Use this to get at 32-bit user passed pointers. */
65 /* Things to consider: the low-level assembly stub does
66 srl x, 0, x for first four arguments, so if you have
67 pointer to something in the first four arguments, just
68 declare it as a pointer, not u32. On the other side,
69 arguments from 5th onwards should be declared as u32
70 for pointers, and need AA() around each usage.
71 A() macro should be used for places where you e.g.
72 have some internal variable u32 and just want to get
73 rid of a compiler warning. AA() has to be used in
74 places where you want to convert a function argument
75 to 32bit pointer or when you e.g. access pt_regs
76 structure and want to consider 32bit registers only.
77 -jj
79 #define A(__x) ((unsigned long)(__x))
80 #define AA(__x) \
81 ({ unsigned long __ret; \
82 __asm__ ("srl %0, 0, %0" \
83 : "=r" (__ret) \
84 : "0" (__x)); \
85 __ret; \
88 extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
89 extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
90 extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
91 extern asmlinkage long sys_setregid(gid_t, gid_t);
92 extern asmlinkage long sys_setgid(gid_t);
93 extern asmlinkage long sys_setreuid(uid_t, uid_t);
94 extern asmlinkage long sys_setuid(uid_t);
95 extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
96 extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
97 extern asmlinkage long sys_setfsuid(uid_t);
98 extern asmlinkage long sys_setfsgid(gid_t);
100 /* For this source file, we want overflow handling. */
102 #undef high2lowuid
103 #undef high2lowgid
104 #undef low2highuid
105 #undef low2highgid
106 #undef SET_UID16
107 #undef SET_GID16
108 #undef NEW_TO_OLD_UID
109 #undef NEW_TO_OLD_GID
110 #undef SET_OLDSTAT_UID
111 #undef SET_OLDSTAT_GID
112 #undef SET_STAT_UID
113 #undef SET_STAT_GID
115 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
116 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
117 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
118 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
119 #define SET_UID16(var, uid) var = high2lowuid(uid)
120 #define SET_GID16(var, gid) var = high2lowgid(gid)
121 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
122 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
123 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
124 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
125 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
126 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
128 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
130 return sys_chown(filename, low2highuid(user), low2highgid(group));
133 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
135 return sys_lchown(filename, low2highuid(user), low2highgid(group));
138 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
140 return sys_fchown(fd, low2highuid(user), low2highgid(group));
143 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
145 return sys_setregid(low2highgid(rgid), low2highgid(egid));
148 asmlinkage long sys32_setgid16(u16 gid)
150 return sys_setgid((gid_t)gid);
153 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
155 return sys_setreuid(low2highuid(ruid), low2highuid(euid));
158 asmlinkage long sys32_setuid16(u16 uid)
160 return sys_setuid((uid_t)uid);
163 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
165 return sys_setresuid(low2highuid(ruid), low2highuid(euid),
166 low2highuid(suid));
169 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
171 int retval;
173 if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
174 !(retval = put_user(high2lowuid(current->euid), euid)))
175 retval = put_user(high2lowuid(current->suid), suid);
177 return retval;
180 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
182 return sys_setresgid(low2highgid(rgid), low2highgid(egid),
183 low2highgid(sgid));
186 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
188 int retval;
190 if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
191 !(retval = put_user(high2lowgid(current->egid), egid)))
192 retval = put_user(high2lowgid(current->sgid), sgid);
194 return retval;
197 asmlinkage long sys32_setfsuid16(u16 uid)
199 return sys_setfsuid((uid_t)uid);
202 asmlinkage long sys32_setfsgid16(u16 gid)
204 return sys_setfsgid((gid_t)gid);
207 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
209 u16 groups[NGROUPS];
210 int i,j;
212 if (gidsetsize < 0)
213 return -EINVAL;
214 i = current->ngroups;
215 if (gidsetsize) {
216 if (i > gidsetsize)
217 return -EINVAL;
218 for(j=0;j<i;j++)
219 groups[j] = current->groups[j];
220 if (copy_to_user(grouplist, groups, sizeof(u16)*i))
221 return -EFAULT;
223 return i;
226 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
228 u16 groups[NGROUPS];
229 int i;
231 if (!capable(CAP_SETGID))
232 return -EPERM;
233 if ((unsigned) gidsetsize > NGROUPS)
234 return -EINVAL;
235 if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
236 return -EFAULT;
237 for (i = 0 ; i < gidsetsize ; i++)
238 current->groups[i] = (gid_t)groups[i];
239 current->ngroups = gidsetsize;
240 return 0;
243 asmlinkage long sys32_getuid16(void)
245 return high2lowuid(current->uid);
248 asmlinkage long sys32_geteuid16(void)
250 return high2lowuid(current->euid);
253 asmlinkage long sys32_getgid16(void)
255 return high2lowgid(current->gid);
258 asmlinkage long sys32_getegid16(void)
260 return high2lowgid(current->egid);
263 /* 32-bit timeval and related flotsam. */
265 struct timeval32
267 int tv_sec, tv_usec;
270 struct itimerval32
272 struct timeval32 it_interval;
273 struct timeval32 it_value;
276 static long get_tv32(struct timeval *o, struct timeval32 *i)
278 return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
279 (__get_user(o->tv_sec, &i->tv_sec) |
280 __get_user(o->tv_usec, &i->tv_usec)));
283 static inline long put_tv32(struct timeval32 *o, struct timeval *i)
285 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
286 (__put_user(i->tv_sec, &o->tv_sec) |
287 __put_user(i->tv_usec, &o->tv_usec)));
290 static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
292 return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
293 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
294 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
295 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
296 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
299 static long put_it32(struct itimerval32 *o, struct itimerval *i)
301 return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
302 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
303 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
304 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
305 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
308 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
310 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
312 return sys_ioperm((unsigned long)from, (unsigned long)num, on);
315 struct msgbuf32 { s32 mtype; char mtext[1]; };
317 struct ipc_perm32
319 key_t key;
320 __kernel_uid_t32 uid;
321 __kernel_gid_t32 gid;
322 __kernel_uid_t32 cuid;
323 __kernel_gid_t32 cgid;
324 __kernel_mode_t32 mode;
325 unsigned short seq;
328 struct semid_ds32 {
329 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
330 __kernel_time_t32 sem_otime; /* last semop time */
331 __kernel_time_t32 sem_ctime; /* last change time */
332 u32 sem_base; /* ptr to first semaphore in array */
333 u32 sem_pending; /* pending operations to be processed */
334 u32 sem_pending_last; /* last pending operation */
335 u32 undo; /* undo requests on this array */
336 unsigned short sem_nsems; /* no. of semaphores in array */
339 struct semid64_ds32 {
340 struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
341 unsigned int __pad1;
342 __kernel_time_t32 sem_otime;
343 unsigned int __pad2;
344 __kernel_time_t32 sem_ctime;
345 u32 sem_nsems;
346 u32 __unused1;
347 u32 __unused2;
350 struct msqid_ds32
352 struct ipc_perm32 msg_perm;
353 u32 msg_first;
354 u32 msg_last;
355 __kernel_time_t32 msg_stime;
356 __kernel_time_t32 msg_rtime;
357 __kernel_time_t32 msg_ctime;
358 u32 wwait;
359 u32 rwait;
360 unsigned short msg_cbytes;
361 unsigned short msg_qnum;
362 unsigned short msg_qbytes;
363 __kernel_ipc_pid_t32 msg_lspid;
364 __kernel_ipc_pid_t32 msg_lrpid;
367 struct msqid64_ds32 {
368 struct ipc64_perm msg_perm;
369 unsigned int __pad1;
370 __kernel_time_t32 msg_stime;
371 unsigned int __pad2;
372 __kernel_time_t32 msg_rtime;
373 unsigned int __pad3;
374 __kernel_time_t32 msg_ctime;
375 unsigned int msg_cbytes;
376 unsigned int msg_qnum;
377 unsigned int msg_qbytes;
378 __kernel_pid_t32 msg_lspid;
379 __kernel_pid_t32 msg_lrpid;
380 unsigned int __unused1;
381 unsigned int __unused2;
385 struct shmid_ds32 {
386 struct ipc_perm32 shm_perm;
387 int shm_segsz;
388 __kernel_time_t32 shm_atime;
389 __kernel_time_t32 shm_dtime;
390 __kernel_time_t32 shm_ctime;
391 __kernel_ipc_pid_t32 shm_cpid;
392 __kernel_ipc_pid_t32 shm_lpid;
393 unsigned short shm_nattch;
396 struct shmid64_ds32 {
397 struct ipc64_perm shm_perm;
398 unsigned int __pad1;
399 __kernel_time_t32 shm_atime;
400 unsigned int __pad2;
401 __kernel_time_t32 shm_dtime;
402 unsigned int __pad3;
403 __kernel_time_t32 shm_ctime;
404 __kernel_size_t32 shm_segsz;
405 __kernel_pid_t32 shm_cpid;
406 __kernel_pid_t32 shm_lpid;
407 unsigned int shm_nattch;
408 unsigned int __unused1;
409 unsigned int __unused2;
414 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
416 * This is really horribly ugly.
418 #define IPCOP_MASK(__x) (1UL << (__x))
419 static int do_sys32_semctl(int first, int second, int third, void *uptr)
421 union semun fourth;
422 u32 pad;
423 int err = -EINVAL;
425 if (!uptr)
426 goto out;
427 err = -EFAULT;
428 if (get_user (pad, (u32 *)uptr))
429 goto out;
430 if(third == SETVAL)
431 fourth.val = (int)pad;
432 else
433 fourth.__pad = (void *)A(pad);
434 if (IPCOP_MASK (third) &
435 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
436 IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
437 IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
438 err = sys_semctl (first, second, third, fourth);
439 } else if (third & IPC_64) {
440 struct semid64_ds s;
441 struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
442 mm_segment_t old_fs;
443 int need_back_translation;
445 if (third == (IPC_SET|IPC_64)) {
446 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
447 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
448 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
449 if (err)
450 goto out;
451 fourth.__pad = &s;
453 need_back_translation =
454 (IPCOP_MASK (third) &
455 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
456 if (need_back_translation)
457 fourth.__pad = &s;
458 old_fs = get_fs ();
459 set_fs (KERNEL_DS);
460 err = sys_semctl (first, second, third, fourth);
461 set_fs (old_fs);
462 if (need_back_translation) {
463 int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
464 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
465 if (err2) err = -EFAULT;
467 } else {
468 struct semid_ds s;
469 struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
470 mm_segment_t old_fs;
471 int need_back_translation;
473 if (third == IPC_SET) {
474 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
475 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
476 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
477 if (err)
478 goto out;
479 fourth.__pad = &s;
481 need_back_translation =
482 (IPCOP_MASK (third) &
483 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
484 if (need_back_translation)
485 fourth.__pad = &s;
486 old_fs = get_fs ();
487 set_fs (KERNEL_DS);
488 err = sys_semctl (first, second, third, fourth);
489 set_fs (old_fs);
490 if (need_back_translation) {
491 int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
492 err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
493 err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
494 err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
495 err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
496 err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
497 err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
498 err2 |= __put_user (s.sem_otime, &usp->sem_otime);
499 err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
500 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
501 if (err2) err = -EFAULT;
504 out:
505 return err;
508 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
510 struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
511 struct msgbuf32 *up = (struct msgbuf32 *)uptr;
512 mm_segment_t old_fs;
513 int err;
515 if (!p)
516 return -ENOMEM;
517 err = -EFAULT;
518 if (get_user (p->mtype, &up->mtype) ||
519 __copy_from_user (p->mtext, &up->mtext, second))
520 goto out;
521 old_fs = get_fs ();
522 set_fs (KERNEL_DS);
523 err = sys_msgsnd (first, p, second, third);
524 set_fs (old_fs);
525 out:
526 kfree (p);
527 return err;
530 static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
531 int version, void *uptr)
533 struct msgbuf32 *up;
534 struct msgbuf *p;
535 mm_segment_t old_fs;
536 int err;
538 if (!version) {
539 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
540 struct ipc_kludge ipck;
542 err = -EINVAL;
543 if (!uptr)
544 goto out;
545 err = -EFAULT;
546 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
547 goto out;
548 uptr = (void *)A(ipck.msgp);
549 msgtyp = ipck.msgtyp;
551 err = -ENOMEM;
552 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
553 if (!p)
554 goto out;
555 old_fs = get_fs ();
556 set_fs (KERNEL_DS);
557 err = sys_msgrcv (first, p, second + 4, msgtyp, third);
558 set_fs (old_fs);
559 if (err < 0)
560 goto free_then_out;
561 up = (struct msgbuf32 *)uptr;
562 if (put_user (p->mtype, &up->mtype) ||
563 __copy_to_user (&up->mtext, p->mtext, err))
564 err = -EFAULT;
565 free_then_out:
566 kfree (p);
567 out:
568 return err;
571 static int do_sys32_msgctl (int first, int second, void *uptr)
573 int err;
575 if (IPCOP_MASK (second) &
576 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
577 IPCOP_MASK (IPC_RMID))) {
578 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
579 } else if (second & IPC_64) {
580 struct msqid64_ds m;
581 struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
582 mm_segment_t old_fs;
584 if (second == (IPC_SET|IPC_64)) {
585 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
586 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
587 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
588 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
589 if (err)
590 goto out;
592 old_fs = get_fs ();
593 set_fs (KERNEL_DS);
594 err = sys_msgctl (first, second, (struct msqid_ds *)&m);
595 set_fs (old_fs);
596 if (IPCOP_MASK (second) &
597 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
598 int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
599 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
600 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
601 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
602 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
603 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
604 if (err2)
605 err = -EFAULT;
607 } else {
608 struct msqid_ds m;
609 struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
610 mm_segment_t old_fs;
612 if (second == IPC_SET) {
613 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
614 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
615 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
616 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
617 if (err)
618 goto out;
620 old_fs = get_fs ();
621 set_fs (KERNEL_DS);
622 err = sys_msgctl (first, second, &m);
623 set_fs (old_fs);
624 if (IPCOP_MASK (second) &
625 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
626 int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
627 err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
628 err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
629 err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
630 err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
631 err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
632 err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
633 err2 |= __put_user (m.msg_stime, &up->msg_stime);
634 err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
635 err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
636 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
637 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
638 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
639 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
640 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
641 if (err2)
642 err = -EFAULT;
646 out:
647 return err;
650 static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
652 unsigned long raddr;
653 u32 *uaddr = (u32 *)A((u32)third);
654 int err = -EINVAL;
656 if (version == 1)
657 goto out;
658 err = sys_shmat (first, uptr, second, &raddr);
659 if (err)
660 goto out;
661 err = put_user (raddr, uaddr);
662 out:
663 return err;
666 static int do_sys32_shmctl (int first, int second, void *uptr)
668 int err;
670 if (IPCOP_MASK (second) &
671 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
672 IPCOP_MASK (IPC_RMID))) {
673 if (second == (IPC_INFO|IPC_64))
674 second = IPC_INFO; /* So that we don't have to translate it */
675 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
676 } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
677 struct shmid64_ds s;
678 struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
679 mm_segment_t old_fs;
681 if (second == (IPC_SET|IPC_64)) {
682 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
683 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
684 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
685 if (err)
686 goto out;
688 old_fs = get_fs ();
689 set_fs (KERNEL_DS);
690 err = sys_shmctl (first, second, (struct shmid_ds *)&s);
691 set_fs (old_fs);
692 if (err < 0)
693 goto out;
695 /* Mask it even in this case so it becomes a CSE. */
696 if (IPCOP_MASK (second) &
697 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
698 int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
699 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
700 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
701 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
702 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
703 if (err2)
704 err = -EFAULT;
706 } else {
707 struct shmid_ds s;
708 struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
709 mm_segment_t old_fs;
711 second &= ~IPC_64;
712 if (second == IPC_SET) {
713 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
714 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
715 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
716 if (err)
717 goto out;
719 old_fs = get_fs ();
720 set_fs (KERNEL_DS);
721 err = sys_shmctl (first, second, &s);
722 set_fs (old_fs);
723 if (err < 0)
724 goto out;
726 /* Mask it even in this case so it becomes a CSE. */
727 if (second == SHM_INFO) {
728 struct shm_info32 {
729 int used_ids;
730 u32 shm_tot, shm_rss, shm_swp;
731 u32 swap_attempts, swap_successes;
732 } *uip = (struct shm_info32 *)uptr;
733 struct shm_info *kp = (struct shm_info *)&s;
734 int err2 = put_user (kp->used_ids, &uip->used_ids);
735 err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
736 err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
737 err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
738 err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
739 err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
740 if (err2)
741 err = -EFAULT;
742 } else if (IPCOP_MASK (second) &
743 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
744 int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
745 err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
746 err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
747 err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
748 err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
749 err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
750 err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
751 err2 |= __put_user (s.shm_atime, &up->shm_atime);
752 err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
753 err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
754 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
755 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
756 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
757 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
758 if (err2)
759 err = -EFAULT;
762 out:
763 return err;
766 asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
768 int version, err;
770 version = call >> 16; /* hack for backward compatibility */
771 call &= 0xffff;
773 if (call <= SEMCTL)
774 switch (call) {
775 case SEMOP:
776 /* struct sembuf is the same on 32 and 64bit :)) */
777 err = sys_semop (first, (struct sembuf *)AA(ptr), second);
778 goto out;
779 case SEMGET:
780 err = sys_semget (first, second, third);
781 goto out;
782 case SEMCTL:
783 err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
784 goto out;
785 default:
786 err = -EINVAL;
787 goto out;
789 if (call <= MSGCTL)
790 switch (call) {
791 case MSGSND:
792 err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
793 goto out;
794 case MSGRCV:
795 err = do_sys32_msgrcv (first, second, fifth, third,
796 version, (void *)AA(ptr));
797 goto out;
798 case MSGGET:
799 err = sys_msgget ((key_t) first, second);
800 goto out;
801 case MSGCTL:
802 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
803 goto out;
804 default:
805 err = -EINVAL;
806 goto out;
808 if (call <= SHMCTL)
809 switch (call) {
810 case SHMAT:
811 err = do_sys32_shmat (first, second, third,
812 version, (void *)AA(ptr));
813 goto out;
814 case SHMDT:
815 err = sys_shmdt ((char *)AA(ptr));
816 goto out;
817 case SHMGET:
818 err = sys_shmget (first, second, third);
819 goto out;
820 case SHMCTL:
821 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
822 goto out;
823 default:
824 err = -EINVAL;
825 goto out;
828 err = -EINVAL;
830 out:
831 return err;
834 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
836 int err;
838 err = get_user(kfl->l_type, &ufl->l_type);
839 err |= __get_user(kfl->l_whence, &ufl->l_whence);
840 err |= __get_user(kfl->l_start, &ufl->l_start);
841 err |= __get_user(kfl->l_len, &ufl->l_len);
842 err |= __get_user(kfl->l_pid, &ufl->l_pid);
843 return err;
846 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
848 int err;
850 err = __put_user(kfl->l_type, &ufl->l_type);
851 err |= __put_user(kfl->l_whence, &ufl->l_whence);
852 err |= __put_user(kfl->l_start, &ufl->l_start);
853 err |= __put_user(kfl->l_len, &ufl->l_len);
854 err |= __put_user(kfl->l_pid, &ufl->l_pid);
855 return err;
858 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
860 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
862 switch (cmd) {
863 case F_GETLK:
864 case F_SETLK:
865 case F_SETLKW:
867 struct flock f;
868 mm_segment_t old_fs;
869 long ret;
871 if (get_flock(&f, (struct flock32 *)arg))
872 return -EFAULT;
873 old_fs = get_fs(); set_fs (KERNEL_DS);
874 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
875 set_fs (old_fs);
876 if (ret) return ret;
877 if (put_flock(&f, (struct flock32 *)arg))
878 return -EFAULT;
879 return 0;
881 default:
882 return sys_fcntl(fd, cmd, (unsigned long)arg);
886 asmlinkage long sys32_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
888 if (cmd >= F_GETLK64 && cmd <= F_SETLKW64)
889 return sys_fcntl(fd, cmd + F_GETLK - F_GETLK64, arg);
890 return sys32_fcntl(fd, cmd, arg);
893 static int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
895 int err;
897 err = put_user (kbuf->f_type, &ubuf->f_type);
898 err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
899 err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
900 err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
901 err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
902 err |= __put_user (kbuf->f_files, &ubuf->f_files);
903 err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
904 err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
905 err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
906 err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
907 return err;
910 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
912 asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
914 int ret;
915 struct statfs s;
916 mm_segment_t old_fs = get_fs();
917 char *pth;
919 pth = getname (path);
920 ret = PTR_ERR(pth);
921 if (!IS_ERR(pth)) {
922 set_fs (KERNEL_DS);
923 ret = sys_statfs((const char *)pth, &s);
924 set_fs (old_fs);
925 putname (pth);
926 if (put_statfs(buf, &s))
927 return -EFAULT;
929 return ret;
932 extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
934 asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
936 int ret;
937 struct statfs s;
938 mm_segment_t old_fs = get_fs();
940 set_fs (KERNEL_DS);
941 ret = sys_fstatfs(fd, &s);
942 set_fs (old_fs);
943 if (put_statfs(buf, &s))
944 return -EFAULT;
945 return ret;
948 extern asmlinkage long sys_truncate(const char * path, unsigned long length);
949 extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
951 asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
953 if ((int)high < 0)
954 return -EINVAL;
955 else
956 return sys_truncate(path, (high << 32) | low);
959 asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
961 if ((int)high < 0)
962 return -EINVAL;
963 else
964 return sys_ftruncate(fd, (high << 32) | low);
967 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
969 struct utimbuf32 {
970 __kernel_time_t32 actime, modtime;
973 asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
975 struct utimbuf t;
976 mm_segment_t old_fs;
977 int ret;
978 char *filenam;
980 if (!times)
981 return sys_utime(filename, NULL);
982 if (get_user (t.actime, &times->actime) ||
983 __get_user (t.modtime, &times->modtime))
984 return -EFAULT;
985 filenam = getname (filename);
986 ret = PTR_ERR(filenam);
987 if (!IS_ERR(filenam)) {
988 old_fs = get_fs();
989 set_fs (KERNEL_DS);
990 ret = sys_utime(filenam, &t);
991 set_fs (old_fs);
992 putname (filenam);
994 return ret;
997 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
999 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
1000 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1002 static long do_readv_writev32(int type, struct file *file,
1003 const struct iovec32 *vector, u32 count)
1005 __kernel_ssize_t32 tot_len;
1006 struct iovec iovstack[UIO_FASTIOV];
1007 struct iovec *iov=iovstack, *ivp;
1008 struct inode *inode;
1009 long retval, i;
1010 io_fn_t fn;
1011 iov_fn_t fnv;
1013 /* First get the "struct iovec" from user memory and
1014 * verify all the pointers
1016 retval = 0;
1017 if (!count)
1018 goto out_nofree;
1019 retval = -EFAULT;
1020 if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1021 goto out_nofree;
1022 retval = -EINVAL;
1023 if (count > UIO_MAXIOV)
1024 goto out_nofree;
1025 if (count > UIO_FASTIOV) {
1026 retval = -ENOMEM;
1027 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1028 if (!iov)
1029 goto out_nofree;
1032 tot_len = 0;
1033 i = count;
1034 ivp = iov;
1035 retval = -EINVAL;
1036 while(i > 0) {
1037 __kernel_ssize_t32 tmp = tot_len;
1038 __kernel_ssize_t32 len;
1039 u32 buf;
1041 __get_user(len, &vector->iov_len);
1042 __get_user(buf, &vector->iov_base);
1043 if (len < 0) /* size_t not fittina an ssize_t32 .. */
1044 goto out;
1045 tot_len += len;
1046 if (tot_len < tmp) /* maths overflow on the ssize_t32 */
1047 goto out;
1048 ivp->iov_base = (void *)A(buf);
1049 ivp->iov_len = (__kernel_size_t) len;
1050 vector++;
1051 ivp++;
1052 i--;
1055 inode = file->f_dentry->d_inode;
1056 /* VERIFY_WRITE actually means a read, as we write to user space */
1057 retval = locks_verify_area((type == VERIFY_WRITE
1058 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1059 inode, file, file->f_pos, tot_len);
1060 if (retval)
1061 goto out;
1063 /* VERIFY_WRITE actually means a read, as we write to user space */
1064 fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
1065 if (fnv) {
1066 retval = fnv(file, iov, count, &file->f_pos);
1067 goto out;
1070 fn = (type == VERIFY_WRITE ? file->f_op->read :
1071 (io_fn_t) file->f_op->write);
1073 ivp = iov;
1074 while (count > 0) {
1075 void * base;
1076 int len, nr;
1078 base = ivp->iov_base;
1079 len = ivp->iov_len;
1080 ivp++;
1081 count--;
1082 nr = fn(file, base, len, &file->f_pos);
1083 if (nr < 0) {
1084 if (!retval)
1085 retval = nr;
1086 break;
1088 retval += nr;
1089 if (nr != len)
1090 break;
1092 out:
1093 if (iov != iovstack)
1094 kfree(iov);
1095 out_nofree:
1096 /* VERIFY_WRITE actually means a read, as we write to user space */
1097 if ((retval + (type == VERIFY_WRITE)) > 0)
1098 dnotify_parent(file->f_dentry,
1099 (type == VERIFY_WRITE) ? DN_MODIFY : DN_ACCESS);
1101 return retval;
1104 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1106 struct file *file;
1107 long ret = -EBADF;
1109 file = fget(fd);
1110 if(!file)
1111 goto bad_file;
1113 if (file->f_op && (file->f_mode & FMODE_READ) &&
1114 (file->f_op->readv || file->f_op->read))
1115 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1116 fput(file);
1118 bad_file:
1119 return ret;
1122 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1124 struct file *file;
1125 int ret = -EBADF;
1127 file = fget(fd);
1128 if(!file)
1129 goto bad_file;
1130 if (file->f_op && (file->f_mode & FMODE_WRITE) &&
1131 (file->f_op->writev || file->f_op->write))
1132 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1133 fput(file);
1135 bad_file:
1136 return ret;
1139 /* readdir & getdents */
1141 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1142 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1144 struct old_linux_dirent32 {
1145 u32 d_ino;
1146 u32 d_offset;
1147 unsigned short d_namlen;
1148 char d_name[1];
1151 struct readdir_callback32 {
1152 struct old_linux_dirent32 * dirent;
1153 int count;
1156 static int fillonedir(void * __buf, const char * name, int namlen,
1157 loff_t offset, ino_t ino, unsigned int d_type)
1159 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1160 struct old_linux_dirent32 * dirent;
1162 if (buf->count)
1163 return -EINVAL;
1164 buf->count++;
1165 dirent = buf->dirent;
1166 put_user(ino, &dirent->d_ino);
1167 put_user(offset, &dirent->d_offset);
1168 put_user(namlen, &dirent->d_namlen);
1169 copy_to_user(dirent->d_name, name, namlen);
1170 put_user(0, dirent->d_name + namlen);
1171 return 0;
1174 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1176 int error = -EBADF;
1177 struct file * file;
1178 struct readdir_callback32 buf;
1180 file = fget(fd);
1181 if (!file)
1182 goto out;
1184 buf.count = 0;
1185 buf.dirent = dirent;
1187 error = vfs_readdir(file, fillonedir, &buf);
1188 if (error < 0)
1189 goto out_putf;
1190 error = buf.count;
1192 out_putf:
1193 fput(file);
1194 out:
1195 return error;
1198 struct linux_dirent32 {
1199 u32 d_ino;
1200 u32 d_off;
1201 unsigned short d_reclen;
1202 char d_name[1];
1205 struct getdents_callback32 {
1206 struct linux_dirent32 * current_dir;
1207 struct linux_dirent32 * previous;
1208 int count;
1209 int error;
1212 static int filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino,
1213 unsigned int d_type)
1215 struct linux_dirent32 * dirent;
1216 struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1217 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1219 buf->error = -EINVAL; /* only used if we fail.. */
1220 if (reclen > buf->count)
1221 return -EINVAL;
1222 dirent = buf->previous;
1223 if (dirent)
1224 put_user(offset, &dirent->d_off);
1225 dirent = buf->current_dir;
1226 buf->previous = dirent;
1227 put_user(ino, &dirent->d_ino);
1228 put_user(reclen, &dirent->d_reclen);
1229 copy_to_user(dirent->d_name, name, namlen);
1230 put_user(0, dirent->d_name + namlen);
1231 ((char *) dirent) += reclen;
1232 buf->current_dir = dirent;
1233 buf->count -= reclen;
1234 return 0;
1237 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1239 struct file * file;
1240 struct linux_dirent32 * lastdirent;
1241 struct getdents_callback32 buf;
1242 int error = -EBADF;
1244 file = fget(fd);
1245 if (!file)
1246 goto out;
1248 buf.current_dir = dirent;
1249 buf.previous = NULL;
1250 buf.count = count;
1251 buf.error = 0;
1253 error = vfs_readdir(file, filldir, &buf);
1254 if (error < 0)
1255 goto out_putf;
1256 lastdirent = buf.previous;
1257 error = buf.error;
1258 if(lastdirent) {
1259 put_user(file->f_pos, &lastdirent->d_off);
1260 error = count - buf.count;
1262 out_putf:
1263 fput(file);
1264 out:
1265 return error;
1268 /* end of readdir & getdents */
1271 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1272 * 64-bit unsigned longs.
1275 static int get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1277 if (ufdset) {
1278 unsigned long odd;
1280 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1281 return -EFAULT;
1283 odd = n & 1UL;
1284 n &= ~1UL;
1285 while (n) {
1286 unsigned long h, l;
1287 __get_user(l, ufdset);
1288 __get_user(h, ufdset+1);
1289 ufdset += 2;
1290 *fdset++ = h << 32 | l;
1291 n -= 2;
1293 if (odd)
1294 __get_user(*fdset, ufdset);
1295 } else {
1296 /* Tricky, must clear full unsigned long in the
1297 * kernel fdset at the end, this makes sure that
1298 * actually happens.
1300 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1302 return 0;
1305 static void set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1307 unsigned long odd;
1309 if (!ufdset)
1310 return;
1312 odd = n & 1UL;
1313 n &= ~1UL;
1314 while (n) {
1315 unsigned long h, l;
1316 l = *fdset++;
1317 h = l >> 32;
1318 __put_user(l, ufdset);
1319 __put_user(h, ufdset+1);
1320 ufdset += 2;
1321 n -= 2;
1323 if (odd)
1324 __put_user(*fdset, ufdset);
1327 #define MAX_SELECT_SECONDS \
1328 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1330 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1332 fd_set_bits fds;
1333 struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1334 char *bits;
1335 unsigned long nn;
1336 long timeout;
1337 int ret, size;
1339 timeout = MAX_SCHEDULE_TIMEOUT;
1340 if (tvp) {
1341 time_t sec, usec;
1343 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1344 || (ret = __get_user(sec, &tvp->tv_sec))
1345 || (ret = __get_user(usec, &tvp->tv_usec)))
1346 goto out_nofds;
1348 ret = -EINVAL;
1349 if(sec < 0 || usec < 0)
1350 goto out_nofds;
1352 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1353 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1354 timeout += sec * (unsigned long) HZ;
1358 ret = -EINVAL;
1359 if (n < 0)
1360 goto out_nofds;
1361 if (n > current->files->max_fdset)
1362 n = current->files->max_fdset;
1365 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1366 * since we used fdset we need to allocate memory in units of
1367 * long-words.
1369 ret = -ENOMEM;
1370 size = FDS_BYTES(n);
1371 bits = kmalloc(6 * size, GFP_KERNEL);
1372 if (!bits)
1373 goto out_nofds;
1374 fds.in = (unsigned long *) bits;
1375 fds.out = (unsigned long *) (bits + size);
1376 fds.ex = (unsigned long *) (bits + 2*size);
1377 fds.res_in = (unsigned long *) (bits + 3*size);
1378 fds.res_out = (unsigned long *) (bits + 4*size);
1379 fds.res_ex = (unsigned long *) (bits + 5*size);
1381 nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1382 if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1383 (ret = get_fd_set32(nn, fds.out, outp)) ||
1384 (ret = get_fd_set32(nn, fds.ex, exp)))
1385 goto out;
1386 zero_fd_set(n, fds.res_in);
1387 zero_fd_set(n, fds.res_out);
1388 zero_fd_set(n, fds.res_ex);
1390 ret = do_select(n, &fds, &timeout);
1392 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1393 time_t sec = 0, usec = 0;
1394 if (timeout) {
1395 sec = timeout / HZ;
1396 usec = timeout % HZ;
1397 usec *= (1000000/HZ);
1399 put_user(sec, &tvp->tv_sec);
1400 put_user(usec, &tvp->tv_usec);
1403 if (ret < 0)
1404 goto out;
1405 if (!ret) {
1406 ret = -ERESTARTNOHAND;
1407 if (signal_pending(current))
1408 goto out;
1409 ret = 0;
1412 set_fd_set32(nn, inp, fds.res_in);
1413 set_fd_set32(nn, outp, fds.res_out);
1414 set_fd_set32(nn, exp, fds.res_ex);
1416 out:
1417 kfree(bits);
1418 out_nofds:
1419 return ret;
1422 static int cp_new_stat32(struct kstat *stat, struct stat32 *statbuf)
1424 int err;
1426 err = put_user(stat->dev, &statbuf->st_dev);
1427 err |= put_user(stat->ino, &statbuf->st_ino);
1428 err |= put_user(stat->mode, &statbuf->st_mode);
1429 err |= put_user(stat->nlink, &statbuf->st_nlink);
1430 err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
1431 err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
1432 err |= put_user(stat->rdev, &statbuf->st_rdev);
1433 if (stat->size > MAX_NON_LFS)
1434 return -EOVERFLOW;
1435 err |= put_user(stat->size, &statbuf->st_size);
1436 err |= put_user(stat->atime, &statbuf->st_atime);
1437 err |= put_user(0, &statbuf->__unused1);
1438 err |= put_user(stat->mtime, &statbuf->st_mtime);
1439 err |= put_user(0, &statbuf->__unused2);
1440 err |= put_user(stat->ctime, &statbuf->st_ctime);
1441 err |= put_user(0, &statbuf->__unused3);
1442 err |= put_user(stat->blksize, &statbuf->st_blksize);
1443 err |= put_user(stat->blocks, &statbuf->st_blocks);
1444 err |= put_user(0, &statbuf->__unused4[0]);
1445 err |= put_user(0, &statbuf->__unused4[1]);
1447 return err;
1450 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1452 struct kstat stat;
1453 int error = vfs_stat(filename, &stat);
1455 if (!error)
1456 error = cp_new_stat32(&stat, statbuf);
1458 return error;
1461 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1463 struct kstat stat;
1464 int error = vfs_lstat(filename, &stat);
1466 if (!error)
1467 error = cp_new_stat32(&stat, statbuf);
1469 return error;
1472 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1474 struct kstat stat;
1475 int error = vfs_fstat(fd, &stat);
1477 if (!error)
1478 error = cp_new_stat32(&stat, statbuf);
1480 return error;
1483 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1485 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1487 return sys_sysfs(option, arg1, arg2);
1490 struct ncp_mount_data32_v3 {
1491 int version;
1492 unsigned int ncp_fd;
1493 __kernel_uid_t32 mounted_uid;
1494 __kernel_pid_t32 wdog_pid;
1495 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1496 unsigned int time_out;
1497 unsigned int retry_count;
1498 unsigned int flags;
1499 __kernel_uid_t32 uid;
1500 __kernel_gid_t32 gid;
1501 __kernel_mode_t32 file_mode;
1502 __kernel_mode_t32 dir_mode;
1505 struct ncp_mount_data32_v4 {
1506 int version;
1507 /* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
1508 unsigned int flags;
1509 unsigned int mounted_uid;
1510 int wdog_pid;
1512 unsigned int ncp_fd;
1513 unsigned int time_out;
1514 unsigned int retry_count;
1516 unsigned int uid;
1517 unsigned int gid;
1518 unsigned int file_mode;
1519 unsigned int dir_mode;
1522 static void *do_ncp_super_data_conv(void *raw_data)
1524 switch (*(int*)raw_data) {
1525 case NCP_MOUNT_VERSION:
1527 struct ncp_mount_data news, *n = &news;
1528 struct ncp_mount_data32_v3 *n32 = (struct ncp_mount_data32_v3 *)raw_data;
1530 n->version = n32->version;
1531 n->ncp_fd = n32->ncp_fd;
1532 n->mounted_uid = low2highuid(n32->mounted_uid);
1533 n->wdog_pid = n32->wdog_pid;
1534 memmove (n->mounted_vol, n32->mounted_vol, sizeof (n32->mounted_vol));
1535 n->time_out = n32->time_out;
1536 n->retry_count = n32->retry_count;
1537 n->flags = n32->flags;
1538 n->uid = low2highuid(n32->uid);
1539 n->gid = low2highgid(n32->gid);
1540 n->file_mode = n32->file_mode;
1541 n->dir_mode = n32->dir_mode;
1542 memcpy(raw_data, n, sizeof(*n));
1544 break;
1545 case NCP_MOUNT_VERSION_V4:
1547 struct ncp_mount_data_v4 news, *n = &news;
1548 struct ncp_mount_data32_v4 *n32 = (struct ncp_mount_data32_v4 *)raw_data;
1550 n->version = n32->version;
1551 n->flags = n32->flags;
1552 n->mounted_uid = n32->mounted_uid;
1553 n->wdog_pid = n32->wdog_pid;
1554 n->ncp_fd = n32->ncp_fd;
1555 n->time_out = n32->time_out;
1556 n->retry_count = n32->retry_count;
1557 n->uid = n32->uid;
1558 n->gid = n32->gid;
1559 n->file_mode = n32->file_mode;
1560 n->dir_mode = n32->dir_mode;
1561 memcpy(raw_data, n, sizeof(*n));
1563 break;
1564 default:
1565 /* do not touch unknown structures */
1566 break;
1568 return raw_data;
1571 struct smb_mount_data32 {
1572 int version;
1573 __kernel_uid_t32 mounted_uid;
1574 __kernel_uid_t32 uid;
1575 __kernel_gid_t32 gid;
1576 __kernel_mode_t32 file_mode;
1577 __kernel_mode_t32 dir_mode;
1580 static void *do_smb_super_data_conv(void *raw_data)
1582 struct smb_mount_data news, *s = &news;
1583 struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1585 if (s32->version != SMB_MOUNT_OLDVERSION)
1586 goto out;
1587 s->version = s32->version;
1588 s->mounted_uid = low2highuid(s32->mounted_uid);
1589 s->uid = low2highuid(s32->uid);
1590 s->gid = low2highgid(s32->gid);
1591 s->file_mode = s32->file_mode;
1592 s->dir_mode = s32->dir_mode;
1593 memcpy(raw_data, s, sizeof(struct smb_mount_data));
1594 out:
1595 return raw_data;
1598 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1600 int i;
1601 unsigned long page;
1602 struct vm_area_struct *vma;
1604 *kernel = 0;
1605 if(!user)
1606 return 0;
1607 vma = find_vma(current->mm, (unsigned long)user);
1608 if(!vma || (unsigned long)user < vma->vm_start)
1609 return -EFAULT;
1610 if(!(vma->vm_flags & VM_READ))
1611 return -EFAULT;
1612 i = vma->vm_end - (unsigned long) user;
1613 if(PAGE_SIZE <= (unsigned long) i)
1614 i = PAGE_SIZE - 1;
1615 if(!(page = __get_free_page(GFP_KERNEL)))
1616 return -ENOMEM;
1617 if(copy_from_user((void *) page, user, i)) {
1618 free_page(page);
1619 return -EFAULT;
1621 *kernel = page;
1622 return 0;
1625 #define SMBFS_NAME "smbfs"
1626 #define NCPFS_NAME "ncpfs"
1628 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1630 unsigned long type_page = 0;
1631 unsigned long data_page = 0;
1632 unsigned long dev_page = 0;
1633 unsigned long dir_page = 0;
1634 int err, is_smb, is_ncp;
1636 is_smb = is_ncp = 0;
1638 err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1639 if (err)
1640 goto out;
1642 if (!type_page) {
1643 err = -EINVAL;
1644 goto out;
1647 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1648 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1650 err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1651 if (err)
1652 goto type_out;
1654 err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1655 if (err)
1656 goto data_out;
1658 err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1659 if (err)
1660 goto dev_out;
1662 if (!is_smb && !is_ncp) {
1663 lock_kernel();
1664 err = do_mount((char*)dev_page, (char*)dir_page,
1665 (char*)type_page, new_flags, (char*)data_page);
1666 unlock_kernel();
1667 } else {
1668 if (is_ncp)
1669 do_ncp_super_data_conv((void *)data_page);
1670 else
1671 do_smb_super_data_conv((void *)data_page);
1673 lock_kernel();
1674 err = do_mount((char*)dev_page, (char*)dir_page,
1675 (char*)type_page, new_flags, (char*)data_page);
1676 unlock_kernel();
1678 free_page(dir_page);
1680 dev_out:
1681 free_page(dev_page);
1683 data_out:
1684 free_page(data_page);
1686 type_out:
1687 free_page(type_page);
1689 out:
1690 return err;
1693 struct rusage32 {
1694 struct timeval32 ru_utime;
1695 struct timeval32 ru_stime;
1696 s32 ru_maxrss;
1697 s32 ru_ixrss;
1698 s32 ru_idrss;
1699 s32 ru_isrss;
1700 s32 ru_minflt;
1701 s32 ru_majflt;
1702 s32 ru_nswap;
1703 s32 ru_inblock;
1704 s32 ru_oublock;
1705 s32 ru_msgsnd;
1706 s32 ru_msgrcv;
1707 s32 ru_nsignals;
1708 s32 ru_nvcsw;
1709 s32 ru_nivcsw;
1712 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1714 int err;
1716 err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1717 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1718 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1719 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1720 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1721 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1722 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1723 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1724 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1725 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1726 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1727 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1728 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1729 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1730 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1731 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1732 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1733 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1734 return err;
1737 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1739 if (!ru)
1740 return sys_wait4(pid, stat_addr, options, NULL);
1741 else {
1742 struct rusage r;
1743 int ret;
1744 unsigned int status;
1745 mm_segment_t old_fs = get_fs();
1747 set_fs (KERNEL_DS);
1748 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1749 set_fs (old_fs);
1750 if (put_rusage (ru, &r)) return -EFAULT;
1751 if (stat_addr && put_user (status, stat_addr))
1752 return -EFAULT;
1753 return ret;
1757 struct sysinfo32 {
1758 s32 uptime;
1759 u32 loads[3];
1760 u32 totalram;
1761 u32 freeram;
1762 u32 sharedram;
1763 u32 bufferram;
1764 u32 totalswap;
1765 u32 freeswap;
1766 unsigned short procs;
1767 char _f[22];
1770 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1772 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1774 struct sysinfo s;
1775 int ret, err;
1776 mm_segment_t old_fs = get_fs ();
1778 set_fs (KERNEL_DS);
1779 ret = sys_sysinfo(&s);
1780 set_fs (old_fs);
1781 err = put_user (s.uptime, &info->uptime);
1782 err |= __put_user (s.loads[0], &info->loads[0]);
1783 err |= __put_user (s.loads[1], &info->loads[1]);
1784 err |= __put_user (s.loads[2], &info->loads[2]);
1785 err |= __put_user (s.totalram, &info->totalram);
1786 err |= __put_user (s.freeram, &info->freeram);
1787 err |= __put_user (s.sharedram, &info->sharedram);
1788 err |= __put_user (s.bufferram, &info->bufferram);
1789 err |= __put_user (s.totalswap, &info->totalswap);
1790 err |= __put_user (s.freeswap, &info->freeswap);
1791 err |= __put_user (s.procs, &info->procs);
1792 if (err)
1793 return -EFAULT;
1794 return ret;
1797 struct timespec32 {
1798 s32 tv_sec;
1799 s32 tv_nsec;
1802 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1804 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1806 struct timespec t;
1807 int ret;
1808 mm_segment_t old_fs = get_fs ();
1810 set_fs (KERNEL_DS);
1811 ret = sys_sched_rr_get_interval(pid, &t);
1812 set_fs (old_fs);
1813 if (put_user (t.tv_sec, &interval->tv_sec) ||
1814 __put_user (t.tv_nsec, &interval->tv_nsec))
1815 return -EFAULT;
1816 return ret;
1819 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1821 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1823 struct timespec t;
1824 int ret;
1825 mm_segment_t old_fs = get_fs ();
1827 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1828 __get_user (t.tv_nsec, &rqtp->tv_nsec))
1829 return -EFAULT;
1830 set_fs (KERNEL_DS);
1831 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1832 set_fs (old_fs);
1833 if (rmtp && ret == -EINTR) {
1834 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1835 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1836 return -EFAULT;
1838 return ret;
1841 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1843 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1845 old_sigset_t s;
1846 int ret;
1847 mm_segment_t old_fs = get_fs();
1849 if (set && get_user (s, set)) return -EFAULT;
1850 set_fs (KERNEL_DS);
1851 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1852 set_fs (old_fs);
1853 if (ret) return ret;
1854 if (oset && put_user (s, oset)) return -EFAULT;
1855 return 0;
1858 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
1860 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
1862 sigset_t s;
1863 sigset_t32 s32;
1864 int ret;
1865 mm_segment_t old_fs = get_fs();
1867 if (set) {
1868 if (copy_from_user (&s32, set, sizeof(sigset_t32)))
1869 return -EFAULT;
1870 switch (_NSIG_WORDS) {
1871 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
1872 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
1873 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1874 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1877 set_fs (KERNEL_DS);
1878 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
1879 set_fs (old_fs);
1880 if (ret) return ret;
1881 if (oset) {
1882 switch (_NSIG_WORDS) {
1883 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1884 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1885 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1886 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1888 if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
1889 return -EFAULT;
1891 return 0;
1894 extern asmlinkage int sys_sigpending(old_sigset_t *set);
1896 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
1898 old_sigset_t s;
1899 int ret;
1900 mm_segment_t old_fs = get_fs();
1902 set_fs (KERNEL_DS);
1903 ret = sys_sigpending(&s);
1904 set_fs (old_fs);
1905 if (put_user (s, set)) return -EFAULT;
1906 return ret;
1909 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
1911 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
1913 sigset_t s;
1914 sigset_t32 s32;
1915 int ret;
1916 mm_segment_t old_fs = get_fs();
1918 set_fs (KERNEL_DS);
1919 ret = sys_rt_sigpending(&s, sigsetsize);
1920 set_fs (old_fs);
1921 if (!ret) {
1922 switch (_NSIG_WORDS) {
1923 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1924 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1925 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1926 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1928 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
1929 return -EFAULT;
1931 return ret;
1934 asmlinkage int
1935 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
1936 struct timespec32 *uts, __kernel_size_t32 sigsetsize)
1938 int ret, sig;
1939 sigset_t these;
1940 sigset_t32 these32;
1941 struct timespec ts;
1942 siginfo_t info;
1943 long timeout = 0;
1945 /* XXX: Don't preclude handling different sized sigset_t's. */
1946 if (sigsetsize != sizeof(sigset_t))
1947 return -EINVAL;
1949 if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
1950 return -EFAULT;
1952 switch (_NSIG_WORDS) {
1953 case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
1954 case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
1955 case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
1956 case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
1960 * Invert the set of allowed signals to get those we
1961 * want to block.
1963 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
1964 signotset(&these);
1966 if (uts) {
1967 if (get_user (ts.tv_sec, &uts->tv_sec) ||
1968 get_user (ts.tv_nsec, &uts->tv_nsec))
1969 return -EINVAL;
1970 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
1971 || ts.tv_sec < 0)
1972 return -EINVAL;
1975 spin_lock_irq(&current->sig->siglock);
1976 sig = dequeue_signal(&these, &info);
1977 if (!sig) {
1978 timeout = MAX_SCHEDULE_TIMEOUT;
1979 if (uts)
1980 timeout = (timespec_to_jiffies(&ts)
1981 + (ts.tv_sec || ts.tv_nsec));
1983 if (timeout) {
1984 /* None ready -- temporarily unblock those we're
1985 * interested while we are sleeping in so that we'll
1986 * be awakened when they arrive. */
1987 current->real_blocked = current->blocked;
1988 sigandsets(&current->blocked, &current->blocked, &these);
1989 recalc_sigpending();
1990 spin_unlock_irq(&current->sig->siglock);
1992 current->state = TASK_INTERRUPTIBLE;
1993 timeout = schedule_timeout(timeout);
1995 spin_lock_irq(&current->sig->siglock);
1996 sig = dequeue_signal(&these, &info);
1997 current->blocked = current->real_blocked;
1998 siginitset(&current->real_blocked, 0);
1999 recalc_sigpending();
2002 spin_unlock_irq(&current->sig->siglock);
2004 if (sig) {
2005 ret = sig;
2006 if (uinfo) {
2007 if (copy_siginfo_to_user32(uinfo, &info))
2008 ret = -EFAULT;
2010 } else {
2011 ret = -EAGAIN;
2012 if (timeout)
2013 ret = -EINTR;
2016 return ret;
2019 extern asmlinkage int
2020 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2022 asmlinkage int
2023 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2025 siginfo_t info;
2026 int ret;
2027 mm_segment_t old_fs = get_fs();
2029 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2030 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2031 return -EFAULT;
2032 set_fs (KERNEL_DS);
2033 ret = sys_rt_sigqueueinfo(pid, sig, &info);
2034 set_fs (old_fs);
2035 return ret;
2038 struct tms32 {
2039 __kernel_clock_t32 tms_utime;
2040 __kernel_clock_t32 tms_stime;
2041 __kernel_clock_t32 tms_cutime;
2042 __kernel_clock_t32 tms_cstime;
2045 extern asmlinkage long sys_times(struct tms * tbuf);
2047 asmlinkage long sys32_times(struct tms32 *tbuf)
2049 struct tms t;
2050 long ret;
2051 mm_segment_t old_fs = get_fs ();
2052 int err;
2054 set_fs (KERNEL_DS);
2055 ret = sys_times(tbuf ? &t : NULL);
2056 set_fs (old_fs);
2057 if (tbuf) {
2058 err = put_user (t.tms_utime, &tbuf->tms_utime);
2059 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2060 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2061 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2062 if (err)
2063 ret = -EFAULT;
2065 return ret;
2068 #define RLIM_INFINITY32 0x7fffffff
2069 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2071 struct rlimit32 {
2072 u32 rlim_cur;
2073 u32 rlim_max;
2076 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2078 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2080 struct rlimit r;
2081 int ret;
2082 mm_segment_t old_fs = get_fs ();
2084 set_fs (KERNEL_DS);
2085 ret = sys_getrlimit(resource, &r);
2086 set_fs (old_fs);
2087 if (!ret) {
2088 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2089 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2091 return ret;
2094 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2096 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2098 struct rlimit r;
2099 int ret;
2100 mm_segment_t old_fs = get_fs ();
2102 if (resource >= RLIM_NLIMITS) return -EINVAL;
2103 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2104 __get_user (r.rlim_max, &rlim->rlim_max))
2105 return -EFAULT;
2106 if (r.rlim_cur == RLIM_INFINITY32)
2107 r.rlim_cur = RLIM_INFINITY;
2108 if (r.rlim_max == RLIM_INFINITY32)
2109 r.rlim_max = RLIM_INFINITY;
2110 set_fs (KERNEL_DS);
2111 ret = sys_setrlimit(resource, &r);
2112 set_fs (old_fs);
2113 return ret;
2116 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2118 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2120 struct rusage r;
2121 int ret;
2122 mm_segment_t old_fs = get_fs();
2124 set_fs (KERNEL_DS);
2125 ret = sys_getrusage(who, &r);
2126 set_fs (old_fs);
2127 if (put_rusage (ru, &r)) return -EFAULT;
2128 return ret;
2131 /* XXX This really belongs in some header file... -DaveM */
2132 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2133 16 for IP, 16 for IPX,
2134 24 for IPv6,
2135 about 80 for AX.25 */
2137 struct msghdr32 {
2138 u32 msg_name;
2139 int msg_namelen;
2140 u32 msg_iov;
2141 __kernel_size_t32 msg_iovlen;
2142 u32 msg_control;
2143 __kernel_size_t32 msg_controllen;
2144 unsigned msg_flags;
2147 struct cmsghdr32 {
2148 __kernel_size_t32 cmsg_len;
2149 int cmsg_level;
2150 int cmsg_type;
2153 /* Bleech... */
2154 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2155 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2157 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2159 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2160 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2161 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2163 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2164 (struct cmsghdr32 *)(ctl) : \
2165 (struct cmsghdr32 *)NULL)
2166 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2168 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2169 struct cmsghdr32 *__cmsg, int __cmsg_len)
2171 struct cmsghdr32 * __ptr;
2173 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2174 CMSG32_ALIGN(__cmsg_len));
2175 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2176 return NULL;
2178 return __ptr;
2181 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2182 struct cmsghdr32 *__cmsg,
2183 int __cmsg_len)
2185 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2186 __cmsg, __cmsg_len);
2189 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2190 struct iovec32 *uiov32,
2191 int niov)
2193 int tot_len = 0;
2195 while(niov > 0) {
2196 u32 len, buf;
2198 if(get_user(len, &uiov32->iov_len) ||
2199 get_user(buf, &uiov32->iov_base)) {
2200 tot_len = -EFAULT;
2201 break;
2203 tot_len += len;
2204 kiov->iov_base = (void *)A(buf);
2205 kiov->iov_len = (__kernel_size_t) len;
2206 uiov32++;
2207 kiov++;
2208 niov--;
2210 return tot_len;
2213 static int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2214 struct msghdr32 *umsg)
2216 u32 tmp1, tmp2, tmp3;
2217 int err;
2219 err = get_user(tmp1, &umsg->msg_name);
2220 err |= __get_user(tmp2, &umsg->msg_iov);
2221 err |= __get_user(tmp3, &umsg->msg_control);
2222 if (err)
2223 return -EFAULT;
2225 kmsg->msg_name = (void *)A(tmp1);
2226 kmsg->msg_iov = (struct iovec *)A(tmp2);
2227 kmsg->msg_control = (void *)A(tmp3);
2229 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2230 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2231 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2232 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2234 return err;
2237 /* I've named the args so it is easy to tell whose space the pointers are in. */
2238 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2239 char *kern_address, int mode)
2241 int tot_len;
2243 if(kern_msg->msg_namelen) {
2244 if(mode==VERIFY_READ) {
2245 int err = move_addr_to_kernel(kern_msg->msg_name,
2246 kern_msg->msg_namelen,
2247 kern_address);
2248 if(err < 0)
2249 return err;
2251 kern_msg->msg_name = kern_address;
2252 } else
2253 kern_msg->msg_name = NULL;
2255 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2256 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2257 GFP_KERNEL);
2258 if(!kern_iov)
2259 return -ENOMEM;
2262 tot_len = iov_from_user32_to_kern(kern_iov,
2263 (struct iovec32 *)kern_msg->msg_iov,
2264 kern_msg->msg_iovlen);
2265 if(tot_len >= 0)
2266 kern_msg->msg_iov = kern_iov;
2267 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2268 kfree(kern_iov);
2270 return tot_len;
2273 /* There is a lot of hair here because the alignment rules (and
2274 * thus placement) of cmsg headers and length are different for
2275 * 32-bit apps. -DaveM
2277 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2278 unsigned char *stackbuf, int stackbuf_size)
2280 struct cmsghdr32 *ucmsg;
2281 struct cmsghdr *kcmsg, *kcmsg_base;
2282 __kernel_size_t32 ucmlen;
2283 __kernel_size_t kcmlen, tmp;
2285 kcmlen = 0;
2286 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2287 ucmsg = CMSG32_FIRSTHDR(kmsg);
2288 while(ucmsg != NULL) {
2289 if(get_user(ucmlen, &ucmsg->cmsg_len))
2290 return -EFAULT;
2292 /* Catch bogons. */
2293 if(CMSG32_ALIGN(ucmlen) <
2294 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2295 return -EINVAL;
2296 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2297 + ucmlen) > kmsg->msg_controllen)
2298 return -EINVAL;
2300 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2301 CMSG_ALIGN(sizeof(struct cmsghdr)));
2302 kcmlen += tmp;
2303 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2305 if(kcmlen == 0)
2306 return -EINVAL;
2308 /* The kcmlen holds the 64-bit version of the control length.
2309 * It may not be modified as we do not stick it into the kmsg
2310 * until we have successfully copied over all of the data
2311 * from the user.
2313 if(kcmlen > stackbuf_size)
2314 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2315 if(kcmsg == NULL)
2316 return -ENOBUFS;
2318 /* Now copy them over neatly. */
2319 memset(kcmsg, 0, kcmlen);
2320 ucmsg = CMSG32_FIRSTHDR(kmsg);
2321 while(ucmsg != NULL) {
2322 __get_user(ucmlen, &ucmsg->cmsg_len);
2323 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2324 CMSG_ALIGN(sizeof(struct cmsghdr)));
2325 kcmsg->cmsg_len = tmp;
2326 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2327 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2329 /* Copy over the data. */
2330 if(copy_from_user(CMSG_DATA(kcmsg),
2331 CMSG32_DATA(ucmsg),
2332 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2333 goto out_free_efault;
2335 /* Advance. */
2336 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2337 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2340 /* Ok, looks like we made it. Hook it up and return success. */
2341 kmsg->msg_control = kcmsg_base;
2342 kmsg->msg_controllen = kcmlen;
2343 return 0;
2345 out_free_efault:
2346 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2347 kfree(kcmsg_base);
2348 return -EFAULT;
2351 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2352 int len, void *data)
2354 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2355 struct cmsghdr32 cmhdr;
2356 int cmlen = CMSG32_LEN(len);
2358 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2359 kmsg->msg_flags |= MSG_CTRUNC;
2360 return;
2363 if(kmsg->msg_controllen < cmlen) {
2364 kmsg->msg_flags |= MSG_CTRUNC;
2365 cmlen = kmsg->msg_controllen;
2367 cmhdr.cmsg_level = level;
2368 cmhdr.cmsg_type = type;
2369 cmhdr.cmsg_len = cmlen;
2371 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2372 return;
2373 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2374 return;
2375 cmlen = CMSG32_SPACE(len);
2376 kmsg->msg_control += cmlen;
2377 kmsg->msg_controllen -= cmlen;
2380 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2382 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2383 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2384 int fdnum = scm->fp->count;
2385 struct file **fp = scm->fp->fp;
2386 int *cmfptr;
2387 int err = 0, i;
2389 if (fdnum < fdmax)
2390 fdmax = fdnum;
2392 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2393 int new_fd;
2394 err = get_unused_fd();
2395 if (err < 0)
2396 break;
2397 new_fd = err;
2398 err = put_user(new_fd, cmfptr);
2399 if (err) {
2400 put_unused_fd(new_fd);
2401 break;
2403 /* Bump the usage count and install the file. */
2404 get_file(fp[i]);
2405 fd_install(new_fd, fp[i]);
2408 if (i > 0) {
2409 int cmlen = CMSG32_LEN(i * sizeof(int));
2410 if (!err)
2411 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2412 if (!err)
2413 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2414 if (!err)
2415 err = put_user(cmlen, &cm->cmsg_len);
2416 if (!err) {
2417 cmlen = CMSG32_SPACE(i * sizeof(int));
2418 kmsg->msg_control += cmlen;
2419 kmsg->msg_controllen -= cmlen;
2422 if (i < fdnum)
2423 kmsg->msg_flags |= MSG_CTRUNC;
2426 * All of the files that fit in the message have had their
2427 * usage counts incremented, so we just free the list.
2429 __scm_destroy(scm);
2432 /* In these cases we (currently) can just copy to data over verbatim
2433 * because all CMSGs created by the kernel have well defined types which
2434 * have the same layout in both the 32-bit and 64-bit API. One must add
2435 * some special cased conversions here if we start sending control messages
2436 * with incompatible types.
2438 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2439 * we do our work. The remaining cases are:
2441 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2442 * IP_TTL int 32-bit clean
2443 * IP_TOS __u8 32-bit clean
2444 * IP_RECVOPTS variable length 32-bit clean
2445 * IP_RETOPTS variable length 32-bit clean
2446 * (these last two are clean because the types are defined
2447 * by the IPv4 protocol)
2448 * IP_RECVERR struct sock_extended_err +
2449 * struct sockaddr_in 32-bit clean
2450 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2451 * struct sockaddr_in6 32-bit clean
2452 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2453 * IPV6_HOPLIMIT int 32-bit clean
2454 * IPV6_FLOWINFO u32 32-bit clean
2455 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2456 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2457 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2458 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2460 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2462 unsigned char *workbuf, *wp;
2463 unsigned long bufsz, space_avail;
2464 struct cmsghdr *ucmsg;
2466 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2467 space_avail = kmsg->msg_controllen + bufsz;
2468 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2469 if(workbuf == NULL)
2470 goto fail;
2472 /* To make this more sane we assume the kernel sends back properly
2473 * formatted control messages. Because of how the kernel will truncate
2474 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2476 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2477 while(((unsigned long)ucmsg) <=
2478 (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2479 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2480 int clen64, clen32;
2482 /* UCMSG is the 64-bit format CMSG entry in user-space.
2483 * KCMSG32 is within the kernel space temporary buffer
2484 * we use to convert into a 32-bit style CMSG.
2486 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2487 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2488 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2490 clen64 = kcmsg32->cmsg_len;
2491 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2492 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2493 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2494 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2495 kcmsg32->cmsg_len = clen32;
2497 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2498 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2501 /* Copy back fixed up data, and adjust pointers. */
2502 bufsz = (wp - workbuf);
2503 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2505 kmsg->msg_control = (struct cmsghdr *)
2506 (((char *)orig_cmsg_uptr) + bufsz);
2507 kmsg->msg_controllen = space_avail - bufsz;
2509 kfree(workbuf);
2510 return;
2512 fail:
2513 /* If we leave the 64-bit format CMSG chunks in there,
2514 * the application could get confused and crash. So to
2515 * ensure greater recovery, we report no CMSGs.
2517 kmsg->msg_controllen += bufsz;
2518 kmsg->msg_control = (void *) orig_cmsg_uptr;
2521 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2523 struct socket *sock;
2524 char address[MAX_SOCK_ADDR];
2525 struct iovec iov[UIO_FASTIOV];
2526 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2527 unsigned char *ctl_buf = ctl;
2528 struct msghdr kern_msg;
2529 int err, total_len;
2531 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2532 return -EFAULT;
2533 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2534 return -EINVAL;
2535 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2536 if (err < 0)
2537 goto out;
2538 total_len = err;
2540 if(kern_msg.msg_controllen) {
2541 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2542 if(err)
2543 goto out_freeiov;
2544 ctl_buf = kern_msg.msg_control;
2546 kern_msg.msg_flags = user_flags;
2548 sock = sockfd_lookup(fd, &err);
2549 if (sock != NULL) {
2550 if (sock->file->f_flags & O_NONBLOCK)
2551 kern_msg.msg_flags |= MSG_DONTWAIT;
2552 err = sock_sendmsg(sock, &kern_msg, total_len);
2553 sockfd_put(sock);
2556 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2557 if(ctl_buf != ctl)
2558 kfree(ctl_buf);
2559 out_freeiov:
2560 if(kern_msg.msg_iov != iov)
2561 kfree(kern_msg.msg_iov);
2562 out:
2563 return err;
2566 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2568 struct iovec iovstack[UIO_FASTIOV];
2569 struct msghdr kern_msg;
2570 char addr[MAX_SOCK_ADDR];
2571 struct socket *sock;
2572 struct iovec *iov = iovstack;
2573 struct sockaddr *uaddr;
2574 int *uaddr_len;
2575 unsigned long cmsg_ptr;
2576 int err, total_len, len = 0;
2578 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2579 return -EFAULT;
2580 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2581 return -EINVAL;
2583 uaddr = kern_msg.msg_name;
2584 uaddr_len = &user_msg->msg_namelen;
2585 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2586 if (err < 0)
2587 goto out;
2588 total_len = err;
2590 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2591 kern_msg.msg_flags = 0;
2593 sock = sockfd_lookup(fd, &err);
2594 if (sock != NULL) {
2595 struct sock_iocb *si;
2596 struct kiocb iocb;
2598 if (sock->file->f_flags & O_NONBLOCK)
2599 user_flags |= MSG_DONTWAIT;
2601 init_sync_kiocb(&iocb, NULL);
2602 si = kiocb_to_siocb(&iocb);
2603 si->sock = sock;
2604 si->scm = &si->async_scm;
2605 si->msg = &kern_msg;
2606 si->size = total_len;
2607 si->flags = user_flags;
2608 memset(si->scm, 0, sizeof(*si->scm));
2610 err = sock->ops->recvmsg(&iocb, sock, &kern_msg, total_len,
2611 user_flags, si->scm);
2612 if (-EIOCBQUEUED == err)
2613 err = wait_on_sync_kiocb(&iocb);
2615 if(err >= 0) {
2616 len = err;
2617 if(!kern_msg.msg_control) {
2618 if(sock->passcred || si->scm->fp)
2619 kern_msg.msg_flags |= MSG_CTRUNC;
2620 if(si->scm->fp)
2621 __scm_destroy(si->scm);
2622 } else {
2623 /* If recvmsg processing itself placed some
2624 * control messages into user space, it's is
2625 * using 64-bit CMSG processing, so we need
2626 * to fix it up before we tack on more stuff.
2628 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2629 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2631 /* Wheee... */
2632 if(sock->passcred)
2633 put_cmsg32(&kern_msg,
2634 SOL_SOCKET, SCM_CREDENTIALS,
2635 sizeof(si->scm->creds),
2636 &si->scm->creds);
2637 if(si->scm->fp != NULL)
2638 scm_detach_fds32(&kern_msg, si->scm);
2641 sockfd_put(sock);
2644 if(uaddr != NULL && err >= 0)
2645 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2646 if(cmsg_ptr != 0 && err >= 0) {
2647 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2648 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2649 err |= __put_user(uclen, &user_msg->msg_controllen);
2651 if(err >= 0)
2652 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2653 if(kern_msg.msg_iov != iov)
2654 kfree(kern_msg.msg_iov);
2655 out:
2656 if(err < 0)
2657 return err;
2658 return len;
2661 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2662 char *optval, int optlen);
2664 static int do_set_attach_filter(int fd, int level, int optname,
2665 char *optval, int optlen)
2667 struct sock_fprog32 {
2668 __u16 len;
2669 __u32 filter;
2670 } *fprog32 = (struct sock_fprog32 *)optval;
2671 struct sock_fprog kfprog;
2672 struct sock_filter *kfilter;
2673 unsigned int fsize;
2674 mm_segment_t old_fs;
2675 __u32 uptr;
2676 int ret;
2678 if (get_user(kfprog.len, &fprog32->len) ||
2679 __get_user(uptr, &fprog32->filter))
2680 return -EFAULT;
2682 kfprog.filter = (struct sock_filter *)A(uptr);
2683 fsize = kfprog.len * sizeof(struct sock_filter);
2685 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2686 if (kfilter == NULL)
2687 return -ENOMEM;
2689 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2690 kfree(kfilter);
2691 return -EFAULT;
2694 kfprog.filter = kfilter;
2696 old_fs = get_fs();
2697 set_fs(KERNEL_DS);
2698 ret = sys_setsockopt(fd, level, optname,
2699 (char *)&kfprog, sizeof(kfprog));
2700 set_fs(old_fs);
2702 kfree(kfilter);
2704 return ret;
2707 static int do_set_icmpv6_filter(int fd, int level, int optname,
2708 char *optval, int optlen)
2710 struct icmp6_filter kfilter;
2711 mm_segment_t old_fs;
2712 int ret, i;
2714 if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
2715 return -EFAULT;
2718 for (i = 0; i < 8; i += 2) {
2719 u32 tmp = kfilter.data[i];
2721 kfilter.data[i] = kfilter.data[i + 1];
2722 kfilter.data[i + 1] = tmp;
2725 old_fs = get_fs();
2726 set_fs(KERNEL_DS);
2727 ret = sys_setsockopt(fd, level, optname,
2728 (char *) &kfilter, sizeof(kfilter));
2729 set_fs(old_fs);
2731 return ret;
2734 static int do_set_sock_timeout(int fd, int level, int optname, char *optval, int optlen)
2736 struct timeval32 *up = (struct timeval32 *) optval;
2737 struct timeval ktime;
2738 mm_segment_t old_fs;
2739 int err;
2741 if (optlen < sizeof(*up))
2742 return -EINVAL;
2743 if (get_user(ktime.tv_sec, &up->tv_sec) ||
2744 __get_user(ktime.tv_usec, &up->tv_usec))
2745 return -EFAULT;
2746 old_fs = get_fs();
2747 set_fs(KERNEL_DS);
2748 err = sys_setsockopt(fd, level, optname, (char *) &ktime, sizeof(ktime));
2749 set_fs(old_fs);
2751 return err;
2754 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2755 char *optval, int optlen)
2757 if (optname == SO_ATTACH_FILTER)
2758 return do_set_attach_filter(fd, level, optname,
2759 optval, optlen);
2760 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
2761 return do_set_sock_timeout(fd, level, optname, optval, optlen);
2762 if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
2763 return do_set_icmpv6_filter(fd, level, optname,
2764 optval, optlen);
2766 return sys_setsockopt(fd, level, optname, optval, optlen);
2769 extern asmlinkage long sys_getsockopt(int fd, int level, int optname,
2770 char *optval, int *optlen);
2772 static int do_get_sock_timeout(int fd, int level, int optname, char *optval, int *optlen)
2774 struct timeval32 *up = (struct timeval32 *) optval;
2775 struct timeval ktime;
2776 mm_segment_t old_fs;
2777 int len, err;
2779 if (get_user(len, optlen))
2780 return -EFAULT;
2781 if (len < sizeof(*up))
2782 return -EINVAL;
2783 len = sizeof(ktime);
2784 old_fs = get_fs();
2785 set_fs(KERNEL_DS);
2786 err = sys_getsockopt(fd, level, optname, (char *) &ktime, &len);
2787 set_fs(old_fs);
2789 if (!err) {
2790 if (put_user(sizeof(*up), optlen) ||
2791 put_user(ktime.tv_sec, &up->tv_sec) ||
2792 __put_user(ktime.tv_usec, &up->tv_usec))
2793 err = -EFAULT;
2795 return err;
2798 asmlinkage int sys32_getsockopt(int fd, int level, int optname,
2799 char *optval, int *optlen)
2801 if (optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)
2802 return do_get_sock_timeout(fd, level, optname, optval, optlen);
2803 return sys_getsockopt(fd, level, optname, optval, optlen);
2806 extern void check_pending(int signum);
2808 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2810 struct k_sigaction new_ka, old_ka;
2811 int ret;
2813 if (sig < 0) {
2814 set_thread_flag(TIF_NEWSIGNALS);
2815 sig = -sig;
2818 if (act) {
2819 old_sigset_t32 mask;
2821 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2822 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2823 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2824 ret |= __get_user(mask, &act->sa_mask);
2825 if (ret)
2826 return ret;
2827 new_ka.ka_restorer = NULL;
2828 siginitset(&new_ka.sa.sa_mask, mask);
2831 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2833 if (!ret && oact) {
2834 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2835 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2836 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2837 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2840 return ret;
2843 asmlinkage int
2844 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2845 void *restorer, __kernel_size_t32 sigsetsize)
2847 struct k_sigaction new_ka, old_ka;
2848 int ret;
2849 sigset_t32 set32;
2851 /* XXX: Don't preclude handling different sized sigset_t's. */
2852 if (sigsetsize != sizeof(sigset_t32))
2853 return -EINVAL;
2855 /* All tasks which use RT signals (effectively) use
2856 * new style signals.
2858 set_thread_flag(TIF_NEWSIGNALS);
2860 if (act) {
2861 new_ka.ka_restorer = restorer;
2862 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2863 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2864 switch (_NSIG_WORDS) {
2865 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2866 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2867 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2868 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2870 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2871 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2872 if (ret)
2873 return -EFAULT;
2876 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2878 if (!ret && oact) {
2879 switch (_NSIG_WORDS) {
2880 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
2881 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
2882 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
2883 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
2885 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2886 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
2887 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2888 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2889 if (ret)
2890 ret = -EFAULT;
2893 return ret;
2898 * count32() counts the number of arguments/envelopes
2900 static int count32(u32 * argv, int max)
2902 int i = 0;
2904 if (argv != NULL) {
2905 for (;;) {
2906 u32 p; int error;
2908 error = get_user(p,argv);
2909 if (error)
2910 return error;
2911 if (!p)
2912 break;
2913 argv++;
2914 if (++i > max)
2915 return -E2BIG;
2918 return i;
2922 * 'copy_string32()' copies argument/envelope strings from user
2923 * memory to free pages in kernel mem. These are in a format ready
2924 * to be put directly into the top of new user memory.
2926 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
2928 while (argc-- > 0) {
2929 u32 str;
2930 int len;
2931 unsigned long pos;
2933 if (get_user(str, argv + argc) ||
2934 !str ||
2935 !(len = strnlen_user((char *)A(str), bprm->p)))
2936 return -EFAULT;
2938 if (bprm->p < len)
2939 return -E2BIG;
2941 bprm->p -= len;
2943 pos = bprm->p;
2944 while (len) {
2945 char *kaddr;
2946 struct page *page;
2947 int offset, bytes_to_copy, new, err;
2949 offset = pos % PAGE_SIZE;
2950 page = bprm->page[pos / PAGE_SIZE];
2951 new = 0;
2952 if (!page) {
2953 page = alloc_page(GFP_USER);
2954 bprm->page[pos / PAGE_SIZE] = page;
2955 if (!page)
2956 return -ENOMEM;
2957 new = 1;
2959 kaddr = kmap(page);
2961 if (new && offset)
2962 memset(kaddr, 0, offset);
2963 bytes_to_copy = PAGE_SIZE - offset;
2964 if (bytes_to_copy > len) {
2965 bytes_to_copy = len;
2966 if (new)
2967 memset(kaddr+offset+len, 0,
2968 PAGE_SIZE-offset-len);
2971 err = copy_from_user(kaddr + offset, (char *)A(str),
2972 bytes_to_copy);
2973 kunmap(page);
2975 if (err)
2976 return -EFAULT;
2978 pos += bytes_to_copy;
2979 str += bytes_to_copy;
2980 len -= bytes_to_copy;
2983 return 0;
2987 * sys32_execve() executes a new program.
2989 static inline int
2990 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
2992 struct linux_binprm bprm;
2993 struct file * file;
2994 int retval;
2995 int i;
2997 file = open_exec(filename);
2999 retval = PTR_ERR(file);
3000 if (IS_ERR(file))
3001 return retval;
3003 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3004 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3006 bprm.file = file;
3007 bprm.filename = filename;
3008 bprm.sh_bang = 0;
3009 bprm.loader = 0;
3010 bprm.exec = 0;
3011 bprm.security = NULL;
3012 bprm.mm = mm_alloc();
3013 retval = -ENOMEM;
3014 if (!bprm.mm)
3015 goto out_file;
3017 retval = init_new_context(current, bprm.mm);
3018 if (retval < 0)
3019 goto out_mm;
3021 bprm.argc = count32(argv, bprm.p / sizeof(u32));
3022 if ((retval = bprm.argc) < 0)
3023 goto out_mm;
3025 bprm.envc = count32(envp, bprm.p / sizeof(u32));
3026 if ((retval = bprm.envc) < 0)
3027 goto out_mm;
3029 retval = security_ops->bprm_alloc_security(&bprm);
3030 if (retval)
3031 goto out;
3033 retval = prepare_binprm(&bprm);
3034 if (retval < 0)
3035 goto out;
3037 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3038 if (retval < 0)
3039 goto out;
3041 bprm.exec = bprm.p;
3042 retval = copy_strings32(bprm.envc, envp, &bprm);
3043 if (retval < 0)
3044 goto out;
3046 retval = copy_strings32(bprm.argc, argv, &bprm);
3047 if (retval < 0)
3048 goto out;
3050 retval = search_binary_handler(&bprm, regs);
3051 if (retval >= 0) {
3052 /* execve success */
3053 security_ops->bprm_free_security(&bprm);
3054 return retval;
3057 out:
3058 /* Something went wrong, return the inode and free the argument pages*/
3059 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
3060 struct page * page = bprm.page[i];
3061 if (page)
3062 __free_page(page);
3065 if (bprm.security)
3066 security_ops->bprm_free_security(&bprm);
3068 out_mm:
3069 mmdrop(bprm.mm);
3071 out_file:
3072 if (bprm.file) {
3073 allow_write_access(bprm.file);
3074 fput(bprm.file);
3076 return retval;
3080 * sparc32_execve() executes a new program after the asm stub has set
3081 * things up for us. This should basically do what I want it to.
3083 asmlinkage int sparc32_execve(struct pt_regs *regs)
3085 int error, base = 0;
3086 char *filename;
3088 /* User register window flush is done by entry.S */
3090 /* Check for indirect call. */
3091 if((u32)regs->u_regs[UREG_G1] == 0)
3092 base = 1;
3094 filename = getname((char *)AA(regs->u_regs[base + UREG_I0]));
3095 error = PTR_ERR(filename);
3096 if(IS_ERR(filename))
3097 goto out;
3098 error = do_execve32(filename,
3099 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3100 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3101 putname(filename);
3103 if(!error) {
3104 fprs_write(0);
3105 current_thread_info()->xfsr[0] = 0;
3106 current_thread_info()->fpsaved[0] = 0;
3107 regs->tstate &= ~TSTATE_PEF;
3108 current->ptrace &= ~PT_DTRACE;
3110 out:
3111 return error;
3114 #ifdef CONFIG_MODULES
3116 extern asmlinkage long sys_init_module(void *, unsigned long, const char *);
3118 asmlinkage int sys32_init_module(void *umod, u32 len, const char *uargs)
3120 return sys_init_module(umod, len, uargs);
3123 extern asmlinkage long sys_delete_module(const char *, unsigned int);
3125 asmlinkage int sys32_delete_module(const char *name_user, unsigned int flags)
3127 return sys_delete_module(name_user, flags);
3130 #else /* CONFIG_MODULES */
3132 asmlinkage int
3133 sys32_init_module(const char *name_user, struct module *mod_user)
3135 return -ENOSYS;
3138 asmlinkage int
3139 sys32_delete_module(const char *name_user)
3141 return -ENOSYS;
3144 #endif /* CONFIG_MODULES */
3146 #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
3147 /* Stuff for NFS server syscalls... */
3148 struct nfsctl_svc32 {
3149 u16 svc32_port;
3150 s32 svc32_nthreads;
3153 struct nfsctl_client32 {
3154 s8 cl32_ident[NFSCLNT_IDMAX+1];
3155 s32 cl32_naddr;
3156 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3157 s32 cl32_fhkeytype;
3158 s32 cl32_fhkeylen;
3159 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3162 struct nfsctl_export32 {
3163 s8 ex32_client[NFSCLNT_IDMAX+1];
3164 s8 ex32_path[NFS_MAXPATHLEN+1];
3165 __kernel_dev_t32 ex32_dev;
3166 __kernel_ino_t32 ex32_ino;
3167 s32 ex32_flags;
3168 __kernel_uid_t32 ex32_anon_uid;
3169 __kernel_gid_t32 ex32_anon_gid;
3172 struct nfsctl_uidmap32 {
3173 u32 ug32_ident; /* char * */
3174 __kernel_uid_t32 ug32_uidbase;
3175 s32 ug32_uidlen;
3176 u32 ug32_udimap; /* uid_t * */
3177 __kernel_uid_t32 ug32_gidbase;
3178 s32 ug32_gidlen;
3179 u32 ug32_gdimap; /* gid_t * */
3182 struct nfsctl_fhparm32 {
3183 struct sockaddr gf32_addr;
3184 __kernel_dev_t32 gf32_dev;
3185 __kernel_ino_t32 gf32_ino;
3186 s32 gf32_version;
3189 struct nfsctl_fdparm32 {
3190 struct sockaddr gd32_addr;
3191 s8 gd32_path[NFS_MAXPATHLEN+1];
3192 s32 gd32_version;
3195 struct nfsctl_fsparm32 {
3196 struct sockaddr gd32_addr;
3197 s8 gd32_path[NFS_MAXPATHLEN+1];
3198 s32 gd32_maxlen;
3201 struct nfsctl_arg32 {
3202 s32 ca32_version; /* safeguard */
3203 union {
3204 struct nfsctl_svc32 u32_svc;
3205 struct nfsctl_client32 u32_client;
3206 struct nfsctl_export32 u32_export;
3207 struct nfsctl_uidmap32 u32_umap;
3208 struct nfsctl_fhparm32 u32_getfh;
3209 struct nfsctl_fdparm32 u32_getfd;
3210 struct nfsctl_fsparm32 u32_getfs;
3211 } u;
3212 #define ca32_svc u.u32_svc
3213 #define ca32_client u.u32_client
3214 #define ca32_export u.u32_export
3215 #define ca32_umap u.u32_umap
3216 #define ca32_getfh u.u32_getfh
3217 #define ca32_getfd u.u32_getfd
3218 #define ca32_getfs u.u32_getfs
3219 #define ca32_authd u.u32_authd
3222 union nfsctl_res32 {
3223 __u8 cr32_getfh[NFS_FHSIZE];
3224 struct knfsd_fh cr32_getfs;
3227 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3229 int err;
3231 err = __get_user(karg->ca_version, &arg32->ca32_version);
3232 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3233 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3234 return err;
3237 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3239 int err;
3241 err = __get_user(karg->ca_version, &arg32->ca32_version);
3242 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3243 &arg32->ca32_client.cl32_ident[0],
3244 NFSCLNT_IDMAX);
3245 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3246 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3247 &arg32->ca32_client.cl32_addrlist[0],
3248 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3249 err |= __get_user(karg->ca_client.cl_fhkeytype,
3250 &arg32->ca32_client.cl32_fhkeytype);
3251 err |= __get_user(karg->ca_client.cl_fhkeylen,
3252 &arg32->ca32_client.cl32_fhkeylen);
3253 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3254 &arg32->ca32_client.cl32_fhkey[0],
3255 NFSCLNT_KEYMAX);
3256 return (err ? -EFAULT : 0);
3259 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3261 int err;
3263 err = __get_user(karg->ca_version, &arg32->ca32_version);
3264 err |= copy_from_user(&karg->ca_export.ex_client[0],
3265 &arg32->ca32_export.ex32_client[0],
3266 NFSCLNT_IDMAX);
3267 err |= copy_from_user(&karg->ca_export.ex_path[0],
3268 &arg32->ca32_export.ex32_path[0],
3269 NFS_MAXPATHLEN);
3270 err |= __get_user(karg->ca_export.ex_dev,
3271 &arg32->ca32_export.ex32_dev);
3272 err |= __get_user(karg->ca_export.ex_ino,
3273 &arg32->ca32_export.ex32_ino);
3274 err |= __get_user(karg->ca_export.ex_flags,
3275 &arg32->ca32_export.ex32_flags);
3276 err |= __get_user(karg->ca_export.ex_anon_uid,
3277 &arg32->ca32_export.ex32_anon_uid);
3278 err |= __get_user(karg->ca_export.ex_anon_gid,
3279 &arg32->ca32_export.ex32_anon_gid);
3280 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3281 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3282 return (err ? -EFAULT : 0);
3285 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3287 u32 uaddr;
3288 int i;
3289 int err;
3291 memset(karg, 0, sizeof(*karg));
3292 if(__get_user(karg->ca_version, &arg32->ca32_version))
3293 return -EFAULT;
3294 karg->ca_umap.ug_ident = (char *)get_zeroed_page(GFP_USER);
3295 if(!karg->ca_umap.ug_ident)
3296 return -ENOMEM;
3297 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3298 if(strncpy_from_user(karg->ca_umap.ug_ident,
3299 (char *)A(uaddr), PAGE_SIZE) <= 0)
3300 return -EFAULT;
3301 err |= __get_user(karg->ca_umap.ug_uidbase,
3302 &arg32->ca32_umap.ug32_uidbase);
3303 err |= __get_user(karg->ca_umap.ug_uidlen,
3304 &arg32->ca32_umap.ug32_uidlen);
3305 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3306 if (err)
3307 return -EFAULT;
3308 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3309 GFP_USER);
3310 if(!karg->ca_umap.ug_udimap)
3311 return -ENOMEM;
3312 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3313 err |= __get_user(karg->ca_umap.ug_udimap[i],
3314 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3315 err |= __get_user(karg->ca_umap.ug_gidbase,
3316 &arg32->ca32_umap.ug32_gidbase);
3317 err |= __get_user(karg->ca_umap.ug_uidlen,
3318 &arg32->ca32_umap.ug32_gidlen);
3319 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3320 if (err)
3321 return -EFAULT;
3322 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3323 GFP_USER);
3324 if(!karg->ca_umap.ug_gdimap)
3325 return -ENOMEM;
3326 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3327 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3328 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3330 return (err ? -EFAULT : 0);
3333 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3335 int err;
3337 err = __get_user(karg->ca_version, &arg32->ca32_version);
3338 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3339 &arg32->ca32_getfh.gf32_addr,
3340 (sizeof(struct sockaddr)));
3341 err |= __get_user(karg->ca_getfh.gf_dev,
3342 &arg32->ca32_getfh.gf32_dev);
3343 err |= __get_user(karg->ca_getfh.gf_ino,
3344 &arg32->ca32_getfh.gf32_ino);
3345 err |= __get_user(karg->ca_getfh.gf_version,
3346 &arg32->ca32_getfh.gf32_version);
3347 return (err ? -EFAULT : 0);
3350 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3352 int err;
3354 err = __get_user(karg->ca_version, &arg32->ca32_version);
3355 err |= copy_from_user(&karg->ca_getfd.gd_addr,
3356 &arg32->ca32_getfd.gd32_addr,
3357 (sizeof(struct sockaddr)));
3358 err |= copy_from_user(&karg->ca_getfd.gd_path,
3359 &arg32->ca32_getfd.gd32_path,
3360 (NFS_MAXPATHLEN+1));
3361 err |= __get_user(karg->ca_getfd.gd_version,
3362 &arg32->ca32_getfd.gd32_version);
3363 return (err ? -EFAULT : 0);
3366 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3368 int err;
3370 err = __get_user(karg->ca_version, &arg32->ca32_version);
3371 err |= copy_from_user(&karg->ca_getfs.gd_addr,
3372 &arg32->ca32_getfs.gd32_addr,
3373 (sizeof(struct sockaddr)));
3374 err |= copy_from_user(&karg->ca_getfs.gd_path,
3375 &arg32->ca32_getfs.gd32_path,
3376 (NFS_MAXPATHLEN+1));
3377 err |= __get_user(karg->ca_getfs.gd_maxlen,
3378 &arg32->ca32_getfs.gd32_maxlen);
3379 return (err ? -EFAULT : 0);
3382 /* This really doesn't need translations, we are only passing
3383 * back a union which contains opaque nfs file handle data.
3385 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3387 return (copy_to_user(res32, kres, sizeof(*res32)) ? -EFAULT : 0);
3390 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3392 struct nfsctl_arg *karg = NULL;
3393 union nfsctl_res *kres = NULL;
3394 mm_segment_t oldfs;
3395 int err;
3397 karg = kmalloc(sizeof(*karg), GFP_USER);
3398 if(!karg)
3399 return -ENOMEM;
3400 if(res32) {
3401 kres = kmalloc(sizeof(*kres), GFP_USER);
3402 if(!kres) {
3403 kfree(karg);
3404 return -ENOMEM;
3407 switch(cmd) {
3408 case NFSCTL_SVC:
3409 err = nfs_svc32_trans(karg, arg32);
3410 break;
3411 case NFSCTL_ADDCLIENT:
3412 err = nfs_clnt32_trans(karg, arg32);
3413 break;
3414 case NFSCTL_DELCLIENT:
3415 err = nfs_clnt32_trans(karg, arg32);
3416 break;
3417 case NFSCTL_EXPORT:
3418 case NFSCTL_UNEXPORT:
3419 err = nfs_exp32_trans(karg, arg32);
3420 break;
3421 /* This one is unimplemented, be we're ready for it. */
3422 case NFSCTL_UGIDUPDATE:
3423 err = nfs_uud32_trans(karg, arg32);
3424 break;
3425 case NFSCTL_GETFH:
3426 err = nfs_getfh32_trans(karg, arg32);
3427 break;
3428 case NFSCTL_GETFD:
3429 err = nfs_getfd32_trans(karg, arg32);
3430 break;
3431 case NFSCTL_GETFS:
3432 err = nfs_getfs32_trans(karg, arg32);
3433 break;
3434 default:
3435 err = -EINVAL;
3436 break;
3438 if(err)
3439 goto done;
3440 oldfs = get_fs();
3441 set_fs(KERNEL_DS);
3442 err = sys_nfsservctl(cmd, karg, kres);
3443 set_fs(oldfs);
3445 if (err)
3446 goto done;
3448 if((cmd == NFSCTL_GETFH) ||
3449 (cmd == NFSCTL_GETFD) ||
3450 (cmd == NFSCTL_GETFS))
3451 err = nfs_getfh32_res_trans(kres, res32);
3453 done:
3454 if(karg) {
3455 if(cmd == NFSCTL_UGIDUPDATE) {
3456 if(karg->ca_umap.ug_ident)
3457 kfree(karg->ca_umap.ug_ident);
3458 if(karg->ca_umap.ug_udimap)
3459 kfree(karg->ca_umap.ug_udimap);
3460 if(karg->ca_umap.ug_gdimap)
3461 kfree(karg->ca_umap.ug_gdimap);
3463 kfree(karg);
3465 if(kres)
3466 kfree(kres);
3467 return err;
3469 #else /* !NFSD */
3470 extern asmlinkage long sys_ni_syscall(void);
3471 int asmlinkage sys32_nfsservctl(int cmd, void *notused, void *notused2)
3473 return sys_ni_syscall();
3475 #endif
3477 /* Translations due to time_t size differences. Which affects all
3478 sorts of things, like timeval and itimerval. */
3480 extern struct timezone sys_tz;
3481 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3483 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3485 if (tv) {
3486 struct timeval ktv;
3487 do_gettimeofday(&ktv);
3488 if (put_tv32(tv, &ktv))
3489 return -EFAULT;
3491 if (tz) {
3492 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3493 return -EFAULT;
3495 return 0;
3498 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3500 struct timeval ktv;
3501 struct timezone ktz;
3503 if (tv) {
3504 if (get_tv32(&ktv, tv))
3505 return -EFAULT;
3507 if (tz) {
3508 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3509 return -EFAULT;
3512 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3515 extern int do_getitimer(int which, struct itimerval *value);
3517 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3519 struct itimerval kit;
3520 int error;
3522 error = do_getitimer(which, &kit);
3523 if (!error && put_it32(it, &kit))
3524 error = -EFAULT;
3526 return error;
3529 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3531 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3533 struct itimerval kin, kout;
3534 int error;
3536 if (in) {
3537 if (get_it32(&kin, in))
3538 return -EFAULT;
3539 } else
3540 memset(&kin, 0, sizeof(kin));
3542 error = do_setitimer(which, &kin, out ? &kout : NULL);
3543 if (error || !out)
3544 return error;
3545 if (put_it32(out, &kout))
3546 return -EFAULT;
3548 return 0;
3552 asmlinkage int sys_utimes(char *, struct timeval *);
3554 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3556 char *kfilename;
3557 struct timeval ktvs[2];
3558 mm_segment_t old_fs;
3559 int ret;
3561 kfilename = getname(filename);
3562 ret = PTR_ERR(kfilename);
3563 if (!IS_ERR(kfilename)) {
3564 if (tvs) {
3565 if (get_tv32(&ktvs[0], tvs) ||
3566 get_tv32(&ktvs[1], 1+tvs))
3567 return -EFAULT;
3570 old_fs = get_fs();
3571 set_fs(KERNEL_DS);
3572 ret = sys_utimes(kfilename, &ktvs[0]);
3573 set_fs(old_fs);
3575 putname(kfilename);
3577 return ret;
3580 /* These are here just in case some old sparc32 binary calls it. */
3581 asmlinkage int sys32_pause(void)
3583 current->state = TASK_INTERRUPTIBLE;
3584 schedule();
3585 return -ERESTARTNOHAND;
3588 /* PCI config space poking. */
3589 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3590 unsigned long dfn,
3591 unsigned long off,
3592 unsigned long len,
3593 unsigned char *buf);
3595 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3596 unsigned long dfn,
3597 unsigned long off,
3598 unsigned long len,
3599 unsigned char *buf);
3601 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3603 return sys_pciconfig_read((unsigned long) bus,
3604 (unsigned long) dfn,
3605 (unsigned long) off,
3606 (unsigned long) len,
3607 (unsigned char *)AA(ubuf));
3610 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3612 return sys_pciconfig_write((unsigned long) bus,
3613 (unsigned long) dfn,
3614 (unsigned long) off,
3615 (unsigned long) len,
3616 (unsigned char *)AA(ubuf));
3619 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
3620 unsigned long arg4, unsigned long arg5);
3622 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
3624 return sys_prctl(option,
3625 (unsigned long) arg2,
3626 (unsigned long) arg3,
3627 (unsigned long) arg4,
3628 (unsigned long) arg5);
3632 extern asmlinkage ssize_t sys_pread64(unsigned int fd, char * buf,
3633 size_t count, loff_t pos);
3635 extern asmlinkage ssize_t sys_pwrite64(unsigned int fd, const char * buf,
3636 size_t count, loff_t pos);
3638 typedef __kernel_ssize_t32 ssize_t32;
3640 asmlinkage ssize_t32 sys32_pread64(unsigned int fd, char *ubuf,
3641 __kernel_size_t32 count, u32 poshi, u32 poslo)
3643 return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3646 asmlinkage ssize_t32 sys32_pwrite64(unsigned int fd, char *ubuf,
3647 __kernel_size_t32 count, u32 poshi, u32 poslo)
3649 return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3652 extern asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count);
3654 asmlinkage ssize_t32 sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count)
3656 return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count);
3659 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
3661 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
3663 mm_segment_t old_fs = get_fs();
3664 int ret;
3665 off_t of;
3667 if (offset && get_user(of, offset))
3668 return -EFAULT;
3670 set_fs(KERNEL_DS);
3671 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
3672 set_fs(old_fs);
3674 if (offset && put_user(of, offset))
3675 return -EFAULT;
3677 return ret;
3680 extern asmlinkage ssize_t sys_sendfile64(int out_fd, int in_fd, loff_t *offset, size_t count);
3682 asmlinkage int sys32_sendfile64(int out_fd, int in_fd, __kernel_loff_t32 *offset, s32 count)
3684 mm_segment_t old_fs = get_fs();
3685 int ret;
3686 loff_t lof;
3688 if (offset && get_user(lof, offset))
3689 return -EFAULT;
3691 set_fs(KERNEL_DS);
3692 ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count);
3693 set_fs(old_fs);
3695 if (offset && put_user(lof, offset))
3696 return -EFAULT;
3698 return ret;
3701 /* Handle adjtimex compatability. */
3703 struct timex32 {
3704 u32 modes;
3705 s32 offset, freq, maxerror, esterror;
3706 s32 status, constant, precision, tolerance;
3707 struct timeval32 time;
3708 s32 tick;
3709 s32 ppsfreq, jitter, shift, stabil;
3710 s32 jitcnt, calcnt, errcnt, stbcnt;
3711 s32 :32; s32 :32; s32 :32; s32 :32;
3712 s32 :32; s32 :32; s32 :32; s32 :32;
3713 s32 :32; s32 :32; s32 :32; s32 :32;
3716 extern int do_adjtimex(struct timex *);
3718 asmlinkage int sys32_adjtimex(struct timex32 *utp)
3720 struct timex txc;
3721 int ret;
3723 memset(&txc, 0, sizeof(struct timex));
3725 if(get_user(txc.modes, &utp->modes) ||
3726 __get_user(txc.offset, &utp->offset) ||
3727 __get_user(txc.freq, &utp->freq) ||
3728 __get_user(txc.maxerror, &utp->maxerror) ||
3729 __get_user(txc.esterror, &utp->esterror) ||
3730 __get_user(txc.status, &utp->status) ||
3731 __get_user(txc.constant, &utp->constant) ||
3732 __get_user(txc.precision, &utp->precision) ||
3733 __get_user(txc.tolerance, &utp->tolerance) ||
3734 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
3735 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
3736 __get_user(txc.tick, &utp->tick) ||
3737 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
3738 __get_user(txc.jitter, &utp->jitter) ||
3739 __get_user(txc.shift, &utp->shift) ||
3740 __get_user(txc.stabil, &utp->stabil) ||
3741 __get_user(txc.jitcnt, &utp->jitcnt) ||
3742 __get_user(txc.calcnt, &utp->calcnt) ||
3743 __get_user(txc.errcnt, &utp->errcnt) ||
3744 __get_user(txc.stbcnt, &utp->stbcnt))
3745 return -EFAULT;
3747 ret = do_adjtimex(&txc);
3749 if(put_user(txc.modes, &utp->modes) ||
3750 __put_user(txc.offset, &utp->offset) ||
3751 __put_user(txc.freq, &utp->freq) ||
3752 __put_user(txc.maxerror, &utp->maxerror) ||
3753 __put_user(txc.esterror, &utp->esterror) ||
3754 __put_user(txc.status, &utp->status) ||
3755 __put_user(txc.constant, &utp->constant) ||
3756 __put_user(txc.precision, &utp->precision) ||
3757 __put_user(txc.tolerance, &utp->tolerance) ||
3758 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
3759 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
3760 __put_user(txc.tick, &utp->tick) ||
3761 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
3762 __put_user(txc.jitter, &utp->jitter) ||
3763 __put_user(txc.shift, &utp->shift) ||
3764 __put_user(txc.stabil, &utp->stabil) ||
3765 __put_user(txc.jitcnt, &utp->jitcnt) ||
3766 __put_user(txc.calcnt, &utp->calcnt) ||
3767 __put_user(txc.errcnt, &utp->errcnt) ||
3768 __put_user(txc.stbcnt, &utp->stbcnt))
3769 ret = -EFAULT;
3771 return ret;
3774 /* This is just a version for 32-bit applications which does
3775 * not force O_LARGEFILE on.
3778 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
3780 char * tmp;
3781 int fd, error;
3783 tmp = getname(filename);
3784 fd = PTR_ERR(tmp);
3785 if (!IS_ERR(tmp)) {
3786 fd = get_unused_fd();
3787 if (fd >= 0) {
3788 struct file * f = filp_open(tmp, flags, mode);
3789 error = PTR_ERR(f);
3790 if (IS_ERR(f))
3791 goto out_error;
3792 fd_install(fd, f);
3794 out:
3795 putname(tmp);
3797 return fd;
3799 out_error:
3800 put_unused_fd(fd);
3801 fd = error;
3802 goto out;
3805 extern unsigned long do_mremap(unsigned long addr,
3806 unsigned long old_len, unsigned long new_len,
3807 unsigned long flags, unsigned long new_addr);
3809 asmlinkage unsigned long sys32_mremap(unsigned long addr,
3810 unsigned long old_len, unsigned long new_len,
3811 unsigned long flags, u32 __new_addr)
3813 struct vm_area_struct *vma;
3814 unsigned long ret = -EINVAL;
3815 unsigned long new_addr = AA(__new_addr);
3817 if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
3818 goto out;
3819 if (addr > 0xf0000000UL - old_len)
3820 goto out;
3821 down_write(&current->mm->mmap_sem);
3822 if (flags & MREMAP_FIXED) {
3823 if (new_addr > 0xf0000000UL - new_len)
3824 goto out_sem;
3825 } else if (addr > 0xf0000000UL - new_len) {
3826 unsigned long map_flags = 0;
3827 struct file *file = NULL;
3829 ret = -ENOMEM;
3830 if (!(flags & MREMAP_MAYMOVE))
3831 goto out_sem;
3833 vma = find_vma(current->mm, addr);
3834 if (vma) {
3835 if (vma->vm_flags & VM_SHARED)
3836 map_flags |= MAP_SHARED;
3837 file = vma->vm_file;
3840 /* MREMAP_FIXED checked above. */
3841 new_addr = get_unmapped_area(file, addr, new_len,
3842 vma ? vma->vm_pgoff : 0,
3843 map_flags);
3844 ret = new_addr;
3845 if (new_addr & ~PAGE_MASK)
3846 goto out_sem;
3847 flags |= MREMAP_FIXED;
3849 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
3850 out_sem:
3851 up_write(&current->mm->mmap_sem);
3852 out:
3853 return ret;
3856 extern asmlinkage long sys_setpriority(int which, int who, int niceval);
3858 asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
3860 return sys_setpriority((int) which,
3861 (int) who,
3862 (int) niceval);
3865 struct __sysctl_args32 {
3866 u32 name;
3867 int nlen;
3868 u32 oldval;
3869 u32 oldlenp;
3870 u32 newval;
3871 u32 newlen;
3872 u32 __unused[4];
3875 asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
3877 struct __sysctl_args32 tmp;
3878 int error;
3879 size_t oldlen, *oldlenp = NULL;
3880 unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
3882 if (copy_from_user(&tmp, args, sizeof(tmp)))
3883 return -EFAULT;
3885 if (tmp.oldval && tmp.oldlenp) {
3886 /* Duh, this is ugly and might not work if sysctl_args
3887 is in read-only memory, but do_sysctl does indirectly
3888 a lot of uaccess in both directions and we'd have to
3889 basically copy the whole sysctl.c here, and
3890 glibc's __sysctl uses rw memory for the structure
3891 anyway. */
3892 if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
3893 put_user(oldlen, (size_t *)addr))
3894 return -EFAULT;
3895 oldlenp = (size_t *)addr;
3898 lock_kernel();
3899 error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
3900 oldlenp, (void *)A(tmp.newval), tmp.newlen);
3901 unlock_kernel();
3902 if (oldlenp) {
3903 if (!error) {
3904 if (get_user(oldlen, (size_t *)addr) ||
3905 put_user(oldlen, (u32 *)A(tmp.oldlenp)))
3906 error = -EFAULT;
3908 copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
3910 return error;
3913 extern asmlinkage int sys_sched_setaffinity(pid_t pid, unsigned int len,
3914 unsigned long *user_mask_ptr);
3916 asmlinkage int sys32_sched_setaffinity(__kernel_pid_t32 pid, unsigned int len,
3917 u32 *user_mask_ptr)
3919 unsigned long kernel_mask;
3920 mm_segment_t old_fs;
3921 int ret;
3923 if (get_user(kernel_mask, user_mask_ptr))
3924 return -EFAULT;
3926 old_fs = get_fs();
3927 set_fs(KERNEL_DS);
3928 ret = sys_sched_setaffinity(pid,
3929 /* XXX Nice api... */
3930 sizeof(kernel_mask),
3931 &kernel_mask);
3932 set_fs(old_fs);
3934 return ret;
3937 extern asmlinkage int sys_sched_getaffinity(pid_t pid, unsigned int len,
3938 unsigned long *user_mask_ptr);
3940 asmlinkage int sys32_sched_getaffinity(__kernel_pid_t32 pid, unsigned int len,
3941 u32 *user_mask_ptr)
3943 unsigned long kernel_mask;
3944 mm_segment_t old_fs;
3945 int ret;
3947 old_fs = get_fs();
3948 set_fs(KERNEL_DS);
3949 ret = sys_sched_getaffinity(pid,
3950 /* XXX Nice api... */
3951 sizeof(kernel_mask),
3952 &kernel_mask);
3953 set_fs(old_fs);
3955 if (ret > 0) {
3956 if (put_user(kernel_mask, user_mask_ptr))
3957 ret = -EFAULT;
3960 return ret;