Linux 2.4.0-test7-pre6
[davej-history.git] / arch / sparc64 / kernel / sys_sparc32.c
blob2072acd2a9f083d5bc37cccb9055821406b012af
1 /* $Id: sys_sparc32.c,v 1.162 2000/08/16 15:33:30 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/malloc.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>
52 #include <asm/types.h>
53 #include <asm/ipc.h>
54 #include <asm/uaccess.h>
55 #include <asm/fpumacro.h>
56 #include <asm/semaphore.h>
58 #include <net/scm.h>
60 /* Use this to get at 32-bit user passed pointers. */
61 /* Things to consider: the low-level assembly stub does
62 srl x, 0, x for first four arguments, so if you have
63 pointer to something in the first four arguments, just
64 declare it as a pointer, not u32. On the other side,
65 arguments from 5th onwards should be declared as u32
66 for pointers, and need AA() around each usage.
67 A() macro should be used for places where you e.g.
68 have some internal variable u32 and just want to get
69 rid of a compiler warning. AA() has to be used in
70 places where you want to convert a function argument
71 to 32bit pointer or when you e.g. access pt_regs
72 structure and want to consider 32bit registers only.
73 -jj
75 #define A(__x) ((unsigned long)(__x))
76 #define AA(__x) \
77 ({ unsigned long __ret; \
78 __asm__ ("srl %0, 0, %0" \
79 : "=r" (__ret) \
80 : "0" (__x)); \
81 __ret; \
84 extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
85 extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
86 extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
87 extern asmlinkage long sys_setregid(gid_t, gid_t);
88 extern asmlinkage long sys_setgid(gid_t);
89 extern asmlinkage long sys_setreuid(uid_t, uid_t);
90 extern asmlinkage long sys_setuid(uid_t);
91 extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
92 extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
93 extern asmlinkage long sys_setfsuid(uid_t);
94 extern asmlinkage long sys_setfsgid(gid_t);
96 /* For this source file, we want overflow handling. */
98 #undef high2lowuid
99 #undef high2lowgid
100 #undef low2highuid
101 #undef low2highgid
102 #undef SET_UID16
103 #undef SET_GID16
104 #undef NEW_TO_OLD_UID
105 #undef NEW_TO_OLD_GID
106 #undef SET_OLDSTAT_UID
107 #undef SET_OLDSTAT_GID
108 #undef SET_STAT_UID
109 #undef SET_STAT_GID
111 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
112 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
113 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
114 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
115 #define SET_UID16(var, uid) var = high2lowuid(uid)
116 #define SET_GID16(var, gid) var = high2lowgid(gid)
117 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
118 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
119 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
120 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
121 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
122 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
124 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
126 return sys_chown(filename, low2highuid(user), low2highgid(group));
129 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
131 return sys_lchown(filename, low2highuid(user), low2highgid(group));
134 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
136 return sys_fchown(fd, low2highuid(user), low2highgid(group));
139 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
141 return sys_setregid(low2highgid(rgid), low2highgid(egid));
144 asmlinkage long sys32_setgid16(u16 gid)
146 return sys_setgid((gid_t)gid);
149 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
151 return sys_setreuid(low2highuid(ruid), low2highuid(euid));
154 asmlinkage long sys32_setuid16(u16 uid)
156 return sys_setuid((uid_t)uid);
159 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
161 return sys_setresuid(low2highuid(ruid), low2highuid(euid),
162 low2highuid(suid));
165 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
167 int retval;
169 if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
170 !(retval = put_user(high2lowuid(current->euid), euid)))
171 retval = put_user(high2lowuid(current->suid), suid);
173 return retval;
176 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
178 return sys_setresgid(low2highgid(rgid), low2highgid(egid),
179 low2highgid(sgid));
182 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
184 int retval;
186 if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
187 !(retval = put_user(high2lowgid(current->egid), egid)))
188 retval = put_user(high2lowgid(current->sgid), sgid);
190 return retval;
193 asmlinkage long sys32_setfsuid16(u16 uid)
195 return sys_setfsuid((uid_t)uid);
198 asmlinkage long sys32_setfsgid16(u16 gid)
200 return sys_setfsgid((gid_t)gid);
203 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
205 u16 groups[NGROUPS];
206 int i,j;
208 if (gidsetsize < 0)
209 return -EINVAL;
210 i = current->ngroups;
211 if (gidsetsize) {
212 if (i > gidsetsize)
213 return -EINVAL;
214 for(j=0;j<i;j++)
215 groups[j] = current->groups[j];
216 if (copy_to_user(grouplist, groups, sizeof(u16)*i))
217 return -EFAULT;
219 return i;
222 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
224 u16 groups[NGROUPS];
225 int i;
227 if (!capable(CAP_SETGID))
228 return -EPERM;
229 if ((unsigned) gidsetsize > NGROUPS)
230 return -EINVAL;
231 if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
232 return -EFAULT;
233 for (i = 0 ; i < gidsetsize ; i++)
234 current->groups[i] = (gid_t)groups[i];
235 current->ngroups = gidsetsize;
236 return 0;
239 asmlinkage long sys32_getuid16(void)
241 return high2lowuid(current->uid);
244 asmlinkage long sys32_geteuid16(void)
246 return high2lowuid(current->euid);
249 asmlinkage long sys32_getgid16(void)
251 return high2lowgid(current->gid);
254 asmlinkage long sys32_getegid16(void)
256 return high2lowgid(current->egid);
259 /* 32-bit timeval and related flotsam. */
261 struct timeval32
263 int tv_sec, tv_usec;
266 struct itimerval32
268 struct timeval32 it_interval;
269 struct timeval32 it_value;
272 static inline long get_tv32(struct timeval *o, struct timeval32 *i)
274 return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
275 (__get_user(o->tv_sec, &i->tv_sec) |
276 __get_user(o->tv_usec, &i->tv_usec)));
279 static inline long put_tv32(struct timeval32 *o, struct timeval *i)
281 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
282 (__put_user(i->tv_sec, &o->tv_sec) |
283 __put_user(i->tv_usec, &o->tv_usec)));
286 static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
288 return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
289 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
290 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
291 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
292 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
295 static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
297 return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
298 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
299 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
300 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
301 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
304 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
306 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
308 return sys_ioperm((unsigned long)from, (unsigned long)num, on);
311 struct msgbuf32 { s32 mtype; char mtext[1]; };
313 struct ipc_perm32
315 key_t key;
316 __kernel_uid_t32 uid;
317 __kernel_gid_t32 gid;
318 __kernel_uid_t32 cuid;
319 __kernel_gid_t32 cgid;
320 __kernel_mode_t32 mode;
321 unsigned short seq;
324 struct semid_ds32 {
325 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
326 __kernel_time_t32 sem_otime; /* last semop time */
327 __kernel_time_t32 sem_ctime; /* last change time */
328 u32 sem_base; /* ptr to first semaphore in array */
329 u32 sem_pending; /* pending operations to be processed */
330 u32 sem_pending_last; /* last pending operation */
331 u32 undo; /* undo requests on this array */
332 unsigned short sem_nsems; /* no. of semaphores in array */
335 struct semid64_ds32 {
336 struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
337 unsigned int __pad1;
338 __kernel_time_t32 sem_otime;
339 unsigned int __pad2;
340 __kernel_time_t32 sem_ctime;
341 u32 sem_nsems;
342 u32 __unused1;
343 u32 __unused2;
346 struct msqid_ds32
348 struct ipc_perm32 msg_perm;
349 u32 msg_first;
350 u32 msg_last;
351 __kernel_time_t32 msg_stime;
352 __kernel_time_t32 msg_rtime;
353 __kernel_time_t32 msg_ctime;
354 u32 wwait;
355 u32 rwait;
356 unsigned short msg_cbytes;
357 unsigned short msg_qnum;
358 unsigned short msg_qbytes;
359 __kernel_ipc_pid_t32 msg_lspid;
360 __kernel_ipc_pid_t32 msg_lrpid;
363 struct msqid64_ds32 {
364 struct ipc64_perm msg_perm;
365 unsigned int __pad1;
366 __kernel_time_t32 msg_stime;
367 unsigned int __pad2;
368 __kernel_time_t32 msg_rtime;
369 unsigned int __pad3;
370 __kernel_time_t32 msg_ctime;
371 unsigned int msg_cbytes;
372 unsigned int msg_qnum;
373 unsigned int msg_qbytes;
374 __kernel_pid_t32 msg_lspid;
375 __kernel_pid_t32 msg_lrpid;
376 unsigned int __unused1;
377 unsigned int __unused2;
381 struct shmid_ds32 {
382 struct ipc_perm32 shm_perm;
383 int shm_segsz;
384 __kernel_time_t32 shm_atime;
385 __kernel_time_t32 shm_dtime;
386 __kernel_time_t32 shm_ctime;
387 __kernel_ipc_pid_t32 shm_cpid;
388 __kernel_ipc_pid_t32 shm_lpid;
389 unsigned short shm_nattch;
392 struct shmid64_ds32 {
393 struct ipc64_perm shm_perm;
394 unsigned int __pad1;
395 __kernel_time_t32 shm_atime;
396 unsigned int __pad2;
397 __kernel_time_t32 shm_dtime;
398 unsigned int __pad3;
399 __kernel_time_t32 shm_ctime;
400 __kernel_size_t32 shm_segsz;
401 __kernel_pid_t32 shm_cpid;
402 __kernel_pid_t32 shm_lpid;
403 unsigned int shm_nattch;
404 unsigned int __unused1;
405 unsigned int __unused2;
410 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
412 * This is really horribly ugly.
414 #define IPCOP_MASK(__x) (1UL << (__x))
415 static int do_sys32_semctl(int first, int second, int third, void *uptr)
417 union semun fourth;
418 u32 pad;
419 int err = -EINVAL;
421 if (!uptr)
422 goto out;
423 err = -EFAULT;
424 if (get_user (pad, (u32 *)uptr))
425 goto out;
426 if(third == SETVAL)
427 fourth.val = (int)pad;
428 else
429 fourth.__pad = (void *)A(pad);
430 if (IPCOP_MASK (third) &
431 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
432 IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
433 IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
434 err = sys_semctl (first, second, third, fourth);
435 } else if (third & IPC_64) {
436 struct semid64_ds s;
437 struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
438 mm_segment_t old_fs;
439 int need_back_translation;
441 if (third == (IPC_SET|IPC_64)) {
442 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
443 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
444 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
445 if (err)
446 goto out;
447 fourth.__pad = &s;
449 need_back_translation =
450 (IPCOP_MASK (third) &
451 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
452 if (need_back_translation)
453 fourth.__pad = &s;
454 old_fs = get_fs ();
455 set_fs (KERNEL_DS);
456 err = sys_semctl (first, second, third, fourth);
457 set_fs (old_fs);
458 if (need_back_translation) {
459 int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
460 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
461 if (err2) err = -EFAULT;
463 } else {
464 struct semid_ds s;
465 struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
466 mm_segment_t old_fs;
467 int need_back_translation;
469 if (third == IPC_SET) {
470 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
471 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
472 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
473 if (err)
474 goto out;
475 fourth.__pad = &s;
477 need_back_translation =
478 (IPCOP_MASK (third) &
479 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
480 if (need_back_translation)
481 fourth.__pad = &s;
482 old_fs = get_fs ();
483 set_fs (KERNEL_DS);
484 err = sys_semctl (first, second, third, fourth);
485 set_fs (old_fs);
486 if (need_back_translation) {
487 int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
488 err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
489 err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
490 err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
491 err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
492 err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
493 err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
494 err2 |= __put_user (s.sem_otime, &usp->sem_otime);
495 err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
496 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
497 if (err2) err = -EFAULT;
500 out:
501 return err;
504 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
506 struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
507 struct msgbuf32 *up = (struct msgbuf32 *)uptr;
508 mm_segment_t old_fs;
509 int err;
511 if (!p)
512 return -ENOMEM;
513 err = get_user (p->mtype, &up->mtype);
514 err |= __copy_from_user (p->mtext, &up->mtext, second);
515 if (err)
516 goto out;
517 old_fs = get_fs ();
518 set_fs (KERNEL_DS);
519 err = sys_msgsnd (first, p, second, third);
520 set_fs (old_fs);
521 out:
522 kfree (p);
523 return err;
526 static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
527 int version, void *uptr)
529 struct msgbuf32 *up;
530 struct msgbuf *p;
531 mm_segment_t old_fs;
532 int err;
534 if (!version) {
535 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
536 struct ipc_kludge ipck;
538 err = -EINVAL;
539 if (!uptr)
540 goto out;
541 err = -EFAULT;
542 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
543 goto out;
544 uptr = (void *)A(ipck.msgp);
545 msgtyp = ipck.msgtyp;
547 err = -ENOMEM;
548 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
549 if (!p)
550 goto out;
551 old_fs = get_fs ();
552 set_fs (KERNEL_DS);
553 err = sys_msgrcv (first, p, second + 4, msgtyp, third);
554 set_fs (old_fs);
555 if (err < 0)
556 goto free_then_out;
557 up = (struct msgbuf32 *)uptr;
558 if (put_user (p->mtype, &up->mtype) ||
559 __copy_to_user (&up->mtext, p->mtext, err))
560 err = -EFAULT;
561 free_then_out:
562 kfree (p);
563 out:
564 return err;
567 static int do_sys32_msgctl (int first, int second, void *uptr)
569 int err;
571 if (IPCOP_MASK (second) &
572 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
573 IPCOP_MASK (IPC_RMID))) {
574 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
575 } else if (second & IPC_64) {
576 struct msqid64_ds m;
577 struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
578 mm_segment_t old_fs;
580 if (second == (IPC_SET|IPC_64)) {
581 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
582 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
583 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
584 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
585 if (err)
586 goto out;
588 old_fs = get_fs ();
589 set_fs (KERNEL_DS);
590 err = sys_msgctl (first, second, (struct msqid_ds *)&m);
591 set_fs (old_fs);
592 if (IPCOP_MASK (second) &
593 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
594 int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
595 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
596 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
597 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
598 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
599 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
600 if (err2)
601 err = -EFAULT;
603 } else {
604 struct msqid_ds m;
605 struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
606 mm_segment_t old_fs;
608 if (second == IPC_SET) {
609 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
610 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
611 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
612 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
613 if (err)
614 goto out;
616 old_fs = get_fs ();
617 set_fs (KERNEL_DS);
618 err = sys_msgctl (first, second, &m);
619 set_fs (old_fs);
620 if (IPCOP_MASK (second) &
621 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
622 int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
623 err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
624 err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
625 err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
626 err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
627 err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
628 err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
629 err2 |= __put_user (m.msg_stime, &up->msg_stime);
630 err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
631 err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
632 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
633 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
634 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
635 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
636 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
637 if (err2)
638 err = -EFAULT;
642 out:
643 return err;
646 static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
648 unsigned long raddr;
649 u32 *uaddr = (u32 *)A((u32)third);
650 int err = -EINVAL;
652 if (version == 1)
653 goto out;
654 err = sys_shmat (first, uptr, second, &raddr);
655 if (err)
656 goto out;
657 err = put_user (raddr, uaddr);
658 out:
659 return err;
662 static int do_sys32_shmctl (int first, int second, void *uptr)
664 int err;
666 if (IPCOP_MASK (second) &
667 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
668 IPCOP_MASK (IPC_RMID))) {
669 if (second == (IPC_INFO|IPC_64))
670 second = IPC_INFO; /* So that we don't have to translate it */
671 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
672 } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
673 struct shmid64_ds s;
674 struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
675 mm_segment_t old_fs;
677 if (second == (IPC_SET|IPC_64)) {
678 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
679 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
680 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
681 if (err)
682 goto out;
684 old_fs = get_fs ();
685 set_fs (KERNEL_DS);
686 err = sys_shmctl (first, second, (struct shmid_ds *)&s);
687 set_fs (old_fs);
688 if (err < 0)
689 goto out;
691 /* Mask it even in this case so it becomes a CSE. */
692 if (IPCOP_MASK (second) &
693 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
694 int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
695 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
696 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
697 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
698 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
699 if (err2)
700 err = -EFAULT;
702 } else {
703 struct shmid_ds s;
704 struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
705 mm_segment_t old_fs;
707 second &= ~IPC_64;
708 if (second == IPC_SET) {
709 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
710 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
711 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
712 if (err)
713 goto out;
715 old_fs = get_fs ();
716 set_fs (KERNEL_DS);
717 err = sys_shmctl (first, second, &s);
718 set_fs (old_fs);
719 if (err < 0)
720 goto out;
722 /* Mask it even in this case so it becomes a CSE. */
723 if (second == SHM_INFO) {
724 struct shm_info32 {
725 int used_ids;
726 u32 shm_tot, shm_rss, shm_swp;
727 u32 swap_attempts, swap_successes;
728 } *uip = (struct shm_info32 *)uptr;
729 struct shm_info *kp = (struct shm_info *)&s;
730 int err2 = put_user (kp->used_ids, &uip->used_ids);
731 err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
732 err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
733 err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
734 err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
735 err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
736 if (err2)
737 err = -EFAULT;
738 } else if (IPCOP_MASK (second) &
739 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
740 int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
741 err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
742 err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
743 err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
744 err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
745 err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
746 err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
747 err2 |= __put_user (s.shm_atime, &up->shm_atime);
748 err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
749 err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
750 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
751 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
752 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
753 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
754 if (err2)
755 err = -EFAULT;
758 out:
759 return err;
762 asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
764 int version, err;
766 version = call >> 16; /* hack for backward compatibility */
767 call &= 0xffff;
769 if (call <= SEMCTL)
770 switch (call) {
771 case SEMOP:
772 /* struct sembuf is the same on 32 and 64bit :)) */
773 err = sys_semop (first, (struct sembuf *)AA(ptr), second);
774 goto out;
775 case SEMGET:
776 err = sys_semget (first, second, third);
777 goto out;
778 case SEMCTL:
779 err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
780 goto out;
781 default:
782 err = -EINVAL;
783 goto out;
785 if (call <= MSGCTL)
786 switch (call) {
787 case MSGSND:
788 err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
789 goto out;
790 case MSGRCV:
791 err = do_sys32_msgrcv (first, second, fifth, third,
792 version, (void *)AA(ptr));
793 goto out;
794 case MSGGET:
795 err = sys_msgget ((key_t) first, second);
796 goto out;
797 case MSGCTL:
798 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
799 goto out;
800 default:
801 err = -EINVAL;
802 goto out;
804 if (call <= SHMCTL)
805 switch (call) {
806 case SHMAT:
807 err = do_sys32_shmat (first, second, third,
808 version, (void *)AA(ptr));
809 goto out;
810 case SHMDT:
811 err = sys_shmdt ((char *)AA(ptr));
812 goto out;
813 case SHMGET:
814 err = sys_shmget (first, second, third);
815 goto out;
816 case SHMCTL:
817 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
818 goto out;
819 default:
820 err = -EINVAL;
821 goto out;
824 err = -EINVAL;
826 out:
827 return err;
830 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
832 int err;
834 err = get_user(kfl->l_type, &ufl->l_type);
835 err |= __get_user(kfl->l_whence, &ufl->l_whence);
836 err |= __get_user(kfl->l_start, &ufl->l_start);
837 err |= __get_user(kfl->l_len, &ufl->l_len);
838 err |= __get_user(kfl->l_pid, &ufl->l_pid);
839 return err;
842 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
844 int err;
846 err = __put_user(kfl->l_type, &ufl->l_type);
847 err |= __put_user(kfl->l_whence, &ufl->l_whence);
848 err |= __put_user(kfl->l_start, &ufl->l_start);
849 err |= __put_user(kfl->l_len, &ufl->l_len);
850 err |= __put_user(kfl->l_pid, &ufl->l_pid);
851 return err;
854 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
856 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
858 switch (cmd) {
859 case F_GETLK:
860 case F_SETLK:
861 case F_SETLKW:
863 struct flock f;
864 mm_segment_t old_fs;
865 long ret;
867 if(get_flock(&f, (struct flock32 *)arg))
868 return -EFAULT;
869 old_fs = get_fs(); set_fs (KERNEL_DS);
870 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
871 set_fs (old_fs);
872 if (ret) return ret;
873 if (f.l_start >= 0x7fffffffUL ||
874 f.l_len >= 0x7fffffffUL ||
875 f.l_start + f.l_len >= 0x7fffffffUL)
876 return -EOVERFLOW;
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 struct dqblk32 {
894 __u32 dqb_bhardlimit;
895 __u32 dqb_bsoftlimit;
896 __u32 dqb_curblocks;
897 __u32 dqb_ihardlimit;
898 __u32 dqb_isoftlimit;
899 __u32 dqb_curinodes;
900 __kernel_time_t32 dqb_btime;
901 __kernel_time_t32 dqb_itime;
904 extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
906 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
908 int cmds = cmd >> SUBCMDSHIFT;
909 int err;
910 struct dqblk d;
911 mm_segment_t old_fs;
912 char *spec;
914 switch (cmds) {
915 case Q_GETQUOTA:
916 break;
917 case Q_SETQUOTA:
918 case Q_SETUSE:
919 case Q_SETQLIM:
920 if (copy_from_user (&d, (struct dqblk32 *)addr,
921 sizeof (struct dqblk32)))
922 return -EFAULT;
923 d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
924 d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
925 break;
926 default:
927 return sys_quotactl(cmd, special,
928 id, (caddr_t)addr);
930 spec = getname (special);
931 err = PTR_ERR(spec);
932 if (IS_ERR(spec)) return err;
933 old_fs = get_fs ();
934 set_fs (KERNEL_DS);
935 err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
936 set_fs (old_fs);
937 putname (spec);
938 if (cmds == Q_GETQUOTA) {
939 __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
940 ((struct dqblk32 *)&d)->dqb_itime = i;
941 ((struct dqblk32 *)&d)->dqb_btime = b;
942 if (copy_to_user ((struct dqblk32 *)addr, &d,
943 sizeof (struct dqblk32)))
944 return -EFAULT;
946 return err;
949 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
951 int err;
953 err = put_user (kbuf->f_type, &ubuf->f_type);
954 err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
955 err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
956 err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
957 err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
958 err |= __put_user (kbuf->f_files, &ubuf->f_files);
959 err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
960 err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
961 err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
962 err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
963 return err;
966 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
968 asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
970 int ret;
971 struct statfs s;
972 mm_segment_t old_fs = get_fs();
973 char *pth;
975 pth = getname (path);
976 ret = PTR_ERR(pth);
977 if (!IS_ERR(pth)) {
978 set_fs (KERNEL_DS);
979 ret = sys_statfs((const char *)pth, &s);
980 set_fs (old_fs);
981 putname (pth);
982 if (put_statfs(buf, &s))
983 return -EFAULT;
985 return ret;
988 extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
990 asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
992 int ret;
993 struct statfs s;
994 mm_segment_t old_fs = get_fs();
996 set_fs (KERNEL_DS);
997 ret = sys_fstatfs(fd, &s);
998 set_fs (old_fs);
999 if (put_statfs(buf, &s))
1000 return -EFAULT;
1001 return ret;
1004 extern asmlinkage long sys_truncate(const char * path, unsigned long length);
1005 extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
1007 asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
1009 if ((int)high < 0)
1010 return -EINVAL;
1011 else
1012 return sys_truncate(path, (high << 32) | low);
1015 asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
1017 if ((int)high < 0)
1018 return -EINVAL;
1019 else
1020 return sys_ftruncate(fd, (high << 32) | low);
1023 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
1025 struct utimbuf32 {
1026 __kernel_time_t32 actime, modtime;
1029 asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
1031 struct utimbuf t;
1032 mm_segment_t old_fs;
1033 int ret;
1034 char *filenam;
1036 if (!times)
1037 return sys_utime(filename, NULL);
1038 if (get_user (t.actime, &times->actime) ||
1039 __get_user (t.modtime, &times->modtime))
1040 return -EFAULT;
1041 filenam = getname (filename);
1042 ret = PTR_ERR(filenam);
1043 if (!IS_ERR(filenam)) {
1044 old_fs = get_fs();
1045 set_fs (KERNEL_DS);
1046 ret = sys_utime(filenam, &t);
1047 set_fs (old_fs);
1048 putname (filenam);
1050 return ret;
1053 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
1055 typedef ssize_t (*io_fn_t)(struct file *, char *, size_t, loff_t *);
1056 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1058 static long do_readv_writev32(int type, struct file *file,
1059 const struct iovec32 *vector, u32 count)
1061 unsigned long tot_len;
1062 struct iovec iovstack[UIO_FASTIOV];
1063 struct iovec *iov=iovstack, *ivp;
1064 struct inode *inode;
1065 long retval, i;
1066 io_fn_t fn;
1067 iov_fn_t fnv;
1069 /* First get the "struct iovec" from user memory and
1070 * verify all the pointers
1072 if (!count)
1073 return 0;
1074 if (verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1075 return -EFAULT;
1076 if (count > UIO_MAXIOV)
1077 return -EINVAL;
1078 if (count > UIO_FASTIOV) {
1079 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1080 if (!iov)
1081 return -ENOMEM;
1084 tot_len = 0;
1085 i = count;
1086 ivp = iov;
1087 while(i > 0) {
1088 u32 len;
1089 u32 buf;
1091 __get_user(len, &vector->iov_len);
1092 __get_user(buf, &vector->iov_base);
1093 tot_len += len;
1094 ivp->iov_base = (void *)A(buf);
1095 ivp->iov_len = (__kernel_size_t) len;
1096 vector++;
1097 ivp++;
1098 i--;
1101 inode = file->f_dentry->d_inode;
1102 /* VERIFY_WRITE actually means a read, as we write to user space */
1103 retval = locks_verify_area((type == VERIFY_WRITE
1104 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1105 inode, file, file->f_pos, tot_len);
1106 if (retval)
1107 goto out;
1109 /* VERIFY_WRITE actually means a read, as we write to user space */
1110 fnv = (type == VERIFY_WRITE ? file->f_op->readv : file->f_op->writev);
1111 if (fnv) {
1112 retval = fnv(file, iov, count, &file->f_pos);
1113 goto out;
1116 fn = (type == VERIFY_WRITE ? file->f_op->read :
1117 (io_fn_t) file->f_op->write);
1119 ivp = iov;
1120 while (count > 0) {
1121 void * base;
1122 int len, nr;
1124 base = ivp->iov_base;
1125 len = ivp->iov_len;
1126 ivp++;
1127 count--;
1128 nr = fn(file, base, len, &file->f_pos);
1129 if (nr < 0) {
1130 if (!retval)
1131 retval = nr;
1132 break;
1134 retval += nr;
1135 if (nr != len)
1136 break;
1138 out:
1139 if (iov != iovstack)
1140 kfree(iov);
1142 return retval;
1145 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1147 struct file *file;
1148 long ret = -EBADF;
1150 file = fget(fd);
1151 if(!file)
1152 goto bad_file;
1154 if (file->f_op && (file->f_mode & FMODE_READ) &&
1155 (file->f_op->readv || file->f_op->read))
1156 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1157 fput(file);
1159 bad_file:
1160 return ret;
1163 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1165 struct file *file;
1166 int ret = -EBADF;
1168 file = fget(fd);
1169 if(!file)
1170 goto bad_file;
1171 if (file->f_op && (file->f_mode & FMODE_WRITE) &&
1172 (file->f_op->writev || file->f_op->write))
1173 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1174 fput(file);
1176 bad_file:
1177 return ret;
1180 /* readdir & getdents */
1182 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1183 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1185 struct old_linux_dirent32 {
1186 u32 d_ino;
1187 u32 d_offset;
1188 unsigned short d_namlen;
1189 char d_name[1];
1192 struct readdir_callback32 {
1193 struct old_linux_dirent32 * dirent;
1194 int count;
1197 static int fillonedir(void * __buf, const char * name, int namlen,
1198 off_t offset, ino_t ino, unsigned int d_type)
1200 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1201 struct old_linux_dirent32 * dirent;
1203 if (buf->count)
1204 return -EINVAL;
1205 buf->count++;
1206 dirent = buf->dirent;
1207 put_user(ino, &dirent->d_ino);
1208 put_user(offset, &dirent->d_offset);
1209 put_user(namlen, &dirent->d_namlen);
1210 copy_to_user(dirent->d_name, name, namlen);
1211 put_user(0, dirent->d_name + namlen);
1212 return 0;
1215 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1217 int error = -EBADF;
1218 struct file * file;
1219 struct readdir_callback32 buf;
1221 file = fget(fd);
1222 if (!file)
1223 goto out;
1225 buf.count = 0;
1226 buf.dirent = dirent;
1228 error = vfs_readdir(file, fillonedir, &buf);
1229 if (error < 0)
1230 goto out_putf;
1231 error = buf.count;
1233 out_putf:
1234 fput(file);
1235 out:
1236 return error;
1239 struct linux_dirent32 {
1240 u32 d_ino;
1241 u32 d_off;
1242 unsigned short d_reclen;
1243 char d_name[1];
1246 struct getdents_callback32 {
1247 struct linux_dirent32 * current_dir;
1248 struct linux_dirent32 * previous;
1249 int count;
1250 int error;
1253 static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino,
1254 unsigned int d_type)
1256 struct linux_dirent32 * dirent;
1257 struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1258 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1260 buf->error = -EINVAL; /* only used if we fail.. */
1261 if (reclen > buf->count)
1262 return -EINVAL;
1263 dirent = buf->previous;
1264 if (dirent)
1265 put_user(offset, &dirent->d_off);
1266 dirent = buf->current_dir;
1267 buf->previous = dirent;
1268 put_user(ino, &dirent->d_ino);
1269 put_user(reclen, &dirent->d_reclen);
1270 copy_to_user(dirent->d_name, name, namlen);
1271 put_user(0, dirent->d_name + namlen);
1272 ((char *) dirent) += reclen;
1273 buf->current_dir = dirent;
1274 buf->count -= reclen;
1275 return 0;
1278 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1280 struct file * file;
1281 struct linux_dirent32 * lastdirent;
1282 struct getdents_callback32 buf;
1283 int error = -EBADF;
1285 file = fget(fd);
1286 if (!file)
1287 goto out;
1289 buf.current_dir = dirent;
1290 buf.previous = NULL;
1291 buf.count = count;
1292 buf.error = 0;
1294 error = vfs_readdir(file, filldir, &buf);
1295 if (error < 0)
1296 goto out_putf;
1297 lastdirent = buf.previous;
1298 error = buf.error;
1299 if(lastdirent) {
1300 put_user(file->f_pos, &lastdirent->d_off);
1301 error = count - buf.count;
1303 out_putf:
1304 fput(file);
1305 out:
1306 return error;
1309 /* end of readdir & getdents */
1312 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1313 * 64-bit unsigned longs.
1316 static inline int
1317 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1319 if (ufdset) {
1320 unsigned long odd;
1322 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1323 return -EFAULT;
1325 odd = n & 1UL;
1326 n &= ~1UL;
1327 while (n) {
1328 unsigned long h, l;
1329 __get_user(l, ufdset);
1330 __get_user(h, ufdset+1);
1331 ufdset += 2;
1332 *fdset++ = h << 32 | l;
1333 n -= 2;
1335 if (odd)
1336 __get_user(*fdset, ufdset);
1337 } else {
1338 /* Tricky, must clear full unsigned long in the
1339 * kernel fdset at the end, this makes sure that
1340 * actually happens.
1342 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1344 return 0;
1347 static inline void
1348 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1350 unsigned long odd;
1352 if (!ufdset)
1353 return;
1355 odd = n & 1UL;
1356 n &= ~1UL;
1357 while (n) {
1358 unsigned long h, l;
1359 l = *fdset++;
1360 h = l >> 32;
1361 __put_user(l, ufdset);
1362 __put_user(h, ufdset+1);
1363 ufdset += 2;
1364 n -= 2;
1366 if (odd)
1367 __put_user(*fdset, ufdset);
1370 #define MAX_SELECT_SECONDS \
1371 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1373 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1375 fd_set_bits fds;
1376 struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1377 char *bits;
1378 unsigned long nn;
1379 long timeout;
1380 int ret, size;
1382 timeout = MAX_SCHEDULE_TIMEOUT;
1383 if (tvp) {
1384 time_t sec, usec;
1386 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1387 || (ret = __get_user(sec, &tvp->tv_sec))
1388 || (ret = __get_user(usec, &tvp->tv_usec)))
1389 goto out_nofds;
1391 ret = -EINVAL;
1392 if(sec < 0 || usec < 0)
1393 goto out_nofds;
1395 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1396 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1397 timeout += sec * (unsigned long) HZ;
1401 ret = -EINVAL;
1402 if (n < 0)
1403 goto out_nofds;
1404 if (n > current->files->max_fdset)
1405 n = current->files->max_fdset;
1408 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1409 * since we used fdset we need to allocate memory in units of
1410 * long-words.
1412 ret = -ENOMEM;
1413 size = FDS_BYTES(n);
1414 bits = kmalloc(6 * size, GFP_KERNEL);
1415 if (!bits)
1416 goto out_nofds;
1417 fds.in = (unsigned long *) bits;
1418 fds.out = (unsigned long *) (bits + size);
1419 fds.ex = (unsigned long *) (bits + 2*size);
1420 fds.res_in = (unsigned long *) (bits + 3*size);
1421 fds.res_out = (unsigned long *) (bits + 4*size);
1422 fds.res_ex = (unsigned long *) (bits + 5*size);
1424 nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1425 if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1426 (ret = get_fd_set32(nn, fds.out, outp)) ||
1427 (ret = get_fd_set32(nn, fds.ex, exp)))
1428 goto out;
1429 zero_fd_set(n, fds.res_in);
1430 zero_fd_set(n, fds.res_out);
1431 zero_fd_set(n, fds.res_ex);
1433 ret = do_select(n, &fds, &timeout);
1435 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1436 time_t sec = 0, usec = 0;
1437 if (timeout) {
1438 sec = timeout / HZ;
1439 usec = timeout % HZ;
1440 usec *= (1000000/HZ);
1442 put_user(sec, &tvp->tv_sec);
1443 put_user(usec, &tvp->tv_usec);
1446 if (ret < 0)
1447 goto out;
1448 if (!ret) {
1449 ret = -ERESTARTNOHAND;
1450 if (signal_pending(current))
1451 goto out;
1452 ret = 0;
1455 set_fd_set32(nn, inp, fds.res_in);
1456 set_fd_set32(nn, outp, fds.res_out);
1457 set_fd_set32(nn, exp, fds.res_ex);
1459 out:
1460 kfree(bits);
1461 out_nofds:
1462 return ret;
1465 static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1467 unsigned long ino, blksize, blocks;
1468 kdev_t dev, rdev;
1469 umode_t mode;
1470 nlink_t nlink;
1471 uid_t uid;
1472 gid_t gid;
1473 off_t size;
1474 time_t atime, mtime, ctime;
1475 int err;
1477 /* Stream the loads of inode data into the load buffer,
1478 * then we push it all into the store buffer below. This
1479 * should give optimal cache performance.
1481 ino = inode->i_ino;
1482 dev = inode->i_dev;
1483 mode = inode->i_mode;
1484 nlink = inode->i_nlink;
1485 uid = inode->i_uid;
1486 gid = inode->i_gid;
1487 rdev = inode->i_rdev;
1488 size = inode->i_size;
1489 atime = inode->i_atime;
1490 mtime = inode->i_mtime;
1491 ctime = inode->i_ctime;
1492 blksize = inode->i_blksize;
1493 blocks = inode->i_blocks;
1495 err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1496 err |= put_user(ino, &statbuf->st_ino);
1497 err |= put_user(mode, &statbuf->st_mode);
1498 err |= put_user(nlink, &statbuf->st_nlink);
1499 err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1500 err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1501 err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1502 err |= put_user(size, &statbuf->st_size);
1503 err |= put_user(atime, &statbuf->st_atime);
1504 err |= put_user(0, &statbuf->__unused1);
1505 err |= put_user(mtime, &statbuf->st_mtime);
1506 err |= put_user(0, &statbuf->__unused2);
1507 err |= put_user(ctime, &statbuf->st_ctime);
1508 err |= put_user(0, &statbuf->__unused3);
1509 if (blksize) {
1510 err |= put_user(blksize, &statbuf->st_blksize);
1511 err |= put_user(blocks, &statbuf->st_blocks);
1512 } else {
1513 unsigned int tmp_blocks;
1515 #define D_B 7
1516 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
1517 tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1518 if (tmp_blocks > D_B) {
1519 unsigned int indirect;
1521 indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1522 tmp_blocks += indirect;
1523 if (indirect > 1) {
1524 indirect = (indirect - 1 + I_B - 1) / I_B;
1525 tmp_blocks += indirect;
1526 if (indirect > 1)
1527 tmp_blocks++;
1530 err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1531 err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1532 #undef D_B
1533 #undef I_B
1535 err |= put_user(0, &statbuf->__unused4[0]);
1536 err |= put_user(0, &statbuf->__unused4[1]);
1538 return err;
1541 /* Perhaps this belongs in fs.h or similar. -DaveM */
1542 static __inline__ int
1543 do_revalidate(struct dentry *dentry)
1545 struct inode * inode = dentry->d_inode;
1546 if (inode->i_op && inode->i_op->revalidate)
1547 return inode->i_op->revalidate(dentry);
1548 return 0;
1551 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1553 struct nameidata nd;
1554 int error;
1556 error = user_path_walk(filename, &nd);
1557 if (!error) {
1558 error = do_revalidate(nd.dentry);
1559 if (!error)
1560 error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1561 path_release(&nd);
1563 return error;
1566 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1568 struct nameidata nd;
1569 int error;
1571 error = user_path_walk_link(filename, &nd);
1572 if (!error) {
1573 error = do_revalidate(nd.dentry);
1574 if (!error)
1575 error = cp_new_stat32(nd.dentry->d_inode, statbuf);
1577 path_release(&nd);
1579 return error;
1582 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1584 struct file *f;
1585 int err = -EBADF;
1587 f = fget(fd);
1588 if (f) {
1589 struct dentry * dentry = f->f_dentry;
1591 err = do_revalidate(dentry);
1592 if (!err)
1593 err = cp_new_stat32(dentry->d_inode, statbuf);
1594 fput(f);
1596 return err;
1599 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1601 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1603 return sys_sysfs(option, arg1, arg2);
1606 struct ncp_mount_data32 {
1607 int version;
1608 unsigned int ncp_fd;
1609 __kernel_uid_t32 mounted_uid;
1610 __kernel_pid_t32 wdog_pid;
1611 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1612 unsigned int time_out;
1613 unsigned int retry_count;
1614 unsigned int flags;
1615 __kernel_uid_t32 uid;
1616 __kernel_gid_t32 gid;
1617 __kernel_mode_t32 file_mode;
1618 __kernel_mode_t32 dir_mode;
1621 static void *do_ncp_super_data_conv(void *raw_data)
1623 struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
1624 struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
1626 n->dir_mode = n32->dir_mode;
1627 n->file_mode = n32->file_mode;
1628 n->gid = low2highgid(n32->gid);
1629 n->uid = low2highuid(n32->uid);
1630 memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
1631 n->wdog_pid = n32->wdog_pid;
1632 n->mounted_uid = low2highuid(n32->mounted_uid);
1633 return raw_data;
1636 struct smb_mount_data32 {
1637 int version;
1638 __kernel_uid_t32 mounted_uid;
1639 __kernel_uid_t32 uid;
1640 __kernel_gid_t32 gid;
1641 __kernel_mode_t32 file_mode;
1642 __kernel_mode_t32 dir_mode;
1645 static void *do_smb_super_data_conv(void *raw_data)
1647 struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
1648 struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1650 s->version = s32->version;
1651 s->mounted_uid = low2highuid(s32->mounted_uid);
1652 s->uid = low2highuid(s32->uid);
1653 s->gid = low2highgid(s32->gid);
1654 s->file_mode = s32->file_mode;
1655 s->dir_mode = s32->dir_mode;
1656 return raw_data;
1659 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1661 int i;
1662 unsigned long page;
1663 struct vm_area_struct *vma;
1665 *kernel = 0;
1666 if(!user)
1667 return 0;
1668 vma = find_vma(current->mm, (unsigned long)user);
1669 if(!vma || (unsigned long)user < vma->vm_start)
1670 return -EFAULT;
1671 if(!(vma->vm_flags & VM_READ))
1672 return -EFAULT;
1673 i = vma->vm_end - (unsigned long) user;
1674 if(PAGE_SIZE <= (unsigned long) i)
1675 i = PAGE_SIZE - 1;
1676 if(!(page = __get_free_page(GFP_KERNEL)))
1677 return -ENOMEM;
1678 if(copy_from_user((void *) page, user, i)) {
1679 free_page(page);
1680 return -EFAULT;
1682 *kernel = page;
1683 return 0;
1686 #define SMBFS_NAME "smbfs"
1687 #define NCPFS_NAME "ncpfs"
1689 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1691 unsigned long type_page = 0;
1692 unsigned long data_page = 0;
1693 unsigned long dev_page = 0;
1694 unsigned long dir_page = 0;
1695 int err, is_smb, is_ncp;
1697 is_smb = is_ncp = 0;
1699 err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1700 if (err)
1701 goto out;
1703 if (!type_page) {
1704 err = -EINVAL;
1705 goto out;
1708 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1709 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1711 err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1712 if (err)
1713 goto type_out;
1715 err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1716 if (err)
1717 goto data_out;
1719 err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1720 if (err)
1721 goto dev_out;
1723 if (!is_smb && !is_ncp) {
1724 lock_kernel();
1725 err = do_mount((char*)dev_page, (char*)dir_page,
1726 (char*)type_page, new_flags, (char*)data_page);
1727 unlock_kernel();
1728 } else {
1729 if (is_ncp)
1730 do_ncp_super_data_conv((void *)data_page);
1731 else
1732 do_smb_super_data_conv((void *)data_page);
1734 lock_kernel();
1735 err = do_mount((char*)dev_page, (char*)dir_page,
1736 (char*)type_page, new_flags, (char*)data_page);
1737 unlock_kernel();
1739 free_page(dir_page);
1741 dev_out:
1742 free_page(dev_page);
1744 data_out:
1745 free_page(data_page);
1747 type_out:
1748 free_page(type_page);
1750 out:
1751 return err;
1754 struct rusage32 {
1755 struct timeval32 ru_utime;
1756 struct timeval32 ru_stime;
1757 s32 ru_maxrss;
1758 s32 ru_ixrss;
1759 s32 ru_idrss;
1760 s32 ru_isrss;
1761 s32 ru_minflt;
1762 s32 ru_majflt;
1763 s32 ru_nswap;
1764 s32 ru_inblock;
1765 s32 ru_oublock;
1766 s32 ru_msgsnd;
1767 s32 ru_msgrcv;
1768 s32 ru_nsignals;
1769 s32 ru_nvcsw;
1770 s32 ru_nivcsw;
1773 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1775 int err;
1777 err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1778 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1779 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1780 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1781 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1782 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1783 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1784 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1785 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1786 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1787 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1788 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1789 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1790 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1791 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1792 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1793 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1794 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1795 return err;
1798 extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
1799 int options, struct rusage * ru);
1801 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1803 if (!ru)
1804 return sys_wait4(pid, stat_addr, options, NULL);
1805 else {
1806 struct rusage r;
1807 int ret;
1808 unsigned int status;
1809 mm_segment_t old_fs = get_fs();
1811 set_fs (KERNEL_DS);
1812 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1813 set_fs (old_fs);
1814 if (put_rusage (ru, &r)) return -EFAULT;
1815 if (stat_addr && put_user (status, stat_addr))
1816 return -EFAULT;
1817 return ret;
1821 struct sysinfo32 {
1822 s32 uptime;
1823 u32 loads[3];
1824 u32 totalram;
1825 u32 freeram;
1826 u32 sharedram;
1827 u32 bufferram;
1828 u32 totalswap;
1829 u32 freeswap;
1830 unsigned short procs;
1831 char _f[22];
1834 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1836 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1838 struct sysinfo s;
1839 int ret, err;
1840 mm_segment_t old_fs = get_fs ();
1842 set_fs (KERNEL_DS);
1843 ret = sys_sysinfo(&s);
1844 set_fs (old_fs);
1845 err = put_user (s.uptime, &info->uptime);
1846 err |= __put_user (s.loads[0], &info->loads[0]);
1847 err |= __put_user (s.loads[1], &info->loads[1]);
1848 err |= __put_user (s.loads[2], &info->loads[2]);
1849 err |= __put_user (s.totalram, &info->totalram);
1850 err |= __put_user (s.freeram, &info->freeram);
1851 err |= __put_user (s.sharedram, &info->sharedram);
1852 err |= __put_user (s.bufferram, &info->bufferram);
1853 err |= __put_user (s.totalswap, &info->totalswap);
1854 err |= __put_user (s.freeswap, &info->freeswap);
1855 err |= __put_user (s.procs, &info->procs);
1856 if (err)
1857 return -EFAULT;
1858 return ret;
1861 struct timespec32 {
1862 s32 tv_sec;
1863 s32 tv_nsec;
1866 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1868 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1870 struct timespec t;
1871 int ret;
1872 mm_segment_t old_fs = get_fs ();
1874 set_fs (KERNEL_DS);
1875 ret = sys_sched_rr_get_interval(pid, &t);
1876 set_fs (old_fs);
1877 if (put_user (t.tv_sec, &interval->tv_sec) ||
1878 __put_user (t.tv_nsec, &interval->tv_nsec))
1879 return -EFAULT;
1880 return ret;
1883 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1885 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1887 struct timespec t;
1888 int ret;
1889 mm_segment_t old_fs = get_fs ();
1891 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1892 __get_user (t.tv_nsec, &rqtp->tv_nsec))
1893 return -EFAULT;
1894 set_fs (KERNEL_DS);
1895 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1896 set_fs (old_fs);
1897 if (rmtp && ret == -EINTR) {
1898 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1899 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1900 return -EFAULT;
1902 return ret;
1905 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1907 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1909 old_sigset_t s;
1910 int ret;
1911 mm_segment_t old_fs = get_fs();
1913 if (set && get_user (s, set)) return -EFAULT;
1914 set_fs (KERNEL_DS);
1915 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1916 set_fs (old_fs);
1917 if (ret) return ret;
1918 if (oset && put_user (s, oset)) return -EFAULT;
1919 return 0;
1922 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
1924 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
1926 sigset_t s;
1927 sigset_t32 s32;
1928 int ret;
1929 mm_segment_t old_fs = get_fs();
1931 if (set) {
1932 if (copy_from_user (&s32, set, sizeof(sigset_t32)))
1933 return -EFAULT;
1934 switch (_NSIG_WORDS) {
1935 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
1936 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
1937 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1938 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1941 set_fs (KERNEL_DS);
1942 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
1943 set_fs (old_fs);
1944 if (ret) return ret;
1945 if (oset) {
1946 switch (_NSIG_WORDS) {
1947 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1948 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1949 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1950 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1952 if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
1953 return -EFAULT;
1955 return 0;
1958 extern asmlinkage int sys_sigpending(old_sigset_t *set);
1960 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
1962 old_sigset_t s;
1963 int ret;
1964 mm_segment_t old_fs = get_fs();
1966 set_fs (KERNEL_DS);
1967 ret = sys_sigpending(&s);
1968 set_fs (old_fs);
1969 if (put_user (s, set)) return -EFAULT;
1970 return ret;
1973 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
1975 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
1977 sigset_t s;
1978 sigset_t32 s32;
1979 int ret;
1980 mm_segment_t old_fs = get_fs();
1982 set_fs (KERNEL_DS);
1983 ret = sys_rt_sigpending(&s, sigsetsize);
1984 set_fs (old_fs);
1985 if (!ret) {
1986 switch (_NSIG_WORDS) {
1987 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1988 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1989 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1990 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1992 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
1993 return -EFAULT;
1995 return ret;
1998 asmlinkage int
1999 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
2000 struct timespec32 *uts, __kernel_size_t32 sigsetsize)
2002 int ret, sig;
2003 sigset_t these;
2004 sigset_t32 these32;
2005 struct timespec ts;
2006 siginfo_t info;
2007 long timeout = 0;
2009 /* XXX: Don't preclude handling different sized sigset_t's. */
2010 if (sigsetsize != sizeof(sigset_t))
2011 return -EINVAL;
2013 if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
2014 return -EFAULT;
2016 switch (_NSIG_WORDS) {
2017 case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
2018 case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
2019 case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
2020 case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
2024 * Invert the set of allowed signals to get those we
2025 * want to block.
2027 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2028 signotset(&these);
2030 if (uts) {
2031 if (get_user (ts.tv_sec, &uts->tv_sec) ||
2032 get_user (ts.tv_nsec, &uts->tv_nsec))
2033 return -EINVAL;
2034 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
2035 || ts.tv_sec < 0)
2036 return -EINVAL;
2039 spin_lock_irq(&current->sigmask_lock);
2040 sig = dequeue_signal(&these, &info);
2041 if (!sig) {
2042 /* None ready -- temporarily unblock those we're interested
2043 in so that we'll be awakened when they arrive. */
2044 sigset_t oldblocked = current->blocked;
2045 sigandsets(&current->blocked, &current->blocked, &these);
2046 recalc_sigpending(current);
2047 spin_unlock_irq(&current->sigmask_lock);
2049 timeout = MAX_SCHEDULE_TIMEOUT;
2050 if (uts)
2051 timeout = (timespec_to_jiffies(&ts)
2052 + (ts.tv_sec || ts.tv_nsec));
2054 current->state = TASK_INTERRUPTIBLE;
2055 timeout = schedule_timeout(timeout);
2057 spin_lock_irq(&current->sigmask_lock);
2058 sig = dequeue_signal(&these, &info);
2059 current->blocked = oldblocked;
2060 recalc_sigpending(current);
2062 spin_unlock_irq(&current->sigmask_lock);
2064 if (sig) {
2065 ret = sig;
2066 if (uinfo) {
2067 if (copy_siginfo_to_user32(uinfo, &info))
2068 ret = -EFAULT;
2070 } else {
2071 ret = -EAGAIN;
2072 if (timeout)
2073 ret = -EINTR;
2076 return ret;
2079 extern asmlinkage int
2080 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2082 asmlinkage int
2083 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2085 siginfo_t info;
2086 int ret;
2087 mm_segment_t old_fs = get_fs();
2089 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2090 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2091 return -EFAULT;
2092 set_fs (KERNEL_DS);
2093 ret = sys_rt_sigqueueinfo(pid, sig, &info);
2094 set_fs (old_fs);
2095 return ret;
2098 struct tms32 {
2099 __kernel_clock_t32 tms_utime;
2100 __kernel_clock_t32 tms_stime;
2101 __kernel_clock_t32 tms_cutime;
2102 __kernel_clock_t32 tms_cstime;
2105 extern asmlinkage long sys_times(struct tms * tbuf);
2107 asmlinkage long sys32_times(struct tms32 *tbuf)
2109 struct tms t;
2110 long ret;
2111 mm_segment_t old_fs = get_fs ();
2112 int err;
2114 set_fs (KERNEL_DS);
2115 ret = sys_times(tbuf ? &t : NULL);
2116 set_fs (old_fs);
2117 if (tbuf) {
2118 err = put_user (t.tms_utime, &tbuf->tms_utime);
2119 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2120 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2121 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2122 if (err)
2123 ret = -EFAULT;
2125 return ret;
2128 #define RLIM_INFINITY32 0x7fffffff
2129 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2131 struct rlimit32 {
2132 u32 rlim_cur;
2133 u32 rlim_max;
2136 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2138 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2140 struct rlimit r;
2141 int ret;
2142 mm_segment_t old_fs = get_fs ();
2144 set_fs (KERNEL_DS);
2145 ret = sys_getrlimit(resource, &r);
2146 set_fs (old_fs);
2147 if (!ret) {
2148 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2149 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2151 return ret;
2154 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2156 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2158 struct rlimit r;
2159 int ret;
2160 mm_segment_t old_fs = get_fs ();
2162 if (resource >= RLIM_NLIMITS) return -EINVAL;
2163 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2164 __get_user (r.rlim_max, &rlim->rlim_max))
2165 return -EFAULT;
2166 if (r.rlim_cur == RLIM_INFINITY32)
2167 r.rlim_cur = RLIM_INFINITY;
2168 if (r.rlim_max == RLIM_INFINITY32)
2169 r.rlim_max = RLIM_INFINITY;
2170 set_fs (KERNEL_DS);
2171 ret = sys_setrlimit(resource, &r);
2172 set_fs (old_fs);
2173 return ret;
2176 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2178 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2180 struct rusage r;
2181 int ret;
2182 mm_segment_t old_fs = get_fs();
2184 set_fs (KERNEL_DS);
2185 ret = sys_getrusage(who, &r);
2186 set_fs (old_fs);
2187 if (put_rusage (ru, &r)) return -EFAULT;
2188 return ret;
2191 /* XXX This really belongs in some header file... -DaveM */
2192 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2193 16 for IP, 16 for IPX,
2194 24 for IPv6,
2195 about 80 for AX.25 */
2197 extern struct socket *sockfd_lookup(int fd, int *err);
2199 /* XXX This as well... */
2200 extern __inline__ void sockfd_put(struct socket *sock)
2202 fput(sock->file);
2205 struct msghdr32 {
2206 u32 msg_name;
2207 int msg_namelen;
2208 u32 msg_iov;
2209 __kernel_size_t32 msg_iovlen;
2210 u32 msg_control;
2211 __kernel_size_t32 msg_controllen;
2212 unsigned msg_flags;
2215 struct cmsghdr32 {
2216 __kernel_size_t32 cmsg_len;
2217 int cmsg_level;
2218 int cmsg_type;
2221 /* Bleech... */
2222 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2223 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2225 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2227 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2228 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2229 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2231 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2232 (struct cmsghdr32 *)(ctl) : \
2233 (struct cmsghdr32 *)NULL)
2234 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2236 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2237 struct cmsghdr32 *__cmsg, int __cmsg_len)
2239 struct cmsghdr32 * __ptr;
2241 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2242 CMSG32_ALIGN(__cmsg_len));
2243 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2244 return NULL;
2246 return __ptr;
2249 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2250 struct cmsghdr32 *__cmsg,
2251 int __cmsg_len)
2253 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2254 __cmsg, __cmsg_len);
2257 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2258 struct iovec32 *uiov32,
2259 int niov)
2261 int tot_len = 0;
2263 while(niov > 0) {
2264 u32 len, buf;
2266 if(get_user(len, &uiov32->iov_len) ||
2267 get_user(buf, &uiov32->iov_base)) {
2268 tot_len = -EFAULT;
2269 break;
2271 tot_len += len;
2272 kiov->iov_base = (void *)A(buf);
2273 kiov->iov_len = (__kernel_size_t) len;
2274 uiov32++;
2275 kiov++;
2276 niov--;
2278 return tot_len;
2281 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2282 struct msghdr32 *umsg)
2284 u32 tmp1, tmp2, tmp3;
2285 int err;
2287 err = get_user(tmp1, &umsg->msg_name);
2288 err |= __get_user(tmp2, &umsg->msg_iov);
2289 err |= __get_user(tmp3, &umsg->msg_control);
2290 if (err)
2291 return -EFAULT;
2293 kmsg->msg_name = (void *)A(tmp1);
2294 kmsg->msg_iov = (struct iovec *)A(tmp2);
2295 kmsg->msg_control = (void *)A(tmp3);
2297 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2298 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2299 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2300 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2302 return err;
2305 /* I've named the args so it is easy to tell whose space the pointers are in. */
2306 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2307 char *kern_address, int mode)
2309 int tot_len;
2311 if(kern_msg->msg_namelen) {
2312 if(mode==VERIFY_READ) {
2313 int err = move_addr_to_kernel(kern_msg->msg_name,
2314 kern_msg->msg_namelen,
2315 kern_address);
2316 if(err < 0)
2317 return err;
2319 kern_msg->msg_name = kern_address;
2320 } else
2321 kern_msg->msg_name = NULL;
2323 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2324 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2325 GFP_KERNEL);
2326 if(!kern_iov)
2327 return -ENOMEM;
2330 tot_len = iov_from_user32_to_kern(kern_iov,
2331 (struct iovec32 *)kern_msg->msg_iov,
2332 kern_msg->msg_iovlen);
2333 if(tot_len >= 0)
2334 kern_msg->msg_iov = kern_iov;
2335 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2336 kfree(kern_iov);
2338 return tot_len;
2341 /* There is a lot of hair here because the alignment rules (and
2342 * thus placement) of cmsg headers and length are different for
2343 * 32-bit apps. -DaveM
2345 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2346 unsigned char *stackbuf, int stackbuf_size)
2348 struct cmsghdr32 *ucmsg;
2349 struct cmsghdr *kcmsg, *kcmsg_base;
2350 __kernel_size_t32 ucmlen;
2351 __kernel_size_t kcmlen, tmp;
2353 kcmlen = 0;
2354 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2355 ucmsg = CMSG32_FIRSTHDR(kmsg);
2356 while(ucmsg != NULL) {
2357 if(get_user(ucmlen, &ucmsg->cmsg_len))
2358 return -EFAULT;
2360 /* Catch bogons. */
2361 if(CMSG32_ALIGN(ucmlen) <
2362 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2363 return -EINVAL;
2364 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2365 + ucmlen) > kmsg->msg_controllen)
2366 return -EINVAL;
2368 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2369 CMSG_ALIGN(sizeof(struct cmsghdr)));
2370 kcmlen += tmp;
2371 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2373 if(kcmlen == 0)
2374 return -EINVAL;
2376 /* The kcmlen holds the 64-bit version of the control length.
2377 * It may not be modified as we do not stick it into the kmsg
2378 * until we have successfully copied over all of the data
2379 * from the user.
2381 if(kcmlen > stackbuf_size)
2382 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2383 if(kcmsg == NULL)
2384 return -ENOBUFS;
2386 /* Now copy them over neatly. */
2387 memset(kcmsg, 0, kcmlen);
2388 ucmsg = CMSG32_FIRSTHDR(kmsg);
2389 while(ucmsg != NULL) {
2390 __get_user(ucmlen, &ucmsg->cmsg_len);
2391 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2392 CMSG_ALIGN(sizeof(struct cmsghdr)));
2393 kcmsg->cmsg_len = tmp;
2394 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2395 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2397 /* Copy over the data. */
2398 if(copy_from_user(CMSG_DATA(kcmsg),
2399 CMSG32_DATA(ucmsg),
2400 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2401 goto out_free_efault;
2403 /* Advance. */
2404 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2405 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2408 /* Ok, looks like we made it. Hook it up and return success. */
2409 kmsg->msg_control = kcmsg_base;
2410 kmsg->msg_controllen = kcmlen;
2411 return 0;
2413 out_free_efault:
2414 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2415 kfree(kcmsg_base);
2416 return -EFAULT;
2419 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2420 int len, void *data)
2422 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2423 struct cmsghdr32 cmhdr;
2424 int cmlen = CMSG32_LEN(len);
2426 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2427 kmsg->msg_flags |= MSG_CTRUNC;
2428 return;
2431 if(kmsg->msg_controllen < cmlen) {
2432 kmsg->msg_flags |= MSG_CTRUNC;
2433 cmlen = kmsg->msg_controllen;
2435 cmhdr.cmsg_level = level;
2436 cmhdr.cmsg_type = type;
2437 cmhdr.cmsg_len = cmlen;
2439 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2440 return;
2441 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2442 return;
2443 cmlen = CMSG32_SPACE(len);
2444 kmsg->msg_control += cmlen;
2445 kmsg->msg_controllen -= cmlen;
2448 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2450 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2451 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2452 int fdnum = scm->fp->count;
2453 struct file **fp = scm->fp->fp;
2454 int *cmfptr;
2455 int err = 0, i;
2457 if (fdnum < fdmax)
2458 fdmax = fdnum;
2460 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2461 int new_fd;
2462 err = get_unused_fd();
2463 if (err < 0)
2464 break;
2465 new_fd = err;
2466 err = put_user(new_fd, cmfptr);
2467 if (err) {
2468 put_unused_fd(new_fd);
2469 break;
2471 /* Bump the usage count and install the file. */
2472 get_file(fp[i]);
2473 fd_install(new_fd, fp[i]);
2476 if (i > 0) {
2477 int cmlen = CMSG32_LEN(i * sizeof(int));
2478 if (!err)
2479 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2480 if (!err)
2481 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2482 if (!err)
2483 err = put_user(cmlen, &cm->cmsg_len);
2484 if (!err) {
2485 cmlen = CMSG32_SPACE(i * sizeof(int));
2486 kmsg->msg_control += cmlen;
2487 kmsg->msg_controllen -= cmlen;
2490 if (i < fdnum)
2491 kmsg->msg_flags |= MSG_CTRUNC;
2494 * All of the files that fit in the message have had their
2495 * usage counts incremented, so we just free the list.
2497 __scm_destroy(scm);
2500 /* In these cases we (currently) can just copy to data over verbatim
2501 * because all CMSGs created by the kernel have well defined types which
2502 * have the same layout in both the 32-bit and 64-bit API. One must add
2503 * some special cased conversions here if we start sending control messages
2504 * with incompatible types.
2506 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2507 * we do our work. The remaining cases are:
2509 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2510 * IP_TTL int 32-bit clean
2511 * IP_TOS __u8 32-bit clean
2512 * IP_RECVOPTS variable length 32-bit clean
2513 * IP_RETOPTS variable length 32-bit clean
2514 * (these last two are clean because the types are defined
2515 * by the IPv4 protocol)
2516 * IP_RECVERR struct sock_extended_err +
2517 * struct sockaddr_in 32-bit clean
2518 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2519 * struct sockaddr_in6 32-bit clean
2520 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2521 * IPV6_HOPLIMIT int 32-bit clean
2522 * IPV6_FLOWINFO u32 32-bit clean
2523 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2524 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2525 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2526 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2528 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2530 unsigned char *workbuf, *wp;
2531 unsigned long bufsz, space_avail;
2532 struct cmsghdr *ucmsg;
2534 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2535 space_avail = kmsg->msg_controllen + bufsz;
2536 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2537 if(workbuf == NULL)
2538 goto fail;
2540 /* To make this more sane we assume the kernel sends back properly
2541 * formatted control messages. Because of how the kernel will truncate
2542 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2544 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2545 while(((unsigned long)ucmsg) <=
2546 (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2547 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2548 int clen64, clen32;
2550 /* UCMSG is the 64-bit format CMSG entry in user-space.
2551 * KCMSG32 is within the kernel space temporary buffer
2552 * we use to convert into a 32-bit style CMSG.
2554 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2555 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2556 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2558 clen64 = kcmsg32->cmsg_len;
2559 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2560 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2561 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2562 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2563 kcmsg32->cmsg_len = clen32;
2565 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2566 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2569 /* Copy back fixed up data, and adjust pointers. */
2570 bufsz = (wp - workbuf);
2571 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2573 kmsg->msg_control = (struct cmsghdr *)
2574 (((char *)orig_cmsg_uptr) + bufsz);
2575 kmsg->msg_controllen = space_avail - bufsz;
2577 kfree(workbuf);
2578 return;
2580 fail:
2581 /* If we leave the 64-bit format CMSG chunks in there,
2582 * the application could get confused and crash. So to
2583 * ensure greater recovery, we report no CMSGs.
2585 kmsg->msg_controllen += bufsz;
2586 kmsg->msg_control = (void *) orig_cmsg_uptr;
2589 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2591 struct socket *sock;
2592 char address[MAX_SOCK_ADDR];
2593 struct iovec iov[UIO_FASTIOV];
2594 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2595 unsigned char *ctl_buf = ctl;
2596 struct msghdr kern_msg;
2597 int err, total_len;
2599 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2600 return -EFAULT;
2601 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2602 return -EINVAL;
2603 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2604 if (err < 0)
2605 goto out;
2606 total_len = err;
2608 if(kern_msg.msg_controllen) {
2609 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2610 if(err)
2611 goto out_freeiov;
2612 ctl_buf = kern_msg.msg_control;
2614 kern_msg.msg_flags = user_flags;
2616 sock = sockfd_lookup(fd, &err);
2617 if (sock != NULL) {
2618 if (sock->file->f_flags & O_NONBLOCK)
2619 kern_msg.msg_flags |= MSG_DONTWAIT;
2620 err = sock_sendmsg(sock, &kern_msg, total_len);
2621 sockfd_put(sock);
2624 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2625 if(ctl_buf != ctl)
2626 kfree(ctl_buf);
2627 out_freeiov:
2628 if(kern_msg.msg_iov != iov)
2629 kfree(kern_msg.msg_iov);
2630 out:
2631 return err;
2634 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2636 struct iovec iovstack[UIO_FASTIOV];
2637 struct msghdr kern_msg;
2638 char addr[MAX_SOCK_ADDR];
2639 struct socket *sock;
2640 struct iovec *iov = iovstack;
2641 struct sockaddr *uaddr;
2642 int *uaddr_len;
2643 unsigned long cmsg_ptr;
2644 int err, total_len, len = 0;
2646 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2647 return -EFAULT;
2648 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2649 return -EINVAL;
2651 uaddr = kern_msg.msg_name;
2652 uaddr_len = &user_msg->msg_namelen;
2653 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2654 if (err < 0)
2655 goto out;
2656 total_len = err;
2658 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2659 kern_msg.msg_flags = 0;
2661 sock = sockfd_lookup(fd, &err);
2662 if (sock != NULL) {
2663 struct scm_cookie scm;
2665 if (sock->file->f_flags & O_NONBLOCK)
2666 user_flags |= MSG_DONTWAIT;
2667 memset(&scm, 0, sizeof(scm));
2668 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2669 user_flags, &scm);
2670 if(err >= 0) {
2671 len = err;
2672 if(!kern_msg.msg_control) {
2673 if(sock->passcred || scm.fp)
2674 kern_msg.msg_flags |= MSG_CTRUNC;
2675 if(scm.fp)
2676 __scm_destroy(&scm);
2677 } else {
2678 /* If recvmsg processing itself placed some
2679 * control messages into user space, it's is
2680 * using 64-bit CMSG processing, so we need
2681 * to fix it up before we tack on more stuff.
2683 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2684 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2686 /* Wheee... */
2687 if(sock->passcred)
2688 put_cmsg32(&kern_msg,
2689 SOL_SOCKET, SCM_CREDENTIALS,
2690 sizeof(scm.creds), &scm.creds);
2691 if(scm.fp != NULL)
2692 scm_detach_fds32(&kern_msg, &scm);
2695 sockfd_put(sock);
2698 if(uaddr != NULL && err >= 0)
2699 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2700 if(cmsg_ptr != 0 && err >= 0) {
2701 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2702 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2703 err |= __put_user(uclen, &user_msg->msg_controllen);
2705 if(err >= 0)
2706 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2707 if(kern_msg.msg_iov != iov)
2708 kfree(kern_msg.msg_iov);
2709 out:
2710 if(err < 0)
2711 return err;
2712 return len;
2715 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2716 char *optval, int optlen);
2718 static int do_set_attach_filter(int fd, int level, int optname,
2719 char *optval, int optlen)
2721 struct sock_fprog32 {
2722 __u16 len;
2723 __u32 filter;
2724 } *fprog32 = (struct sock_fprog32 *)optval;
2725 struct sock_fprog kfprog;
2726 struct sock_filter *kfilter;
2727 unsigned int fsize;
2728 mm_segment_t old_fs;
2729 __u32 uptr;
2730 int ret;
2732 if (get_user(kfprog.len, &fprog32->len) ||
2733 __get_user(uptr, &fprog32->filter))
2734 return -EFAULT;
2736 kfprog.filter = (struct sock_filter *)A(uptr);
2737 fsize = kfprog.len * sizeof(struct sock_filter);
2739 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2740 if (kfilter == NULL)
2741 return -ENOMEM;
2743 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2744 kfree(kfilter);
2745 return -EFAULT;
2748 kfprog.filter = kfilter;
2750 old_fs = get_fs();
2751 set_fs(KERNEL_DS);
2752 ret = sys_setsockopt(fd, level, optname,
2753 (char *)&kfprog, sizeof(kfprog));
2754 set_fs(old_fs);
2756 kfree(kfilter);
2758 return ret;
2761 static int do_set_icmpv6_filter(int fd, int level, int optname,
2762 char *optval, int optlen)
2764 struct icmp6_filter kfilter;
2765 mm_segment_t old_fs;
2766 int ret, i;
2768 if (copy_from_user(&kfilter, optval, sizeof(kfilter)))
2769 return -EFAULT;
2772 for (i = 0; i < 8; i += 2) {
2773 u32 tmp = kfilter.data[i];
2775 kfilter.data[i] = kfilter.data[i + 1];
2776 kfilter.data[i + 1] = tmp;
2779 old_fs = get_fs();
2780 set_fs(KERNEL_DS);
2781 ret = sys_setsockopt(fd, level, optname,
2782 (char *) &kfilter, sizeof(kfilter));
2783 set_fs(old_fs);
2785 return ret;
2788 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2789 char *optval, int optlen)
2791 if (optname == SO_ATTACH_FILTER)
2792 return do_set_attach_filter(fd, level, optname,
2793 optval, optlen);
2794 if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)
2795 return do_set_icmpv6_filter(fd, level, optname,
2796 optval, optlen);
2798 return sys_setsockopt(fd, level, optname, optval, optlen);
2801 extern void check_pending(int signum);
2803 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2805 struct k_sigaction new_ka, old_ka;
2806 int ret;
2808 if(sig < 0) {
2809 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2810 sig = -sig;
2813 if (act) {
2814 old_sigset_t32 mask;
2816 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2817 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2818 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2819 ret |= __get_user(mask, &act->sa_mask);
2820 if (ret)
2821 return ret;
2822 new_ka.ka_restorer = NULL;
2823 siginitset(&new_ka.sa.sa_mask, mask);
2826 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2828 if (!ret && oact) {
2829 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2830 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2831 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2832 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2835 return ret;
2838 asmlinkage int
2839 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2840 void *restorer, __kernel_size_t32 sigsetsize)
2842 struct k_sigaction new_ka, old_ka;
2843 int ret;
2844 sigset_t32 set32;
2846 /* XXX: Don't preclude handling different sized sigset_t's. */
2847 if (sigsetsize != sizeof(sigset_t32))
2848 return -EINVAL;
2850 /* All tasks which use RT signals (effectively) use
2851 * new style signals.
2853 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2855 if (act) {
2856 new_ka.ka_restorer = restorer;
2857 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2858 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2859 switch (_NSIG_WORDS) {
2860 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2861 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2862 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2863 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2865 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2866 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2867 if (ret)
2868 return -EFAULT;
2871 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2873 if (!ret && oact) {
2874 switch (_NSIG_WORDS) {
2875 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
2876 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
2877 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
2878 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
2880 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2881 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
2882 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2883 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2886 return ret;
2891 * count32() counts the number of arguments/envelopes
2893 static int count32(u32 * argv)
2895 int i = 0;
2897 if (argv != NULL) {
2898 for (;;) {
2899 u32 p; int error;
2901 error = get_user(p,argv);
2902 if (error) return error;
2903 if (!p) break;
2904 argv++; i++;
2907 return i;
2911 * 'copy_string32()' copies argument/envelope strings from user
2912 * memory to free pages in kernel mem. These are in a format ready
2913 * to be put directly into the top of new user memory.
2915 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
2917 while (argc-- > 0) {
2918 u32 str;
2919 int len;
2920 unsigned long pos;
2922 if (get_user(str, argv + argc) ||
2923 !str ||
2924 !(len = strnlen_user((char *)A(str), bprm->p)))
2925 return -EFAULT;
2927 if (bprm->p < len)
2928 return -E2BIG;
2930 bprm->p -= len;
2932 pos = bprm->p;
2933 while (len) {
2934 char *kaddr;
2935 struct page *page;
2936 int offset, bytes_to_copy, new, err;
2938 offset = pos % PAGE_SIZE;
2939 page = bprm->page[pos / PAGE_SIZE];
2940 new = 0;
2941 if (!page) {
2942 page = alloc_page(GFP_USER);
2943 bprm->page[pos / PAGE_SIZE] = page;
2944 if (!page)
2945 return -ENOMEM;
2946 new = 1;
2948 kaddr = (char *)kmap(page);
2950 if (new && offset)
2951 memset(kaddr, 0, offset);
2952 bytes_to_copy = PAGE_SIZE - offset;
2953 if (bytes_to_copy > len) {
2954 bytes_to_copy = len;
2955 if (new)
2956 memset(kaddr+offset+len, 0,
2957 PAGE_SIZE-offset-len);
2960 err = copy_from_user(kaddr + offset, (char *)A(str),
2961 bytes_to_copy);
2962 flush_page_to_ram(page);
2963 kunmap((unsigned long)kaddr);
2965 if (err)
2966 return -EFAULT;
2968 pos += bytes_to_copy;
2969 str += bytes_to_copy;
2970 len -= bytes_to_copy;
2973 return 0;
2977 * sys32_execve() executes a new program.
2979 static inline int
2980 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
2982 struct linux_binprm bprm;
2983 struct file * file;
2984 int retval;
2985 int i;
2987 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2988 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
2990 file = open_exec(filename);
2992 retval = PTR_ERR(file);
2993 if (IS_ERR(file))
2994 return retval;
2996 bprm.file = file;
2997 bprm.filename = filename;
2998 bprm.sh_bang = 0;
2999 bprm.loader = 0;
3000 bprm.exec = 0;
3001 if ((bprm.argc = count32(argv)) < 0) {
3002 allow_write_access(file);
3003 fput(file);
3004 return bprm.argc;
3006 if ((bprm.envc = count32(envp)) < 0) {
3007 allow_write_access(file);
3008 fput(file);
3009 return bprm.envc;
3012 retval = prepare_binprm(&bprm);
3013 if (retval < 0)
3014 goto out;
3016 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3017 if (retval < 0)
3018 goto out;
3020 bprm.exec = bprm.p;
3021 retval = copy_strings32(bprm.envc, envp, &bprm);
3022 if (retval < 0)
3023 goto out;
3025 retval = copy_strings32(bprm.argc, argv, &bprm);
3026 if (retval < 0)
3027 goto out;
3029 retval = search_binary_handler(&bprm, regs);
3030 if (retval >= 0)
3031 /* execve success */
3032 return retval;
3034 out:
3035 /* Something went wrong, return the inode and free the argument pages*/
3036 allow_write_access(bprm.file);
3037 if (bprm.file)
3038 fput(bprm.file);
3040 for (i=0 ; i<MAX_ARG_PAGES ; i++)
3041 if (bprm.page[i])
3042 __free_page(bprm.page[i]);
3044 return retval;
3048 * sparc32_execve() executes a new program after the asm stub has set
3049 * things up for us. This should basically do what I want it to.
3051 asmlinkage int sparc32_execve(struct pt_regs *regs)
3053 int error, base = 0;
3054 char *filename;
3056 /* User register window flush is done by entry.S */
3058 /* Check for indirect call. */
3059 if((u32)regs->u_regs[UREG_G1] == 0)
3060 base = 1;
3062 filename = getname((char *)AA(regs->u_regs[base + UREG_I0]));
3063 error = PTR_ERR(filename);
3064 if(IS_ERR(filename))
3065 goto out;
3066 error = do_execve32(filename,
3067 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3068 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3069 putname(filename);
3071 if(!error) {
3072 fprs_write(0);
3073 current->thread.xfsr[0] = 0;
3074 current->thread.fpsaved[0] = 0;
3075 regs->tstate &= ~TSTATE_PEF;
3077 out:
3078 return error;
3081 #ifdef CONFIG_MODULES
3083 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3085 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3087 return sys_create_module(name_user, (size_t)size);
3090 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3092 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3093 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3095 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3097 return sys_init_module(name_user, mod_user);
3100 extern asmlinkage int sys_delete_module(const char *name_user);
3102 asmlinkage int sys32_delete_module(const char *name_user)
3104 return sys_delete_module(name_user);
3107 struct module_info32 {
3108 u32 addr;
3109 u32 size;
3110 u32 flags;
3111 s32 usecount;
3114 /* Query various bits about modules. */
3116 static inline long
3117 get_mod_name(const char *user_name, char **buf)
3119 unsigned long page;
3120 long retval;
3122 if ((unsigned long)user_name >= TASK_SIZE
3123 && !segment_eq(get_fs (), KERNEL_DS))
3124 return -EFAULT;
3126 page = __get_free_page(GFP_KERNEL);
3127 if (!page)
3128 return -ENOMEM;
3130 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3131 if (retval > 0) {
3132 if (retval < PAGE_SIZE) {
3133 *buf = (char *)page;
3134 return retval;
3136 retval = -ENAMETOOLONG;
3137 } else if (!retval)
3138 retval = -EINVAL;
3140 free_page(page);
3141 return retval;
3144 static inline void
3145 put_mod_name(char *buf)
3147 free_page((unsigned long)buf);
3150 static __inline__ struct module *find_module(const char *name)
3152 struct module *mod;
3154 for (mod = module_list; mod ; mod = mod->next) {
3155 if (mod->flags & MOD_DELETED)
3156 continue;
3157 if (!strcmp(mod->name, name))
3158 break;
3161 return mod;
3164 static int
3165 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3167 struct module *mod;
3168 size_t nmod, space, len;
3170 nmod = space = 0;
3172 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3173 len = strlen(mod->name)+1;
3174 if (len > bufsize)
3175 goto calc_space_needed;
3176 if (copy_to_user(buf, mod->name, len))
3177 return -EFAULT;
3178 buf += len;
3179 bufsize -= len;
3180 space += len;
3183 if (put_user(nmod, ret))
3184 return -EFAULT;
3185 else
3186 return 0;
3188 calc_space_needed:
3189 space += len;
3190 while ((mod = mod->next)->next != NULL)
3191 space += strlen(mod->name)+1;
3193 if (put_user(space, ret))
3194 return -EFAULT;
3195 else
3196 return -ENOSPC;
3199 static int
3200 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3202 size_t i, space, len;
3204 if (mod->next == NULL)
3205 return -EINVAL;
3206 if (!MOD_CAN_QUERY(mod))
3207 return put_user(0, ret);
3209 space = 0;
3210 for (i = 0; i < mod->ndeps; ++i) {
3211 const char *dep_name = mod->deps[i].dep->name;
3213 len = strlen(dep_name)+1;
3214 if (len > bufsize)
3215 goto calc_space_needed;
3216 if (copy_to_user(buf, dep_name, len))
3217 return -EFAULT;
3218 buf += len;
3219 bufsize -= len;
3220 space += len;
3223 return put_user(i, ret);
3225 calc_space_needed:
3226 space += len;
3227 while (++i < mod->ndeps)
3228 space += strlen(mod->deps[i].dep->name)+1;
3230 if (put_user(space, ret))
3231 return -EFAULT;
3232 else
3233 return -ENOSPC;
3236 static int
3237 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3239 size_t nrefs, space, len;
3240 struct module_ref *ref;
3242 if (mod->next == NULL)
3243 return -EINVAL;
3244 if (!MOD_CAN_QUERY(mod))
3245 if (put_user(0, ret))
3246 return -EFAULT;
3247 else
3248 return 0;
3250 space = 0;
3251 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3252 const char *ref_name = ref->ref->name;
3254 len = strlen(ref_name)+1;
3255 if (len > bufsize)
3256 goto calc_space_needed;
3257 if (copy_to_user(buf, ref_name, len))
3258 return -EFAULT;
3259 buf += len;
3260 bufsize -= len;
3261 space += len;
3264 if (put_user(nrefs, ret))
3265 return -EFAULT;
3266 else
3267 return 0;
3269 calc_space_needed:
3270 space += len;
3271 while ((ref = ref->next_ref) != NULL)
3272 space += strlen(ref->ref->name)+1;
3274 if (put_user(space, ret))
3275 return -EFAULT;
3276 else
3277 return -ENOSPC;
3280 static inline int
3281 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3283 size_t i, space, len;
3284 struct module_symbol *s;
3285 char *strings;
3286 unsigned *vals;
3288 if (!MOD_CAN_QUERY(mod))
3289 if (put_user(0, ret))
3290 return -EFAULT;
3291 else
3292 return 0;
3294 space = mod->nsyms * 2*sizeof(u32);
3296 i = len = 0;
3297 s = mod->syms;
3299 if (space > bufsize)
3300 goto calc_space_needed;
3302 if (!access_ok(VERIFY_WRITE, buf, space))
3303 return -EFAULT;
3305 bufsize -= space;
3306 vals = (unsigned *)buf;
3307 strings = buf+space;
3309 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3310 len = strlen(s->name)+1;
3311 if (len > bufsize)
3312 goto calc_space_needed;
3314 if (copy_to_user(strings, s->name, len)
3315 || __put_user(s->value, vals+0)
3316 || __put_user(space, vals+1))
3317 return -EFAULT;
3319 strings += len;
3320 bufsize -= len;
3321 space += len;
3324 if (put_user(i, ret))
3325 return -EFAULT;
3326 else
3327 return 0;
3329 calc_space_needed:
3330 for (; i < mod->nsyms; ++i, ++s)
3331 space += strlen(s->name)+1;
3333 if (put_user(space, ret))
3334 return -EFAULT;
3335 else
3336 return -ENOSPC;
3339 static inline int
3340 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3342 int error = 0;
3344 if (mod->next == NULL)
3345 return -EINVAL;
3347 if (sizeof(struct module_info32) <= bufsize) {
3348 struct module_info32 info;
3349 info.addr = (unsigned long)mod;
3350 info.size = mod->size;
3351 info.flags = mod->flags;
3352 info.usecount =
3353 ((mod_member_present(mod, can_unload)
3354 && mod->can_unload)
3355 ? -1 : atomic_read(&mod->uc.usecount));
3357 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3358 return -EFAULT;
3359 } else
3360 error = -ENOSPC;
3362 if (put_user(sizeof(struct module_info32), ret))
3363 return -EFAULT;
3365 return error;
3368 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3370 struct module *mod;
3371 int err;
3373 lock_kernel();
3374 if (name_user == 0) {
3375 /* This finds "kernel_module" which is not exported. */
3376 for(mod = module_list; mod->next != NULL; mod = mod->next)
3378 } else {
3379 long namelen;
3380 char *name;
3382 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3383 err = namelen;
3384 goto out;
3386 err = -ENOENT;
3387 if (namelen == 0) {
3388 /* This finds "kernel_module" which is not exported. */
3389 for(mod = module_list; mod->next != NULL; mod = mod->next)
3391 } else if ((mod = find_module(name)) == NULL) {
3392 put_mod_name(name);
3393 goto out;
3395 put_mod_name(name);
3398 switch (which)
3400 case 0:
3401 err = 0;
3402 break;
3403 case QM_MODULES:
3404 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3405 break;
3406 case QM_DEPS:
3407 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3408 break;
3409 case QM_REFS:
3410 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3411 break;
3412 case QM_SYMBOLS:
3413 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3414 break;
3415 case QM_INFO:
3416 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3417 break;
3418 default:
3419 err = -EINVAL;
3420 break;
3422 out:
3423 unlock_kernel();
3424 return err;
3427 struct kernel_sym32 {
3428 u32 value;
3429 char name[60];
3432 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3434 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3436 int len, i;
3437 struct kernel_sym *tbl;
3438 mm_segment_t old_fs;
3440 len = sys_get_kernel_syms(NULL);
3441 if (!table) return len;
3442 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3443 if (!tbl) return -ENOMEM;
3444 old_fs = get_fs();
3445 set_fs (KERNEL_DS);
3446 sys_get_kernel_syms(tbl);
3447 set_fs (old_fs);
3448 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3449 if (put_user (tbl[i].value, &table->value) ||
3450 copy_to_user (table->name, tbl[i].name, 60))
3451 break;
3453 kfree (tbl);
3454 return i;
3457 #else /* CONFIG_MODULES */
3459 asmlinkage unsigned long
3460 sys32_create_module(const char *name_user, size_t size)
3462 return -ENOSYS;
3465 asmlinkage int
3466 sys32_init_module(const char *name_user, struct module *mod_user)
3468 return -ENOSYS;
3471 asmlinkage int
3472 sys32_delete_module(const char *name_user)
3474 return -ENOSYS;
3477 asmlinkage int
3478 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3479 size_t *ret)
3481 /* Let the program know about the new interface. Not that
3482 it'll do them much good. */
3483 if (which == 0)
3484 return 0;
3486 return -ENOSYS;
3489 asmlinkage int
3490 sys32_get_kernel_syms(struct kernel_sym *table)
3492 return -ENOSYS;
3495 #endif /* CONFIG_MODULES */
3497 /* Stuff for NFS server syscalls... */
3498 struct nfsctl_svc32 {
3499 u16 svc32_port;
3500 s32 svc32_nthreads;
3503 struct nfsctl_client32 {
3504 s8 cl32_ident[NFSCLNT_IDMAX+1];
3505 s32 cl32_naddr;
3506 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3507 s32 cl32_fhkeytype;
3508 s32 cl32_fhkeylen;
3509 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3512 struct nfsctl_export32 {
3513 s8 ex32_client[NFSCLNT_IDMAX+1];
3514 s8 ex32_path[NFS_MAXPATHLEN+1];
3515 __kernel_dev_t32 ex32_dev;
3516 __kernel_ino_t32 ex32_ino;
3517 s32 ex32_flags;
3518 __kernel_uid_t32 ex32_anon_uid;
3519 __kernel_gid_t32 ex32_anon_gid;
3522 struct nfsctl_uidmap32 {
3523 u32 ug32_ident; /* char * */
3524 __kernel_uid_t32 ug32_uidbase;
3525 s32 ug32_uidlen;
3526 u32 ug32_udimap; /* uid_t * */
3527 __kernel_uid_t32 ug32_gidbase;
3528 s32 ug32_gidlen;
3529 u32 ug32_gdimap; /* gid_t * */
3532 struct nfsctl_fhparm32 {
3533 struct sockaddr gf32_addr;
3534 __kernel_dev_t32 gf32_dev;
3535 __kernel_ino_t32 gf32_ino;
3536 s32 gf32_version;
3539 struct nfsctl_fdparm32 {
3540 struct sockaddr gd32_addr;
3541 s8 gd32_path[NFS_MAXPATHLEN+1];
3542 s32 gd32_version;
3545 struct nfsctl_fsparm32 {
3546 struct sockaddr gd32_addr;
3547 s8 gd32_path[NFS_MAXPATHLEN+1];
3548 s32 gd32_maxlen;
3551 struct nfsctl_arg32 {
3552 s32 ca32_version; /* safeguard */
3553 union {
3554 struct nfsctl_svc32 u32_svc;
3555 struct nfsctl_client32 u32_client;
3556 struct nfsctl_export32 u32_export;
3557 struct nfsctl_uidmap32 u32_umap;
3558 struct nfsctl_fhparm32 u32_getfh;
3559 struct nfsctl_fdparm32 u32_getfd;
3560 struct nfsctl_fsparm32 u32_getfs;
3561 } u;
3562 #define ca32_svc u.u32_svc
3563 #define ca32_client u.u32_client
3564 #define ca32_export u.u32_export
3565 #define ca32_umap u.u32_umap
3566 #define ca32_getfh u.u32_getfh
3567 #define ca32_getfd u.u32_getfd
3568 #define ca32_getfs u.u32_getfs
3569 #define ca32_authd u.u32_authd
3572 union nfsctl_res32 {
3573 __u8 cr32_getfh[NFS_FHSIZE];
3574 struct knfsd_fh cr32_getfs;
3577 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3579 int err;
3581 err = __get_user(karg->ca_version, &arg32->ca32_version);
3582 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3583 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3584 return err;
3587 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3589 int err;
3591 err = __get_user(karg->ca_version, &arg32->ca32_version);
3592 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3593 &arg32->ca32_client.cl32_ident[0],
3594 NFSCLNT_IDMAX);
3595 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3596 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3597 &arg32->ca32_client.cl32_addrlist[0],
3598 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3599 err |= __get_user(karg->ca_client.cl_fhkeytype,
3600 &arg32->ca32_client.cl32_fhkeytype);
3601 err |= __get_user(karg->ca_client.cl_fhkeylen,
3602 &arg32->ca32_client.cl32_fhkeylen);
3603 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3604 &arg32->ca32_client.cl32_fhkey[0],
3605 NFSCLNT_KEYMAX);
3606 return err;
3609 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3611 int err;
3613 err = __get_user(karg->ca_version, &arg32->ca32_version);
3614 err |= copy_from_user(&karg->ca_export.ex_client[0],
3615 &arg32->ca32_export.ex32_client[0],
3616 NFSCLNT_IDMAX);
3617 err |= copy_from_user(&karg->ca_export.ex_path[0],
3618 &arg32->ca32_export.ex32_path[0],
3619 NFS_MAXPATHLEN);
3620 err |= __get_user(karg->ca_export.ex_dev,
3621 &arg32->ca32_export.ex32_dev);
3622 err |= __get_user(karg->ca_export.ex_ino,
3623 &arg32->ca32_export.ex32_ino);
3624 err |= __get_user(karg->ca_export.ex_flags,
3625 &arg32->ca32_export.ex32_flags);
3626 err |= __get_user(karg->ca_export.ex_anon_uid,
3627 &arg32->ca32_export.ex32_anon_uid);
3628 err |= __get_user(karg->ca_export.ex_anon_gid,
3629 &arg32->ca32_export.ex32_anon_gid);
3630 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3631 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3632 return err;
3635 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3637 u32 uaddr;
3638 int i;
3639 int err;
3641 memset(karg, 0, sizeof(*karg));
3642 if(__get_user(karg->ca_version, &arg32->ca32_version))
3643 return -EFAULT;
3644 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3645 if(!karg->ca_umap.ug_ident)
3646 return -ENOMEM;
3647 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3648 if(strncpy_from_user(karg->ca_umap.ug_ident,
3649 (char *)A(uaddr), PAGE_SIZE) <= 0)
3650 return -EFAULT;
3651 err |= __get_user(karg->ca_umap.ug_uidbase,
3652 &arg32->ca32_umap.ug32_uidbase);
3653 err |= __get_user(karg->ca_umap.ug_uidlen,
3654 &arg32->ca32_umap.ug32_uidlen);
3655 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3656 if (err)
3657 return -EFAULT;
3658 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3659 GFP_USER);
3660 if(!karg->ca_umap.ug_udimap)
3661 return -ENOMEM;
3662 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3663 err |= __get_user(karg->ca_umap.ug_udimap[i],
3664 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3665 err |= __get_user(karg->ca_umap.ug_gidbase,
3666 &arg32->ca32_umap.ug32_gidbase);
3667 err |= __get_user(karg->ca_umap.ug_uidlen,
3668 &arg32->ca32_umap.ug32_gidlen);
3669 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3670 if (err)
3671 return -EFAULT;
3672 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3673 GFP_USER);
3674 if(!karg->ca_umap.ug_gdimap)
3675 return -ENOMEM;
3676 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3677 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3678 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3680 return err;
3683 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3685 int err;
3687 err = __get_user(karg->ca_version, &arg32->ca32_version);
3688 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3689 &arg32->ca32_getfh.gf32_addr,
3690 (sizeof(struct sockaddr)));
3691 err |= __get_user(karg->ca_getfh.gf_dev,
3692 &arg32->ca32_getfh.gf32_dev);
3693 err |= __get_user(karg->ca_getfh.gf_ino,
3694 &arg32->ca32_getfh.gf32_ino);
3695 err |= __get_user(karg->ca_getfh.gf_version,
3696 &arg32->ca32_getfh.gf32_version);
3697 return err;
3700 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3702 int err;
3704 err = __get_user(karg->ca_version, &arg32->ca32_version);
3705 err |= copy_from_user(&karg->ca_getfd.gd_addr,
3706 &arg32->ca32_getfd.gd32_addr,
3707 (sizeof(struct sockaddr)));
3708 err |= copy_from_user(&karg->ca_getfd.gd_path,
3709 &arg32->ca32_getfd.gd32_path,
3710 (NFS_MAXPATHLEN+1));
3711 err |= __get_user(karg->ca_getfd.gd_version,
3712 &arg32->ca32_getfd.gd32_version);
3713 return err;
3716 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3718 int err;
3720 err = __get_user(karg->ca_version, &arg32->ca32_version);
3721 err |= copy_from_user(&karg->ca_getfs.gd_addr,
3722 &arg32->ca32_getfs.gd32_addr,
3723 (sizeof(struct sockaddr)));
3724 err |= copy_from_user(&karg->ca_getfs.gd_path,
3725 &arg32->ca32_getfs.gd32_path,
3726 (NFS_MAXPATHLEN+1));
3727 err |= __get_user(karg->ca_getfs.gd_maxlen,
3728 &arg32->ca32_getfs.gd32_maxlen);
3729 return err;
3732 /* This really doesn't need translations, we are only passing
3733 * back a union which contains opaque nfs file handle data.
3735 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3737 return copy_to_user(res32, kres, sizeof(*res32));
3740 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3742 struct nfsctl_arg *karg = NULL;
3743 union nfsctl_res *kres = NULL;
3744 mm_segment_t oldfs;
3745 int err;
3747 karg = kmalloc(sizeof(*karg), GFP_USER);
3748 if(!karg)
3749 return -ENOMEM;
3750 if(res32) {
3751 kres = kmalloc(sizeof(*kres), GFP_USER);
3752 if(!kres) {
3753 kfree(karg);
3754 return -ENOMEM;
3757 switch(cmd) {
3758 case NFSCTL_SVC:
3759 err = nfs_svc32_trans(karg, arg32);
3760 break;
3761 case NFSCTL_ADDCLIENT:
3762 err = nfs_clnt32_trans(karg, arg32);
3763 break;
3764 case NFSCTL_DELCLIENT:
3765 err = nfs_clnt32_trans(karg, arg32);
3766 break;
3767 case NFSCTL_EXPORT:
3768 case NFSCTL_UNEXPORT:
3769 err = nfs_exp32_trans(karg, arg32);
3770 break;
3771 /* This one is unimplemented, be we're ready for it. */
3772 case NFSCTL_UGIDUPDATE:
3773 err = nfs_uud32_trans(karg, arg32);
3774 break;
3775 case NFSCTL_GETFH:
3776 err = nfs_getfh32_trans(karg, arg32);
3777 break;
3778 case NFSCTL_GETFD:
3779 err = nfs_getfd32_trans(karg, arg32);
3780 break;
3781 case NFSCTL_GETFS:
3782 err = nfs_getfs32_trans(karg, arg32);
3783 break;
3784 default:
3785 err = -EINVAL;
3786 break;
3788 if(err)
3789 goto done;
3790 oldfs = get_fs();
3791 set_fs(KERNEL_DS);
3792 err = sys_nfsservctl(cmd, karg, kres);
3793 set_fs(oldfs);
3795 if (err)
3796 goto done;
3798 if((cmd == NFSCTL_GETFH) ||
3799 (cmd == NFSCTL_GETFD) ||
3800 (cmd == NFSCTL_GETFS))
3801 err = nfs_getfh32_res_trans(kres, res32);
3803 done:
3804 if(karg) {
3805 if(cmd == NFSCTL_UGIDUPDATE) {
3806 if(karg->ca_umap.ug_ident)
3807 kfree(karg->ca_umap.ug_ident);
3808 if(karg->ca_umap.ug_udimap)
3809 kfree(karg->ca_umap.ug_udimap);
3810 if(karg->ca_umap.ug_gdimap)
3811 kfree(karg->ca_umap.ug_gdimap);
3813 kfree(karg);
3815 if(kres)
3816 kfree(kres);
3817 return err;
3820 /* Translations due to time_t size differences. Which affects all
3821 sorts of things, like timeval and itimerval. */
3823 extern struct timezone sys_tz;
3824 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3826 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3828 if (tv) {
3829 struct timeval ktv;
3830 do_gettimeofday(&ktv);
3831 if (put_tv32(tv, &ktv))
3832 return -EFAULT;
3834 if (tz) {
3835 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3836 return -EFAULT;
3838 return 0;
3841 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3843 struct timeval ktv;
3844 struct timezone ktz;
3846 if (tv) {
3847 if (get_tv32(&ktv, tv))
3848 return -EFAULT;
3850 if (tz) {
3851 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3852 return -EFAULT;
3855 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3858 extern int do_getitimer(int which, struct itimerval *value);
3860 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3862 struct itimerval kit;
3863 int error;
3865 error = do_getitimer(which, &kit);
3866 if (!error && put_it32(it, &kit))
3867 error = -EFAULT;
3869 return error;
3872 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3874 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3876 struct itimerval kin, kout;
3877 int error;
3879 if (in) {
3880 if (get_it32(&kin, in))
3881 return -EFAULT;
3882 } else
3883 memset(&kin, 0, sizeof(kin));
3885 error = do_setitimer(which, &kin, out ? &kout : NULL);
3886 if (error || !out)
3887 return error;
3888 if (put_it32(out, &kout))
3889 return -EFAULT;
3891 return 0;
3895 asmlinkage int sys_utimes(char *, struct timeval *);
3897 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3899 char *kfilename;
3900 struct timeval ktvs[2];
3901 mm_segment_t old_fs;
3902 int ret;
3904 kfilename = getname(filename);
3905 ret = PTR_ERR(kfilename);
3906 if (!IS_ERR(kfilename)) {
3907 if (tvs) {
3908 if (get_tv32(&ktvs[0], tvs) ||
3909 get_tv32(&ktvs[1], 1+tvs))
3910 return -EFAULT;
3913 old_fs = get_fs();
3914 set_fs(KERNEL_DS);
3915 ret = sys_utimes(kfilename, &ktvs[0]);
3916 set_fs(old_fs);
3918 putname(kfilename);
3920 return ret;
3923 /* These are here just in case some old sparc32 binary calls it. */
3924 asmlinkage int sys32_pause(void)
3926 current->state = TASK_INTERRUPTIBLE;
3927 schedule();
3928 return -ERESTARTNOHAND;
3931 /* PCI config space poking. */
3932 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3933 unsigned long dfn,
3934 unsigned long off,
3935 unsigned long len,
3936 unsigned char *buf);
3938 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3939 unsigned long dfn,
3940 unsigned long off,
3941 unsigned long len,
3942 unsigned char *buf);
3944 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3946 return sys_pciconfig_read((unsigned long) bus,
3947 (unsigned long) dfn,
3948 (unsigned long) off,
3949 (unsigned long) len,
3950 (unsigned char *)AA(ubuf));
3953 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3955 return sys_pciconfig_write((unsigned long) bus,
3956 (unsigned long) dfn,
3957 (unsigned long) off,
3958 (unsigned long) len,
3959 (unsigned char *)AA(ubuf));
3962 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
3963 unsigned long arg4, unsigned long arg5);
3965 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
3967 return sys_prctl(option,
3968 (unsigned long) arg2,
3969 (unsigned long) arg3,
3970 (unsigned long) arg4,
3971 (unsigned long) arg5);
3975 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
3976 size_t count, loff_t pos);
3978 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
3979 size_t count, loff_t pos);
3981 typedef __kernel_ssize_t32 ssize_t32;
3983 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
3984 __kernel_size_t32 count, u32 poshi, u32 poslo)
3986 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3989 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
3990 __kernel_size_t32 count, u32 poshi, u32 poslo)
3992 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
3996 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
3998 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4000 mm_segment_t old_fs = get_fs();
4001 int ret;
4002 off_t of;
4004 if (offset && get_user(of, offset))
4005 return -EFAULT;
4007 set_fs(KERNEL_DS);
4008 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4009 set_fs(old_fs);
4011 if (!ret && offset && put_user(of, offset))
4012 return -EFAULT;
4014 return ret;
4017 /* Handle adjtimex compatability. */
4019 struct timex32 {
4020 u32 modes;
4021 s32 offset, freq, maxerror, esterror;
4022 s32 status, constant, precision, tolerance;
4023 struct timeval32 time;
4024 s32 tick;
4025 s32 ppsfreq, jitter, shift, stabil;
4026 s32 jitcnt, calcnt, errcnt, stbcnt;
4027 s32 :32; s32 :32; s32 :32; s32 :32;
4028 s32 :32; s32 :32; s32 :32; s32 :32;
4029 s32 :32; s32 :32; s32 :32; s32 :32;
4032 extern int do_adjtimex(struct timex *);
4034 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4036 struct timex txc;
4037 int ret;
4039 memset(&txc, 0, sizeof(struct timex));
4041 if(get_user(txc.modes, &utp->modes) ||
4042 __get_user(txc.offset, &utp->offset) ||
4043 __get_user(txc.freq, &utp->freq) ||
4044 __get_user(txc.maxerror, &utp->maxerror) ||
4045 __get_user(txc.esterror, &utp->esterror) ||
4046 __get_user(txc.status, &utp->status) ||
4047 __get_user(txc.constant, &utp->constant) ||
4048 __get_user(txc.precision, &utp->precision) ||
4049 __get_user(txc.tolerance, &utp->tolerance) ||
4050 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4051 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4052 __get_user(txc.tick, &utp->tick) ||
4053 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4054 __get_user(txc.jitter, &utp->jitter) ||
4055 __get_user(txc.shift, &utp->shift) ||
4056 __get_user(txc.stabil, &utp->stabil) ||
4057 __get_user(txc.jitcnt, &utp->jitcnt) ||
4058 __get_user(txc.calcnt, &utp->calcnt) ||
4059 __get_user(txc.errcnt, &utp->errcnt) ||
4060 __get_user(txc.stbcnt, &utp->stbcnt))
4061 return -EFAULT;
4063 ret = do_adjtimex(&txc);
4065 if(put_user(txc.modes, &utp->modes) ||
4066 __put_user(txc.offset, &utp->offset) ||
4067 __put_user(txc.freq, &utp->freq) ||
4068 __put_user(txc.maxerror, &utp->maxerror) ||
4069 __put_user(txc.esterror, &utp->esterror) ||
4070 __put_user(txc.status, &utp->status) ||
4071 __put_user(txc.constant, &utp->constant) ||
4072 __put_user(txc.precision, &utp->precision) ||
4073 __put_user(txc.tolerance, &utp->tolerance) ||
4074 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4075 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4076 __put_user(txc.tick, &utp->tick) ||
4077 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4078 __put_user(txc.jitter, &utp->jitter) ||
4079 __put_user(txc.shift, &utp->shift) ||
4080 __put_user(txc.stabil, &utp->stabil) ||
4081 __put_user(txc.jitcnt, &utp->jitcnt) ||
4082 __put_user(txc.calcnt, &utp->calcnt) ||
4083 __put_user(txc.errcnt, &utp->errcnt) ||
4084 __put_user(txc.stbcnt, &utp->stbcnt))
4085 ret = -EFAULT;
4087 return ret;
4090 /* This is just a version for 32-bit applications which does
4091 * not force O_LARGEFILE on.
4094 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4096 char * tmp;
4097 int fd, error;
4099 tmp = getname(filename);
4100 fd = PTR_ERR(tmp);
4101 if (!IS_ERR(tmp)) {
4102 fd = get_unused_fd();
4103 if (fd >= 0) {
4104 struct file * f = filp_open(tmp, flags, mode);
4105 error = PTR_ERR(f);
4106 if (IS_ERR(f))
4107 goto out_error;
4108 fd_install(fd, f);
4110 out:
4111 putname(tmp);
4113 return fd;
4115 out_error:
4116 put_unused_fd(fd);
4117 fd = error;
4118 goto out;
4121 extern unsigned long do_mremap(unsigned long addr,
4122 unsigned long old_len, unsigned long new_len,
4123 unsigned long flags, unsigned long new_addr);
4125 asmlinkage unsigned long sys32_mremap(unsigned long addr,
4126 unsigned long old_len, unsigned long new_len,
4127 unsigned long flags, u32 __new_addr)
4129 unsigned long ret = -EINVAL;
4130 unsigned long new_addr = AA(__new_addr);
4132 if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
4133 goto out;
4134 if (addr > 0xf0000000UL - old_len)
4135 goto out;
4136 down(&current->mm->mmap_sem);
4137 if (flags & MREMAP_FIXED) {
4138 if (new_addr > 0xf0000000UL - new_len)
4139 goto out_sem;
4140 } else if (addr > 0xf0000000UL - new_len) {
4141 ret = -ENOMEM;
4142 if (!(flags & MREMAP_MAYMOVE))
4143 goto out_sem;
4144 new_addr = get_unmapped_area (addr, new_len);
4145 if (!new_addr)
4146 goto out_sem;
4147 flags |= MREMAP_FIXED;
4149 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
4150 out_sem:
4151 up(&current->mm->mmap_sem);
4152 out:
4153 return ret;
4156 extern asmlinkage long sys_setpriority(int which, int who, int niceval);
4158 asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
4160 return sys_setpriority((int) which,
4161 (int) who,
4162 (int) niceval);