Import 2.4.0-test3pre5
[davej-history.git] / arch / sparc64 / kernel / sys_sparc32.c
blob8f3339bfa2f6deb1236743b4e4574c96e2e73729
1 /* $Id: sys_sparc32.c,v 1.154 2000/07/06 01:41:29 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>
49 #include <asm/types.h>
50 #include <asm/ipc.h>
51 #include <asm/uaccess.h>
52 #include <asm/fpumacro.h>
53 #include <asm/semaphore.h>
55 #include <net/scm.h>
57 /* Use this to get at 32-bit user passed pointers. */
58 /* Things to consider: the low-level assembly stub does
59 srl x, 0, x for first four arguments, so if you have
60 pointer to something in the first four arguments, just
61 declare it as a pointer, not u32. On the other side,
62 arguments from 5th onwards should be declared as u32
63 for pointers, and need AA() around each usage.
64 A() macro should be used for places where you e.g.
65 have some internal variable u32 and just want to get
66 rid of a compiler warning. AA() has to be used in
67 places where you want to convert a function argument
68 to 32bit pointer or when you e.g. access pt_regs
69 structure and want to consider 32bit registers only.
70 -jj
72 #define A(__x) ((unsigned long)(__x))
73 #define AA(__x) \
74 ({ unsigned long __ret; \
75 __asm__ ("srl %0, 0, %0" \
76 : "=r" (__ret) \
77 : "0" (__x)); \
78 __ret; \
81 extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
82 extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
83 extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
84 extern asmlinkage long sys_setregid(gid_t, gid_t);
85 extern asmlinkage long sys_setgid(gid_t);
86 extern asmlinkage long sys_setreuid(uid_t, uid_t);
87 extern asmlinkage long sys_setuid(uid_t);
88 extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
89 extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
90 extern asmlinkage long sys_setfsuid(uid_t);
91 extern asmlinkage long sys_setfsgid(gid_t);
93 /* For this source file, we want overflow handling. */
95 #undef high2lowuid
96 #undef high2lowgid
97 #undef low2highuid
98 #undef low2highgid
99 #undef SET_UID16
100 #undef SET_GID16
101 #undef NEW_TO_OLD_UID
102 #undef NEW_TO_OLD_GID
103 #undef SET_OLDSTAT_UID
104 #undef SET_OLDSTAT_GID
105 #undef SET_STAT_UID
106 #undef SET_STAT_GID
108 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
109 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
110 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
111 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
112 #define SET_UID16(var, uid) var = high2lowuid(uid)
113 #define SET_GID16(var, gid) var = high2lowgid(gid)
114 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
115 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
116 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
117 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
118 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
119 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
121 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
123 return sys_chown(filename, low2highuid(user), low2highgid(group));
126 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
128 return sys_lchown(filename, low2highuid(user), low2highgid(group));
131 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
133 return sys_fchown(fd, low2highuid(user), low2highgid(group));
136 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
138 return sys_setregid(low2highgid(rgid), low2highgid(egid));
141 asmlinkage long sys32_setgid16(u16 gid)
143 return sys_setgid((gid_t)gid);
146 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
148 return sys_setreuid(low2highuid(ruid), low2highuid(euid));
151 asmlinkage long sys32_setuid16(u16 uid)
153 return sys_setuid((uid_t)uid);
156 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
158 return sys_setresuid(low2highuid(ruid), low2highuid(euid),
159 low2highuid(suid));
162 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
164 int retval;
166 if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
167 !(retval = put_user(high2lowuid(current->euid), euid)))
168 retval = put_user(high2lowuid(current->suid), suid);
170 return retval;
173 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
175 return sys_setresgid(low2highgid(rgid), low2highgid(egid),
176 low2highgid(sgid));
179 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
181 int retval;
183 if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
184 !(retval = put_user(high2lowgid(current->egid), egid)))
185 retval = put_user(high2lowgid(current->sgid), sgid);
187 return retval;
190 asmlinkage long sys32_setfsuid16(u16 uid)
192 return sys_setfsuid((uid_t)uid);
195 asmlinkage long sys32_setfsgid16(u16 gid)
197 return sys_setfsgid((gid_t)gid);
200 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
202 u16 groups[NGROUPS];
203 int i,j;
205 if (gidsetsize < 0)
206 return -EINVAL;
207 i = current->ngroups;
208 if (gidsetsize) {
209 if (i > gidsetsize)
210 return -EINVAL;
211 for(j=0;j<i;j++)
212 groups[j] = current->groups[j];
213 if (copy_to_user(grouplist, groups, sizeof(u16)*i))
214 return -EFAULT;
216 return i;
219 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
221 u16 groups[NGROUPS];
222 int i;
224 if (!capable(CAP_SETGID))
225 return -EPERM;
226 if ((unsigned) gidsetsize > NGROUPS)
227 return -EINVAL;
228 if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
229 return -EFAULT;
230 for (i = 0 ; i < gidsetsize ; i++)
231 current->groups[i] = (gid_t)groups[i];
232 current->ngroups = gidsetsize;
233 return 0;
236 asmlinkage long sys32_getuid16(void)
238 return high2lowuid(current->uid);
241 asmlinkage long sys32_geteuid16(void)
243 return high2lowuid(current->euid);
246 asmlinkage long sys32_getgid16(void)
248 return high2lowgid(current->gid);
251 asmlinkage long sys32_getegid16(void)
253 return high2lowgid(current->egid);
256 /* In order to reduce some races, while at the same time doing additional
257 * checking and hopefully speeding things up, we copy filenames to the
258 * kernel data space before using them..
260 * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
262 static inline int do_getname32(const char *filename, char *page)
264 int retval;
266 /* 32bit pointer will be always far below TASK_SIZE :)) */
267 retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
268 if (retval > 0) {
269 if (retval < PAGE_SIZE)
270 return 0;
271 return -ENAMETOOLONG;
272 } else if (!retval)
273 retval = -ENOENT;
274 return retval;
277 char * getname32(const char *filename)
279 char *tmp, *result;
281 result = ERR_PTR(-ENOMEM);
282 tmp = (char *)__get_free_page(GFP_KERNEL);
283 if (tmp) {
284 int retval = do_getname32(filename, tmp);
286 result = tmp;
287 if (retval < 0) {
288 putname(tmp);
289 result = ERR_PTR(retval);
292 return result;
295 /* 32-bit timeval and related flotsam. */
297 struct timeval32
299 int tv_sec, tv_usec;
302 struct itimerval32
304 struct timeval32 it_interval;
305 struct timeval32 it_value;
308 static inline long get_tv32(struct timeval *o, struct timeval32 *i)
310 return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
311 (__get_user(o->tv_sec, &i->tv_sec) |
312 __get_user(o->tv_usec, &i->tv_usec)));
315 static inline long put_tv32(struct timeval32 *o, struct timeval *i)
317 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
318 (__put_user(i->tv_sec, &o->tv_sec) |
319 __put_user(i->tv_usec, &o->tv_usec)));
322 static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
324 return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
325 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
326 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
327 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
328 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
331 static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
333 return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
334 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
335 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
336 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
337 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
340 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
342 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
344 return sys_ioperm((unsigned long)from, (unsigned long)num, on);
347 struct msgbuf32 { s32 mtype; char mtext[1]; };
349 struct ipc_perm32
351 key_t key;
352 __kernel_uid_t32 uid;
353 __kernel_gid_t32 gid;
354 __kernel_uid_t32 cuid;
355 __kernel_gid_t32 cgid;
356 __kernel_mode_t32 mode;
357 unsigned short seq;
360 struct semid_ds32 {
361 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
362 __kernel_time_t32 sem_otime; /* last semop time */
363 __kernel_time_t32 sem_ctime; /* last change time */
364 u32 sem_base; /* ptr to first semaphore in array */
365 u32 sem_pending; /* pending operations to be processed */
366 u32 sem_pending_last; /* last pending operation */
367 u32 undo; /* undo requests on this array */
368 unsigned short sem_nsems; /* no. of semaphores in array */
371 struct semid64_ds32 {
372 struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
373 unsigned int __pad1;
374 __kernel_time_t32 sem_otime;
375 unsigned int __pad2;
376 __kernel_time_t32 sem_ctime;
377 u32 sem_nsems;
378 u32 __unused1;
379 u32 __unused2;
382 struct msqid_ds32
384 struct ipc_perm32 msg_perm;
385 u32 msg_first;
386 u32 msg_last;
387 __kernel_time_t32 msg_stime;
388 __kernel_time_t32 msg_rtime;
389 __kernel_time_t32 msg_ctime;
390 u32 wwait;
391 u32 rwait;
392 unsigned short msg_cbytes;
393 unsigned short msg_qnum;
394 unsigned short msg_qbytes;
395 __kernel_ipc_pid_t32 msg_lspid;
396 __kernel_ipc_pid_t32 msg_lrpid;
399 struct msqid64_ds32 {
400 struct ipc64_perm msg_perm;
401 unsigned int __pad1;
402 __kernel_time_t32 msg_stime;
403 unsigned int __pad2;
404 __kernel_time_t32 msg_rtime;
405 unsigned int __pad3;
406 __kernel_time_t32 msg_ctime;
407 unsigned int msg_cbytes;
408 unsigned int msg_qnum;
409 unsigned int msg_qbytes;
410 __kernel_pid_t32 msg_lspid;
411 __kernel_pid_t32 msg_lrpid;
412 unsigned int __unused1;
413 unsigned int __unused2;
417 struct shmid_ds32 {
418 struct ipc_perm32 shm_perm;
419 int shm_segsz;
420 __kernel_time_t32 shm_atime;
421 __kernel_time_t32 shm_dtime;
422 __kernel_time_t32 shm_ctime;
423 __kernel_ipc_pid_t32 shm_cpid;
424 __kernel_ipc_pid_t32 shm_lpid;
425 unsigned short shm_nattch;
428 struct shmid64_ds32 {
429 struct ipc64_perm shm_perm;
430 unsigned int __pad1;
431 __kernel_time_t32 shm_atime;
432 unsigned int __pad2;
433 __kernel_time_t32 shm_dtime;
434 unsigned int __pad3;
435 __kernel_time_t32 shm_ctime;
436 __kernel_size_t32 shm_segsz;
437 __kernel_pid_t32 shm_cpid;
438 __kernel_pid_t32 shm_lpid;
439 unsigned int shm_nattch;
440 unsigned int __unused1;
441 unsigned int __unused2;
446 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
448 * This is really horribly ugly.
450 #define IPCOP_MASK(__x) (1UL << (__x))
451 static int do_sys32_semctl(int first, int second, int third, void *uptr)
453 union semun fourth;
454 u32 pad;
455 int err = -EINVAL;
457 if (!uptr)
458 goto out;
459 err = -EFAULT;
460 if (get_user (pad, (u32 *)uptr))
461 goto out;
462 if(third == SETVAL)
463 fourth.val = (int)pad;
464 else
465 fourth.__pad = (void *)A(pad);
466 if (IPCOP_MASK (third) &
467 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
468 IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
469 IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
470 err = sys_semctl (first, second, third, fourth);
471 } else if (third & IPC_64) {
472 struct semid64_ds s;
473 struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
474 mm_segment_t old_fs;
475 int need_back_translation;
477 if (third == (IPC_SET|IPC_64)) {
478 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
479 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
480 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
481 if (err)
482 goto out;
483 fourth.__pad = &s;
485 need_back_translation =
486 (IPCOP_MASK (third) &
487 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
488 if (need_back_translation)
489 fourth.__pad = &s;
490 old_fs = get_fs ();
491 set_fs (KERNEL_DS);
492 err = sys_semctl (first, second, third, fourth);
493 set_fs (old_fs);
494 if (need_back_translation) {
495 int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
496 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
497 if (err2) err = -EFAULT;
499 } else {
500 struct semid_ds s;
501 struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
502 mm_segment_t old_fs;
503 int need_back_translation;
505 if (third == IPC_SET) {
506 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
507 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
508 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
509 if (err)
510 goto out;
511 fourth.__pad = &s;
513 need_back_translation =
514 (IPCOP_MASK (third) &
515 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
516 if (need_back_translation)
517 fourth.__pad = &s;
518 old_fs = get_fs ();
519 set_fs (KERNEL_DS);
520 err = sys_semctl (first, second, third, fourth);
521 set_fs (old_fs);
522 if (need_back_translation) {
523 int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
524 err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
525 err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
526 err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
527 err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
528 err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
529 err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
530 err2 |= __put_user (s.sem_otime, &usp->sem_otime);
531 err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
532 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
533 if (err2) err = -EFAULT;
536 out:
537 return err;
540 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
542 struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
543 struct msgbuf32 *up = (struct msgbuf32 *)uptr;
544 mm_segment_t old_fs;
545 int err;
547 if (!p)
548 return -ENOMEM;
549 err = get_user (p->mtype, &up->mtype);
550 err |= __copy_from_user (p->mtext, &up->mtext, second);
551 if (err)
552 goto out;
553 old_fs = get_fs ();
554 set_fs (KERNEL_DS);
555 err = sys_msgsnd (first, p, second, third);
556 set_fs (old_fs);
557 out:
558 kfree (p);
559 return err;
562 static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
563 int version, void *uptr)
565 struct msgbuf32 *up;
566 struct msgbuf *p;
567 mm_segment_t old_fs;
568 int err;
570 if (!version) {
571 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
572 struct ipc_kludge ipck;
574 err = -EINVAL;
575 if (!uptr)
576 goto out;
577 err = -EFAULT;
578 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
579 goto out;
580 uptr = (void *)A(ipck.msgp);
581 msgtyp = ipck.msgtyp;
583 err = -ENOMEM;
584 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
585 if (!p)
586 goto out;
587 old_fs = get_fs ();
588 set_fs (KERNEL_DS);
589 err = sys_msgrcv (first, p, second + 4, msgtyp, third);
590 set_fs (old_fs);
591 if (err < 0)
592 goto free_then_out;
593 up = (struct msgbuf32 *)uptr;
594 if (put_user (p->mtype, &up->mtype) ||
595 __copy_to_user (&up->mtext, p->mtext, err))
596 err = -EFAULT;
597 free_then_out:
598 kfree (p);
599 out:
600 return err;
603 static int do_sys32_msgctl (int first, int second, void *uptr)
605 int err;
607 if (IPCOP_MASK (second) &
608 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
609 IPCOP_MASK (IPC_RMID))) {
610 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
611 } else if (second & IPC_64) {
612 struct msqid64_ds m;
613 struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
614 mm_segment_t old_fs;
616 if (second == (IPC_SET|IPC_64)) {
617 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
618 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
619 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
620 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
621 if (err)
622 goto out;
624 old_fs = get_fs ();
625 set_fs (KERNEL_DS);
626 err = sys_msgctl (first, second, (struct msqid_ds *)&m);
627 set_fs (old_fs);
628 if (IPCOP_MASK (second) &
629 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
630 int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
631 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
632 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
633 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
634 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
635 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
636 if (err2)
637 err = -EFAULT;
639 } else {
640 struct msqid_ds m;
641 struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
642 mm_segment_t old_fs;
644 if (second == IPC_SET) {
645 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
646 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
647 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
648 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
649 if (err)
650 goto out;
652 old_fs = get_fs ();
653 set_fs (KERNEL_DS);
654 err = sys_msgctl (first, second, &m);
655 set_fs (old_fs);
656 if (IPCOP_MASK (second) &
657 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
658 int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
659 err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
660 err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
661 err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
662 err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
663 err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
664 err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
665 err2 |= __put_user (m.msg_stime, &up->msg_stime);
666 err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
667 err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
668 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
669 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
670 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
671 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
672 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
673 if (err2)
674 err = -EFAULT;
678 out:
679 return err;
682 static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
684 unsigned long raddr;
685 u32 *uaddr = (u32 *)A((u32)third);
686 int err = -EINVAL;
688 if (version == 1)
689 goto out;
690 err = sys_shmat (first, uptr, second, &raddr);
691 if (err)
692 goto out;
693 err = put_user (raddr, uaddr);
694 out:
695 return err;
698 static int do_sys32_shmctl (int first, int second, void *uptr)
700 int err;
702 if (IPCOP_MASK (second) &
703 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
704 IPCOP_MASK (IPC_RMID))) {
705 if (second == (IPC_INFO|IPC_64))
706 second = IPC_INFO; /* So that we don't have to translate it */
707 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
708 } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
709 struct shmid64_ds s;
710 struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
711 mm_segment_t old_fs;
713 if (second == (IPC_SET|IPC_64)) {
714 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
715 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
716 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
717 if (err)
718 goto out;
720 old_fs = get_fs ();
721 set_fs (KERNEL_DS);
722 err = sys_shmctl (first, second, (struct shmid_ds *)&s);
723 set_fs (old_fs);
724 if (err < 0)
725 goto out;
727 /* Mask it even in this case so it becomes a CSE. */
728 if (IPCOP_MASK (second) &
729 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
730 int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
731 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
732 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
733 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
734 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
735 if (err2)
736 err = -EFAULT;
738 } else {
739 struct shmid_ds s;
740 struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
741 mm_segment_t old_fs;
743 second &= ~IPC_64;
744 if (second == IPC_SET) {
745 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
746 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
747 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
748 if (err)
749 goto out;
751 old_fs = get_fs ();
752 set_fs (KERNEL_DS);
753 err = sys_shmctl (first, second, &s);
754 set_fs (old_fs);
755 if (err < 0)
756 goto out;
758 /* Mask it even in this case so it becomes a CSE. */
759 if (second == SHM_INFO) {
760 struct shm_info32 {
761 int used_ids;
762 u32 shm_tot, shm_rss, shm_swp;
763 u32 swap_attempts, swap_successes;
764 } *uip = (struct shm_info32 *)uptr;
765 struct shm_info *kp = (struct shm_info *)&s;
766 int err2 = put_user (kp->used_ids, &uip->used_ids);
767 err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
768 err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
769 err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
770 err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
771 err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
772 if (err2)
773 err = -EFAULT;
774 } else if (IPCOP_MASK (second) &
775 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
776 int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
777 err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
778 err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
779 err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
780 err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
781 err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
782 err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
783 err2 |= __put_user (s.shm_atime, &up->shm_atime);
784 err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
785 err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
786 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
787 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
788 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
789 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
790 if (err2)
791 err = -EFAULT;
794 out:
795 return err;
798 asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
800 int version, err;
802 lock_kernel();
803 version = call >> 16; /* hack for backward compatibility */
804 call &= 0xffff;
806 if (call <= SEMCTL)
807 switch (call) {
808 case SEMOP:
809 /* struct sembuf is the same on 32 and 64bit :)) */
810 err = sys_semop (first, (struct sembuf *)AA(ptr), second);
811 goto out;
812 case SEMGET:
813 err = sys_semget (first, second, third);
814 goto out;
815 case SEMCTL:
816 err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
817 goto out;
818 default:
819 err = -EINVAL;
820 goto out;
822 if (call <= MSGCTL)
823 switch (call) {
824 case MSGSND:
825 err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
826 goto out;
827 case MSGRCV:
828 err = do_sys32_msgrcv (first, second, fifth, third,
829 version, (void *)AA(ptr));
830 goto out;
831 case MSGGET:
832 err = sys_msgget ((key_t) first, second);
833 goto out;
834 case MSGCTL:
835 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
836 goto out;
837 default:
838 err = -EINVAL;
839 goto out;
841 if (call <= SHMCTL)
842 switch (call) {
843 case SHMAT:
844 err = do_sys32_shmat (first, second, third,
845 version, (void *)AA(ptr));
846 goto out;
847 case SHMDT:
848 err = sys_shmdt ((char *)AA(ptr));
849 goto out;
850 case SHMGET:
851 err = sys_shmget (first, second, third);
852 goto out;
853 case SHMCTL:
854 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
855 goto out;
856 default:
857 err = -EINVAL;
858 goto out;
861 err = -EINVAL;
863 out:
864 unlock_kernel();
865 return err;
868 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
870 int err;
872 err = get_user(kfl->l_type, &ufl->l_type);
873 err |= __get_user(kfl->l_whence, &ufl->l_whence);
874 err |= __get_user(kfl->l_start, &ufl->l_start);
875 err |= __get_user(kfl->l_len, &ufl->l_len);
876 err |= __get_user(kfl->l_pid, &ufl->l_pid);
877 return err;
880 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
882 int err;
884 err = __put_user(kfl->l_type, &ufl->l_type);
885 err |= __put_user(kfl->l_whence, &ufl->l_whence);
886 err |= __put_user(kfl->l_start, &ufl->l_start);
887 err |= __put_user(kfl->l_len, &ufl->l_len);
888 err |= __put_user(kfl->l_pid, &ufl->l_pid);
889 return err;
892 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
894 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
896 switch (cmd) {
897 case F_GETLK:
898 case F_SETLK:
899 case F_SETLKW:
901 struct flock f;
902 mm_segment_t old_fs;
903 long ret;
905 if(get_flock(&f, (struct flock32 *)arg))
906 return -EFAULT;
907 old_fs = get_fs(); set_fs (KERNEL_DS);
908 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
909 set_fs (old_fs);
910 if(put_flock(&f, (struct flock32 *)arg))
911 return -EFAULT;
912 return ret;
914 default:
915 return sys_fcntl(fd, cmd, (unsigned long)arg);
919 struct dqblk32 {
920 __u32 dqb_bhardlimit;
921 __u32 dqb_bsoftlimit;
922 __u32 dqb_curblocks;
923 __u32 dqb_ihardlimit;
924 __u32 dqb_isoftlimit;
925 __u32 dqb_curinodes;
926 __kernel_time_t32 dqb_btime;
927 __kernel_time_t32 dqb_itime;
930 extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
932 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
934 int cmds = cmd >> SUBCMDSHIFT;
935 int err;
936 struct dqblk d;
937 mm_segment_t old_fs;
938 char *spec;
940 switch (cmds) {
941 case Q_GETQUOTA:
942 break;
943 case Q_SETQUOTA:
944 case Q_SETUSE:
945 case Q_SETQLIM:
946 if (copy_from_user (&d, (struct dqblk32 *)addr,
947 sizeof (struct dqblk32)))
948 return -EFAULT;
949 d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
950 d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
951 break;
952 default:
953 return sys_quotactl(cmd, special,
954 id, (caddr_t)addr);
956 spec = getname32 (special);
957 err = PTR_ERR(spec);
958 if (IS_ERR(spec)) return err;
959 old_fs = get_fs ();
960 set_fs (KERNEL_DS);
961 err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
962 set_fs (old_fs);
963 putname (spec);
964 if (cmds == Q_GETQUOTA) {
965 __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
966 ((struct dqblk32 *)&d)->dqb_itime = i;
967 ((struct dqblk32 *)&d)->dqb_btime = b;
968 if (copy_to_user ((struct dqblk32 *)addr, &d,
969 sizeof (struct dqblk32)))
970 return -EFAULT;
972 return err;
975 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
977 int err;
979 err = put_user (kbuf->f_type, &ubuf->f_type);
980 err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
981 err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
982 err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
983 err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
984 err |= __put_user (kbuf->f_files, &ubuf->f_files);
985 err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
986 err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
987 err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
988 err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
989 return err;
992 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
994 asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
996 int ret;
997 struct statfs s;
998 mm_segment_t old_fs = get_fs();
999 char *pth;
1001 pth = getname32 (path);
1002 ret = PTR_ERR(pth);
1003 if (!IS_ERR(pth)) {
1004 set_fs (KERNEL_DS);
1005 ret = sys_statfs((const char *)pth, &s);
1006 set_fs (old_fs);
1007 putname (pth);
1008 if (put_statfs(buf, &s))
1009 return -EFAULT;
1011 return ret;
1014 extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
1016 asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
1018 int ret;
1019 struct statfs s;
1020 mm_segment_t old_fs = get_fs();
1022 set_fs (KERNEL_DS);
1023 ret = sys_fstatfs(fd, &s);
1024 set_fs (old_fs);
1025 if (put_statfs(buf, &s))
1026 return -EFAULT;
1027 return ret;
1030 extern asmlinkage long sys_truncate(const char * path, unsigned long length);
1031 extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
1033 asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
1035 if ((int)high < 0)
1036 return -EINVAL;
1037 else
1038 return sys_truncate(path, (high << 32) | low);
1041 asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
1043 if ((int)high < 0)
1044 return -EINVAL;
1045 else
1046 return sys_ftruncate(fd, (high << 32) | low);
1049 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
1051 struct utimbuf32 {
1052 __kernel_time_t32 actime, modtime;
1055 asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
1057 struct utimbuf t;
1058 mm_segment_t old_fs;
1059 int ret;
1060 char *filenam;
1062 if (!times)
1063 return sys_utime(filename, NULL);
1064 if (get_user (t.actime, &times->actime) ||
1065 __get_user (t.modtime, &times->modtime))
1066 return -EFAULT;
1067 filenam = getname32 (filename);
1068 ret = PTR_ERR(filenam);
1069 if (!IS_ERR(filenam)) {
1070 old_fs = get_fs();
1071 set_fs (KERNEL_DS);
1072 ret = sys_utime(filenam, &t);
1073 set_fs (old_fs);
1074 putname (filenam);
1076 return ret;
1079 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
1081 typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
1083 static long do_readv_writev32(int type, struct file *file,
1084 const struct iovec32 *vector, u32 count)
1086 unsigned long tot_len;
1087 struct iovec iovstack[UIO_FASTIOV];
1088 struct iovec *iov=iovstack, *ivp;
1089 struct inode *inode;
1090 long retval, i;
1091 IO_fn_t fn;
1093 /* First get the "struct iovec" from user memory and
1094 * verify all the pointers
1096 if (!count)
1097 return 0;
1098 if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1099 return -EFAULT;
1100 if (count > UIO_MAXIOV)
1101 return -EINVAL;
1102 if (count > UIO_FASTIOV) {
1103 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1104 if (!iov)
1105 return -ENOMEM;
1108 tot_len = 0;
1109 i = count;
1110 ivp = iov;
1111 while(i > 0) {
1112 u32 len;
1113 u32 buf;
1115 __get_user(len, &vector->iov_len);
1116 __get_user(buf, &vector->iov_base);
1117 tot_len += len;
1118 ivp->iov_base = (void *)A(buf);
1119 ivp->iov_len = (__kernel_size_t) len;
1120 vector++;
1121 ivp++;
1122 i--;
1125 inode = file->f_dentry->d_inode;
1126 /* VERIFY_WRITE actually means a read, as we write to user space */
1127 retval = locks_verify_area((type == VERIFY_WRITE
1128 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1129 inode, file, file->f_pos, tot_len);
1130 if (retval) {
1131 if (iov != iovstack)
1132 kfree(iov);
1133 return retval;
1136 /* Then do the actual IO. Note that sockets need to be handled
1137 * specially as they have atomicity guarantees and can handle
1138 * iovec's natively
1140 if (inode->i_sock) {
1141 int err;
1142 err = sock_readv_writev(type, inode, file, iov, count, tot_len);
1143 if (iov != iovstack)
1144 kfree(iov);
1145 return err;
1148 if (!file->f_op) {
1149 if (iov != iovstack)
1150 kfree(iov);
1151 return -EINVAL;
1153 /* VERIFY_WRITE actually means a read, as we write to user space */
1154 fn = file->f_op->read;
1155 if (type == VERIFY_READ)
1156 fn = (IO_fn_t) file->f_op->write;
1157 ivp = iov;
1158 while (count > 0) {
1159 void * base;
1160 int len, nr;
1162 base = ivp->iov_base;
1163 len = ivp->iov_len;
1164 ivp++;
1165 count--;
1166 nr = fn(file, base, len, &file->f_pos);
1167 if (nr < 0) {
1168 if (retval)
1169 break;
1170 retval = nr;
1171 break;
1173 retval += nr;
1174 if (nr != len)
1175 break;
1177 if (iov != iovstack)
1178 kfree(iov);
1179 return retval;
1182 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1184 struct file *file;
1185 long ret = -EBADF;
1187 lock_kernel();
1189 file = fget(fd);
1190 if(!file)
1191 goto bad_file;
1193 if (file->f_op && file->f_op->read && (file->f_mode & FMODE_READ))
1194 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1195 fput(file);
1197 bad_file:
1198 unlock_kernel();
1199 return ret;
1202 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1204 struct file *file;
1205 int ret = -EBADF;
1207 lock_kernel();
1209 file = fget(fd);
1210 if(!file)
1211 goto bad_file;
1212 if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE))
1213 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1214 fput(file);
1216 bad_file:
1217 unlock_kernel();
1218 return ret;
1221 /* readdir & getdents */
1223 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1224 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1226 struct old_linux_dirent32 {
1227 u32 d_ino;
1228 u32 d_offset;
1229 unsigned short d_namlen;
1230 char d_name[1];
1233 struct readdir_callback32 {
1234 struct old_linux_dirent32 * dirent;
1235 int count;
1238 static int fillonedir(void * __buf, const char * name, int namlen,
1239 off_t offset, ino_t ino)
1241 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1242 struct old_linux_dirent32 * dirent;
1244 if (buf->count)
1245 return -EINVAL;
1246 buf->count++;
1247 dirent = buf->dirent;
1248 put_user(ino, &dirent->d_ino);
1249 put_user(offset, &dirent->d_offset);
1250 put_user(namlen, &dirent->d_namlen);
1251 copy_to_user(dirent->d_name, name, namlen);
1252 put_user(0, dirent->d_name + namlen);
1253 return 0;
1256 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1258 int error = -EBADF;
1259 struct file * file;
1260 struct readdir_callback32 buf;
1262 file = fget(fd);
1263 if (!file)
1264 goto out;
1266 buf.count = 0;
1267 buf.dirent = dirent;
1269 error = vfs_readdir(file, fillonedir, &buf);
1270 if (error < 0)
1271 goto out_putf;
1272 error = buf.count;
1274 out_putf:
1275 fput(file);
1276 out:
1277 return error;
1280 struct linux_dirent32 {
1281 u32 d_ino;
1282 u32 d_off;
1283 unsigned short d_reclen;
1284 char d_name[1];
1287 struct getdents_callback32 {
1288 struct linux_dirent32 * current_dir;
1289 struct linux_dirent32 * previous;
1290 int count;
1291 int error;
1294 static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
1296 struct linux_dirent32 * dirent;
1297 struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1298 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1300 buf->error = -EINVAL; /* only used if we fail.. */
1301 if (reclen > buf->count)
1302 return -EINVAL;
1303 dirent = buf->previous;
1304 if (dirent)
1305 put_user(offset, &dirent->d_off);
1306 dirent = buf->current_dir;
1307 buf->previous = dirent;
1308 put_user(ino, &dirent->d_ino);
1309 put_user(reclen, &dirent->d_reclen);
1310 copy_to_user(dirent->d_name, name, namlen);
1311 put_user(0, dirent->d_name + namlen);
1312 ((char *) dirent) += reclen;
1313 buf->current_dir = dirent;
1314 buf->count -= reclen;
1315 return 0;
1318 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1320 struct file * file;
1321 struct linux_dirent32 * lastdirent;
1322 struct getdents_callback32 buf;
1323 int error = -EBADF;
1325 file = fget(fd);
1326 if (!file)
1327 goto out;
1329 buf.current_dir = dirent;
1330 buf.previous = NULL;
1331 buf.count = count;
1332 buf.error = 0;
1334 error = vfs_readdir(file, filldir, &buf);
1335 if (error < 0)
1336 goto out_putf;
1337 lastdirent = buf.previous;
1338 error = buf.error;
1339 if(lastdirent) {
1340 put_user(file->f_pos, &lastdirent->d_off);
1341 error = count - buf.count;
1343 out_putf:
1344 fput(file);
1345 out:
1346 return error;
1349 /* end of readdir & getdents */
1352 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1353 * 64-bit unsigned longs.
1356 static inline int
1357 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1359 if (ufdset) {
1360 unsigned long odd;
1362 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1363 return -EFAULT;
1365 odd = n & 1UL;
1366 n &= ~1UL;
1367 while (n) {
1368 unsigned long h, l;
1369 __get_user(l, ufdset);
1370 __get_user(h, ufdset+1);
1371 ufdset += 2;
1372 *fdset++ = h << 32 | l;
1373 n -= 2;
1375 if (odd)
1376 __get_user(*fdset, ufdset);
1377 } else {
1378 /* Tricky, must clear full unsigned long in the
1379 * kernel fdset at the end, this makes sure that
1380 * actually happens.
1382 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1384 return 0;
1387 static inline void
1388 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1390 unsigned long odd;
1392 if (!ufdset)
1393 return;
1395 odd = n & 1UL;
1396 n &= ~1UL;
1397 while (n) {
1398 unsigned long h, l;
1399 l = *fdset++;
1400 h = l >> 32;
1401 __put_user(l, ufdset);
1402 __put_user(h, ufdset+1);
1403 ufdset += 2;
1404 n -= 2;
1406 if (odd)
1407 __put_user(*fdset, ufdset);
1410 #define MAX_SELECT_SECONDS \
1411 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1413 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1415 fd_set_bits fds;
1416 struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1417 char *bits;
1418 unsigned long nn;
1419 long timeout;
1420 int ret, size;
1422 timeout = MAX_SCHEDULE_TIMEOUT;
1423 if (tvp) {
1424 time_t sec, usec;
1426 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1427 || (ret = __get_user(sec, &tvp->tv_sec))
1428 || (ret = __get_user(usec, &tvp->tv_usec)))
1429 goto out_nofds;
1431 ret = -EINVAL;
1432 if(sec < 0 || usec < 0)
1433 goto out_nofds;
1435 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1436 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1437 timeout += sec * (unsigned long) HZ;
1441 ret = -EINVAL;
1442 if (n < 0)
1443 goto out_nofds;
1444 if (n > current->files->max_fdset)
1445 n = current->files->max_fdset;
1448 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1449 * since we used fdset we need to allocate memory in units of
1450 * long-words.
1452 ret = -ENOMEM;
1453 size = FDS_BYTES(n);
1454 bits = kmalloc(6 * size, GFP_KERNEL);
1455 if (!bits)
1456 goto out_nofds;
1457 fds.in = (unsigned long *) bits;
1458 fds.out = (unsigned long *) (bits + size);
1459 fds.ex = (unsigned long *) (bits + 2*size);
1460 fds.res_in = (unsigned long *) (bits + 3*size);
1461 fds.res_out = (unsigned long *) (bits + 4*size);
1462 fds.res_ex = (unsigned long *) (bits + 5*size);
1464 nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1465 if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1466 (ret = get_fd_set32(nn, fds.out, outp)) ||
1467 (ret = get_fd_set32(nn, fds.ex, exp)))
1468 goto out;
1469 zero_fd_set(n, fds.res_in);
1470 zero_fd_set(n, fds.res_out);
1471 zero_fd_set(n, fds.res_ex);
1473 ret = do_select(n, &fds, &timeout);
1475 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1476 time_t sec = 0, usec = 0;
1477 if (timeout) {
1478 sec = timeout / HZ;
1479 usec = timeout % HZ;
1480 usec *= (1000000/HZ);
1482 put_user(sec, &tvp->tv_sec);
1483 put_user(usec, &tvp->tv_usec);
1486 if (ret < 0)
1487 goto out;
1488 if (!ret) {
1489 ret = -ERESTARTNOHAND;
1490 if (signal_pending(current))
1491 goto out;
1492 ret = 0;
1495 set_fd_set32(nn, inp, fds.res_in);
1496 set_fd_set32(nn, outp, fds.res_out);
1497 set_fd_set32(nn, exp, fds.res_ex);
1499 out:
1500 kfree(bits);
1501 out_nofds:
1502 return ret;
1505 static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1507 unsigned long ino, blksize, blocks;
1508 kdev_t dev, rdev;
1509 umode_t mode;
1510 nlink_t nlink;
1511 uid_t uid;
1512 gid_t gid;
1513 off_t size;
1514 time_t atime, mtime, ctime;
1515 int err;
1517 /* Stream the loads of inode data into the load buffer,
1518 * then we push it all into the store buffer below. This
1519 * should give optimal cache performance.
1521 ino = inode->i_ino;
1522 dev = inode->i_dev;
1523 mode = inode->i_mode;
1524 nlink = inode->i_nlink;
1525 uid = inode->i_uid;
1526 gid = inode->i_gid;
1527 rdev = inode->i_rdev;
1528 size = inode->i_size;
1529 atime = inode->i_atime;
1530 mtime = inode->i_mtime;
1531 ctime = inode->i_ctime;
1532 blksize = inode->i_blksize;
1533 blocks = inode->i_blocks;
1535 err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1536 err |= put_user(ino, &statbuf->st_ino);
1537 err |= put_user(mode, &statbuf->st_mode);
1538 err |= put_user(nlink, &statbuf->st_nlink);
1539 err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1540 err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1541 err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1542 err |= put_user(size, &statbuf->st_size);
1543 err |= put_user(atime, &statbuf->st_atime);
1544 err |= put_user(0, &statbuf->__unused1);
1545 err |= put_user(mtime, &statbuf->st_mtime);
1546 err |= put_user(0, &statbuf->__unused2);
1547 err |= put_user(ctime, &statbuf->st_ctime);
1548 err |= put_user(0, &statbuf->__unused3);
1549 if (blksize) {
1550 err |= put_user(blksize, &statbuf->st_blksize);
1551 err |= put_user(blocks, &statbuf->st_blocks);
1552 } else {
1553 unsigned int tmp_blocks;
1555 #define D_B 7
1556 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
1557 tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1558 if (tmp_blocks > D_B) {
1559 unsigned int indirect;
1561 indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1562 tmp_blocks += indirect;
1563 if (indirect > 1) {
1564 indirect = (indirect - 1 + I_B - 1) / I_B;
1565 tmp_blocks += indirect;
1566 if (indirect > 1)
1567 tmp_blocks++;
1570 err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1571 err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1572 #undef D_B
1573 #undef I_B
1575 err |= put_user(0, &statbuf->__unused4[0]);
1576 err |= put_user(0, &statbuf->__unused4[1]);
1578 return err;
1581 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1583 struct nameidata nd;
1584 int error;
1586 error = user_path_walk(filename, &nd);
1587 if (!error) {
1588 struct inode *inode = nd.dentry->d_inode;
1590 if (inode->i_op &&
1591 inode->i_op->revalidate)
1592 error = inode->i_op->revalidate(nd.dentry);
1593 else
1594 error = 0;
1595 if (!error)
1596 error = cp_new_stat32(inode, statbuf);
1598 path_release(&nd);
1600 return error;
1603 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1605 struct nameidata nd;
1606 int error;
1608 error = user_path_walk_link(filename, &nd);
1609 if (!error) {
1610 struct inode *inode = nd.dentry->d_inode;
1612 if (inode->i_op &&
1613 inode->i_op->revalidate)
1614 error = inode->i_op->revalidate(nd.dentry);
1615 else
1616 error = 0;
1617 if (!error)
1618 error = cp_new_stat32(inode, statbuf);
1620 path_release(&nd);
1622 return error;
1625 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1627 struct file *f;
1628 int err = -EBADF;
1630 f = fget(fd);
1631 if (f) {
1632 struct inode *inode = f->f_dentry->d_inode;
1634 if (inode->i_op &&
1635 inode->i_op->revalidate)
1636 err = inode->i_op->revalidate(f->f_dentry);
1637 else
1638 err = 0;
1639 if (!err)
1640 err = cp_new_stat32(inode, statbuf);
1642 fput(f);
1644 return err;
1647 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1649 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1651 return sys_sysfs(option, arg1, arg2);
1654 struct ncp_mount_data32 {
1655 int version;
1656 unsigned int ncp_fd;
1657 __kernel_uid_t32 mounted_uid;
1658 __kernel_pid_t32 wdog_pid;
1659 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1660 unsigned int time_out;
1661 unsigned int retry_count;
1662 unsigned int flags;
1663 __kernel_uid_t32 uid;
1664 __kernel_gid_t32 gid;
1665 __kernel_mode_t32 file_mode;
1666 __kernel_mode_t32 dir_mode;
1669 static void *do_ncp_super_data_conv(void *raw_data)
1671 struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
1672 struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
1674 n->dir_mode = n32->dir_mode;
1675 n->file_mode = n32->file_mode;
1676 n->gid = low2highgid(n32->gid);
1677 n->uid = low2highuid(n32->uid);
1678 memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
1679 n->wdog_pid = n32->wdog_pid;
1680 n->mounted_uid = low2highuid(n32->mounted_uid);
1681 return raw_data;
1684 struct smb_mount_data32 {
1685 int version;
1686 __kernel_uid_t32 mounted_uid;
1687 __kernel_uid_t32 uid;
1688 __kernel_gid_t32 gid;
1689 __kernel_mode_t32 file_mode;
1690 __kernel_mode_t32 dir_mode;
1693 static void *do_smb_super_data_conv(void *raw_data)
1695 struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
1696 struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1698 s->version = s32->version;
1699 s->mounted_uid = low2highuid(s32->mounted_uid);
1700 s->uid = low2highuid(s32->uid);
1701 s->gid = low2highgid(s32->gid);
1702 s->file_mode = s32->file_mode;
1703 s->dir_mode = s32->dir_mode;
1704 return raw_data;
1707 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1709 int i;
1710 unsigned long page;
1711 struct vm_area_struct *vma;
1713 *kernel = 0;
1714 if(!user)
1715 return 0;
1716 vma = find_vma(current->mm, (unsigned long)user);
1717 if(!vma || (unsigned long)user < vma->vm_start)
1718 return -EFAULT;
1719 if(!(vma->vm_flags & VM_READ))
1720 return -EFAULT;
1721 i = vma->vm_end - (unsigned long) user;
1722 if(PAGE_SIZE <= (unsigned long) i)
1723 i = PAGE_SIZE - 1;
1724 if(!(page = __get_free_page(GFP_KERNEL)))
1725 return -ENOMEM;
1726 if(copy_from_user((void *) page, user, i)) {
1727 free_page(page);
1728 return -EFAULT;
1730 *kernel = page;
1731 return 0;
1734 #define SMBFS_NAME "smbfs"
1735 #define NCPFS_NAME "ncpfs"
1737 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1739 unsigned long type_page = 0;
1740 unsigned long data_page = 0;
1741 unsigned long dev_page = 0;
1742 unsigned long dir_page = 0;
1743 int err, is_smb, is_ncp;
1745 is_smb = is_ncp = 0;
1747 lock_kernel();
1748 err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1749 if (err)
1750 goto out;
1752 if (!type_page) {
1753 err = -EINVAL;
1754 goto out;
1757 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1758 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1760 err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1761 if (err)
1762 goto type_out;
1764 err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1765 if (err)
1766 goto data_out;
1768 err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1769 if (err)
1770 goto dev_out;
1772 if (!is_smb && !is_ncp) {
1773 err = do_mount((char*)dev_page, (char*)dir_page,
1774 (char*)type_page, new_flags, (char*)data_page);
1775 } else {
1776 if (is_ncp)
1777 do_ncp_super_data_conv((void *)data_page);
1778 else
1779 do_smb_super_data_conv((void *)data_page);
1781 err = do_mount((char*)dev_page, (char*)dir_page,
1782 (char*)type_page, new_flags, (char*)data_page);
1784 free_page(dir_page);
1786 dev_out:
1787 free_page(dev_page);
1789 data_out:
1790 free_page(data_page);
1792 type_out:
1793 free_page(type_page);
1795 out:
1796 unlock_kernel();
1797 return err;
1800 struct rusage32 {
1801 struct timeval32 ru_utime;
1802 struct timeval32 ru_stime;
1803 s32 ru_maxrss;
1804 s32 ru_ixrss;
1805 s32 ru_idrss;
1806 s32 ru_isrss;
1807 s32 ru_minflt;
1808 s32 ru_majflt;
1809 s32 ru_nswap;
1810 s32 ru_inblock;
1811 s32 ru_oublock;
1812 s32 ru_msgsnd;
1813 s32 ru_msgrcv;
1814 s32 ru_nsignals;
1815 s32 ru_nvcsw;
1816 s32 ru_nivcsw;
1819 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1821 int err;
1823 err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1824 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1825 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1826 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1827 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1828 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1829 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1830 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1831 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1832 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1833 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1834 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1835 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1836 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1837 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1838 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1839 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1840 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1841 return err;
1844 extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
1845 int options, struct rusage * ru);
1847 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1849 if (!ru)
1850 return sys_wait4(pid, stat_addr, options, NULL);
1851 else {
1852 struct rusage r;
1853 int ret;
1854 unsigned int status;
1855 mm_segment_t old_fs = get_fs();
1857 set_fs (KERNEL_DS);
1858 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1859 set_fs (old_fs);
1860 if (put_rusage (ru, &r)) return -EFAULT;
1861 if (stat_addr && put_user (status, stat_addr))
1862 return -EFAULT;
1863 return ret;
1867 struct sysinfo32 {
1868 s32 uptime;
1869 u32 loads[3];
1870 u32 totalram;
1871 u32 freeram;
1872 u32 sharedram;
1873 u32 bufferram;
1874 u32 totalswap;
1875 u32 freeswap;
1876 unsigned short procs;
1877 char _f[22];
1880 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1882 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1884 struct sysinfo s;
1885 int ret, err;
1886 mm_segment_t old_fs = get_fs ();
1888 set_fs (KERNEL_DS);
1889 ret = sys_sysinfo(&s);
1890 set_fs (old_fs);
1891 err = put_user (s.uptime, &info->uptime);
1892 err |= __put_user (s.loads[0], &info->loads[0]);
1893 err |= __put_user (s.loads[1], &info->loads[1]);
1894 err |= __put_user (s.loads[2], &info->loads[2]);
1895 err |= __put_user (s.totalram, &info->totalram);
1896 err |= __put_user (s.freeram, &info->freeram);
1897 err |= __put_user (s.sharedram, &info->sharedram);
1898 err |= __put_user (s.bufferram, &info->bufferram);
1899 err |= __put_user (s.totalswap, &info->totalswap);
1900 err |= __put_user (s.freeswap, &info->freeswap);
1901 err |= __put_user (s.procs, &info->procs);
1902 if (err)
1903 return -EFAULT;
1904 return ret;
1907 struct timespec32 {
1908 s32 tv_sec;
1909 s32 tv_nsec;
1912 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1914 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1916 struct timespec t;
1917 int ret;
1918 mm_segment_t old_fs = get_fs ();
1920 set_fs (KERNEL_DS);
1921 ret = sys_sched_rr_get_interval(pid, &t);
1922 set_fs (old_fs);
1923 if (put_user (t.tv_sec, &interval->tv_sec) ||
1924 __put_user (t.tv_nsec, &interval->tv_nsec))
1925 return -EFAULT;
1926 return ret;
1929 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1931 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1933 struct timespec t;
1934 int ret;
1935 mm_segment_t old_fs = get_fs ();
1937 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1938 __get_user (t.tv_nsec, &rqtp->tv_nsec))
1939 return -EFAULT;
1940 set_fs (KERNEL_DS);
1941 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1942 set_fs (old_fs);
1943 if (rmtp && ret == -EINTR) {
1944 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1945 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1946 return -EFAULT;
1948 return ret;
1951 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1953 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1955 old_sigset_t s;
1956 int ret;
1957 mm_segment_t old_fs = get_fs();
1959 if (set && get_user (s, set)) return -EFAULT;
1960 set_fs (KERNEL_DS);
1961 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1962 set_fs (old_fs);
1963 if (ret) return ret;
1964 if (oset && put_user (s, oset)) return -EFAULT;
1965 return 0;
1968 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
1970 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
1972 sigset_t s;
1973 sigset_t32 s32;
1974 int ret;
1975 mm_segment_t old_fs = get_fs();
1977 if (set) {
1978 if (copy_from_user (&s32, set, sizeof(sigset_t32)))
1979 return -EFAULT;
1980 switch (_NSIG_WORDS) {
1981 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
1982 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
1983 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1984 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1987 set_fs (KERNEL_DS);
1988 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
1989 set_fs (old_fs);
1990 if (ret) return ret;
1991 if (oset) {
1992 switch (_NSIG_WORDS) {
1993 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
1994 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
1995 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
1996 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
1998 if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
1999 return -EFAULT;
2001 return 0;
2004 extern asmlinkage int sys_sigpending(old_sigset_t *set);
2006 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
2008 old_sigset_t s;
2009 int ret;
2010 mm_segment_t old_fs = get_fs();
2012 set_fs (KERNEL_DS);
2013 ret = sys_sigpending(&s);
2014 set_fs (old_fs);
2015 if (put_user (s, set)) return -EFAULT;
2016 return ret;
2019 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
2021 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
2023 sigset_t s;
2024 sigset_t32 s32;
2025 int ret;
2026 mm_segment_t old_fs = get_fs();
2028 set_fs (KERNEL_DS);
2029 ret = sys_rt_sigpending(&s, sigsetsize);
2030 set_fs (old_fs);
2031 if (!ret) {
2032 switch (_NSIG_WORDS) {
2033 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2034 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2035 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2036 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2038 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
2039 return -EFAULT;
2041 return ret;
2044 asmlinkage int
2045 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
2046 struct timespec32 *uts, __kernel_size_t32 sigsetsize)
2048 int ret, sig;
2049 sigset_t these;
2050 sigset_t32 these32;
2051 struct timespec ts;
2052 siginfo_t info;
2053 long timeout = 0;
2055 /* XXX: Don't preclude handling different sized sigset_t's. */
2056 if (sigsetsize != sizeof(sigset_t))
2057 return -EINVAL;
2059 if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
2060 return -EFAULT;
2062 switch (_NSIG_WORDS) {
2063 case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
2064 case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
2065 case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
2066 case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
2070 * Invert the set of allowed signals to get those we
2071 * want to block.
2073 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2074 signotset(&these);
2076 if (uts) {
2077 if (get_user (ts.tv_sec, &uts->tv_sec) ||
2078 get_user (ts.tv_nsec, &uts->tv_nsec))
2079 return -EINVAL;
2080 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
2081 || ts.tv_sec < 0)
2082 return -EINVAL;
2085 spin_lock_irq(&current->sigmask_lock);
2086 sig = dequeue_signal(&these, &info);
2087 if (!sig) {
2088 /* None ready -- temporarily unblock those we're interested
2089 in so that we'll be awakened when they arrive. */
2090 sigset_t oldblocked = current->blocked;
2091 sigandsets(&current->blocked, &current->blocked, &these);
2092 recalc_sigpending(current);
2093 spin_unlock_irq(&current->sigmask_lock);
2095 timeout = MAX_SCHEDULE_TIMEOUT;
2096 if (uts)
2097 timeout = (timespec_to_jiffies(&ts)
2098 + (ts.tv_sec || ts.tv_nsec));
2100 current->state = TASK_INTERRUPTIBLE;
2101 timeout = schedule_timeout(timeout);
2103 spin_lock_irq(&current->sigmask_lock);
2104 sig = dequeue_signal(&these, &info);
2105 current->blocked = oldblocked;
2106 recalc_sigpending(current);
2108 spin_unlock_irq(&current->sigmask_lock);
2110 if (sig) {
2111 ret = sig;
2112 if (uinfo) {
2113 if (copy_siginfo_to_user32(uinfo, &info))
2114 ret = -EFAULT;
2116 } else {
2117 ret = -EAGAIN;
2118 if (timeout)
2119 ret = -EINTR;
2122 return ret;
2125 extern asmlinkage int
2126 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2128 asmlinkage int
2129 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2131 siginfo_t info;
2132 int ret;
2133 mm_segment_t old_fs = get_fs();
2135 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2136 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2137 return -EFAULT;
2138 set_fs (KERNEL_DS);
2139 ret = sys_rt_sigqueueinfo(pid, sig, &info);
2140 set_fs (old_fs);
2141 return ret;
2144 struct tms32 {
2145 __kernel_clock_t32 tms_utime;
2146 __kernel_clock_t32 tms_stime;
2147 __kernel_clock_t32 tms_cutime;
2148 __kernel_clock_t32 tms_cstime;
2151 extern asmlinkage long sys_times(struct tms * tbuf);
2153 asmlinkage long sys32_times(struct tms32 *tbuf)
2155 struct tms t;
2156 long ret;
2157 mm_segment_t old_fs = get_fs ();
2158 int err;
2160 set_fs (KERNEL_DS);
2161 ret = sys_times(tbuf ? &t : NULL);
2162 set_fs (old_fs);
2163 if (tbuf) {
2164 err = put_user (t.tms_utime, &tbuf->tms_utime);
2165 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2166 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2167 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2168 if (err)
2169 ret = -EFAULT;
2171 return ret;
2174 #define RLIM_INFINITY32 0x7fffffff
2175 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2177 struct rlimit32 {
2178 u32 rlim_cur;
2179 u32 rlim_max;
2182 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2184 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2186 struct rlimit r;
2187 int ret;
2188 mm_segment_t old_fs = get_fs ();
2190 set_fs (KERNEL_DS);
2191 ret = sys_getrlimit(resource, &r);
2192 set_fs (old_fs);
2193 if (!ret) {
2194 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2195 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2197 return ret;
2200 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2202 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2204 struct rlimit r;
2205 int ret;
2206 mm_segment_t old_fs = get_fs ();
2208 if (resource >= RLIM_NLIMITS) return -EINVAL;
2209 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2210 __get_user (r.rlim_max, &rlim->rlim_max))
2211 return -EFAULT;
2212 if (r.rlim_cur == RLIM_INFINITY32)
2213 r.rlim_cur = RLIM_INFINITY;
2214 if (r.rlim_max == RLIM_INFINITY32)
2215 r.rlim_max = RLIM_INFINITY;
2216 set_fs (KERNEL_DS);
2217 ret = sys_setrlimit(resource, &r);
2218 set_fs (old_fs);
2219 return ret;
2222 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2224 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2226 struct rusage r;
2227 int ret;
2228 mm_segment_t old_fs = get_fs();
2230 set_fs (KERNEL_DS);
2231 ret = sys_getrusage(who, &r);
2232 set_fs (old_fs);
2233 if (put_rusage (ru, &r)) return -EFAULT;
2234 return ret;
2237 /* XXX This really belongs in some header file... -DaveM */
2238 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2239 16 for IP, 16 for IPX,
2240 24 for IPv6,
2241 about 80 for AX.25 */
2243 /* XXX These as well... */
2244 extern __inline__ struct socket *socki_lookup(struct inode *inode)
2246 return &inode->u.socket_i;
2249 extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
2251 struct file *file;
2252 struct inode *inode;
2254 if (!(file = fget(fd)))
2256 *err = -EBADF;
2257 return NULL;
2260 inode = file->f_dentry->d_inode;
2261 if (!inode || !inode->i_sock || !socki_lookup(inode))
2263 *err = -ENOTSOCK;
2264 fput(file);
2265 return NULL;
2268 return socki_lookup(inode);
2271 extern __inline__ void sockfd_put(struct socket *sock)
2273 fput(sock->file);
2276 struct msghdr32 {
2277 u32 msg_name;
2278 int msg_namelen;
2279 u32 msg_iov;
2280 __kernel_size_t32 msg_iovlen;
2281 u32 msg_control;
2282 __kernel_size_t32 msg_controllen;
2283 unsigned msg_flags;
2286 struct cmsghdr32 {
2287 __kernel_size_t32 cmsg_len;
2288 int cmsg_level;
2289 int cmsg_type;
2292 /* Bleech... */
2293 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2294 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2296 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2298 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2299 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2300 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2302 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2303 (struct cmsghdr32 *)(ctl) : \
2304 (struct cmsghdr32 *)NULL)
2305 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2307 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2308 struct cmsghdr32 *__cmsg, int __cmsg_len)
2310 struct cmsghdr32 * __ptr;
2312 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2313 CMSG32_ALIGN(__cmsg_len));
2314 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2315 return NULL;
2317 return __ptr;
2320 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2321 struct cmsghdr32 *__cmsg,
2322 int __cmsg_len)
2324 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2325 __cmsg, __cmsg_len);
2328 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2329 struct iovec32 *uiov32,
2330 int niov)
2332 int tot_len = 0;
2334 while(niov > 0) {
2335 u32 len, buf;
2337 if(get_user(len, &uiov32->iov_len) ||
2338 get_user(buf, &uiov32->iov_base)) {
2339 tot_len = -EFAULT;
2340 break;
2342 tot_len += len;
2343 kiov->iov_base = (void *)A(buf);
2344 kiov->iov_len = (__kernel_size_t) len;
2345 uiov32++;
2346 kiov++;
2347 niov--;
2349 return tot_len;
2352 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2353 struct msghdr32 *umsg)
2355 u32 tmp1, tmp2, tmp3;
2356 int err;
2358 err = get_user(tmp1, &umsg->msg_name);
2359 err |= __get_user(tmp2, &umsg->msg_iov);
2360 err |= __get_user(tmp3, &umsg->msg_control);
2361 if (err)
2362 return -EFAULT;
2364 kmsg->msg_name = (void *)A(tmp1);
2365 kmsg->msg_iov = (struct iovec *)A(tmp2);
2366 kmsg->msg_control = (void *)A(tmp3);
2368 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2369 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2370 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2371 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2373 return err;
2376 /* I've named the args so it is easy to tell whose space the pointers are in. */
2377 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2378 char *kern_address, int mode)
2380 int tot_len;
2382 if(kern_msg->msg_namelen) {
2383 if(mode==VERIFY_READ) {
2384 int err = move_addr_to_kernel(kern_msg->msg_name,
2385 kern_msg->msg_namelen,
2386 kern_address);
2387 if(err < 0)
2388 return err;
2390 kern_msg->msg_name = kern_address;
2391 } else
2392 kern_msg->msg_name = NULL;
2394 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2395 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2396 GFP_KERNEL);
2397 if(!kern_iov)
2398 return -ENOMEM;
2401 tot_len = iov_from_user32_to_kern(kern_iov,
2402 (struct iovec32 *)kern_msg->msg_iov,
2403 kern_msg->msg_iovlen);
2404 if(tot_len >= 0)
2405 kern_msg->msg_iov = kern_iov;
2406 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2407 kfree(kern_iov);
2409 return tot_len;
2412 /* There is a lot of hair here because the alignment rules (and
2413 * thus placement) of cmsg headers and length are different for
2414 * 32-bit apps. -DaveM
2416 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2417 unsigned char *stackbuf, int stackbuf_size)
2419 struct cmsghdr32 *ucmsg;
2420 struct cmsghdr *kcmsg, *kcmsg_base;
2421 __kernel_size_t32 ucmlen;
2422 __kernel_size_t kcmlen, tmp;
2424 kcmlen = 0;
2425 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2426 ucmsg = CMSG32_FIRSTHDR(kmsg);
2427 while(ucmsg != NULL) {
2428 if(get_user(ucmlen, &ucmsg->cmsg_len))
2429 return -EFAULT;
2431 /* Catch bogons. */
2432 if(CMSG32_ALIGN(ucmlen) <
2433 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2434 return -EINVAL;
2435 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2436 + ucmlen) > kmsg->msg_controllen)
2437 return -EINVAL;
2439 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2440 CMSG_ALIGN(sizeof(struct cmsghdr)));
2441 kcmlen += tmp;
2442 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2444 if(kcmlen == 0)
2445 return -EINVAL;
2447 /* The kcmlen holds the 64-bit version of the control length.
2448 * It may not be modified as we do not stick it into the kmsg
2449 * until we have successfully copied over all of the data
2450 * from the user.
2452 if(kcmlen > stackbuf_size)
2453 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2454 if(kcmsg == NULL)
2455 return -ENOBUFS;
2457 /* Now copy them over neatly. */
2458 memset(kcmsg, 0, kcmlen);
2459 ucmsg = CMSG32_FIRSTHDR(kmsg);
2460 while(ucmsg != NULL) {
2461 __get_user(ucmlen, &ucmsg->cmsg_len);
2462 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2463 CMSG_ALIGN(sizeof(struct cmsghdr)));
2464 kcmsg->cmsg_len = tmp;
2465 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2466 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2468 /* Copy over the data. */
2469 if(copy_from_user(CMSG_DATA(kcmsg),
2470 CMSG32_DATA(ucmsg),
2471 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2472 goto out_free_efault;
2474 /* Advance. */
2475 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2476 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2479 /* Ok, looks like we made it. Hook it up and return success. */
2480 kmsg->msg_control = kcmsg_base;
2481 kmsg->msg_controllen = kcmlen;
2482 return 0;
2484 out_free_efault:
2485 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2486 kfree(kcmsg_base);
2487 return -EFAULT;
2490 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2491 int len, void *data)
2493 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2494 struct cmsghdr32 cmhdr;
2495 int cmlen = CMSG32_LEN(len);
2497 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2498 kmsg->msg_flags |= MSG_CTRUNC;
2499 return;
2502 if(kmsg->msg_controllen < cmlen) {
2503 kmsg->msg_flags |= MSG_CTRUNC;
2504 cmlen = kmsg->msg_controllen;
2506 cmhdr.cmsg_level = level;
2507 cmhdr.cmsg_type = type;
2508 cmhdr.cmsg_len = cmlen;
2510 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2511 return;
2512 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2513 return;
2514 cmlen = CMSG32_SPACE(len);
2515 kmsg->msg_control += cmlen;
2516 kmsg->msg_controllen -= cmlen;
2519 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2521 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2522 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2523 int fdnum = scm->fp->count;
2524 struct file **fp = scm->fp->fp;
2525 int *cmfptr;
2526 int err = 0, i;
2528 if (fdnum < fdmax)
2529 fdmax = fdnum;
2531 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2532 int new_fd;
2533 err = get_unused_fd();
2534 if (err < 0)
2535 break;
2536 new_fd = err;
2537 err = put_user(new_fd, cmfptr);
2538 if (err) {
2539 put_unused_fd(new_fd);
2540 break;
2542 /* Bump the usage count and install the file. */
2543 get_file(fp[i]);
2544 fd_install(new_fd, fp[i]);
2547 if (i > 0) {
2548 int cmlen = CMSG32_LEN(i * sizeof(int));
2549 if (!err)
2550 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2551 if (!err)
2552 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2553 if (!err)
2554 err = put_user(cmlen, &cm->cmsg_len);
2555 if (!err) {
2556 cmlen = CMSG32_SPACE(i * sizeof(int));
2557 kmsg->msg_control += cmlen;
2558 kmsg->msg_controllen -= cmlen;
2561 if (i < fdnum)
2562 kmsg->msg_flags |= MSG_CTRUNC;
2565 * All of the files that fit in the message have had their
2566 * usage counts incremented, so we just free the list.
2568 __scm_destroy(scm);
2571 /* In these cases we (currently) can just copy to data over verbatim
2572 * because all CMSGs created by the kernel have well defined types which
2573 * have the same layout in both the 32-bit and 64-bit API. One must add
2574 * some special cased conversions here if we start sending control messages
2575 * with incompatible types.
2577 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2578 * we do our work. The remaining cases are:
2580 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2581 * IP_TTL int 32-bit clean
2582 * IP_TOS __u8 32-bit clean
2583 * IP_RECVOPTS variable length 32-bit clean
2584 * IP_RETOPTS variable length 32-bit clean
2585 * (these last two are clean because the types are defined
2586 * by the IPv4 protocol)
2587 * IP_RECVERR struct sock_extended_err +
2588 * struct sockaddr_in 32-bit clean
2589 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2590 * struct sockaddr_in6 32-bit clean
2591 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2592 * IPV6_HOPLIMIT int 32-bit clean
2593 * IPV6_FLOWINFO u32 32-bit clean
2594 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2595 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2596 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2597 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2599 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2601 unsigned char *workbuf, *wp;
2602 unsigned long bufsz, space_avail;
2603 struct cmsghdr *ucmsg;
2605 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2606 space_avail = kmsg->msg_controllen + bufsz;
2607 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2608 if(workbuf == NULL)
2609 goto fail;
2611 /* To make this more sane we assume the kernel sends back properly
2612 * formatted control messages. Because of how the kernel will truncate
2613 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2615 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2616 while(((unsigned long)ucmsg) <=
2617 (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2618 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2619 int clen64, clen32;
2621 /* UCMSG is the 64-bit format CMSG entry in user-space.
2622 * KCMSG32 is within the kernel space temporary buffer
2623 * we use to convert into a 32-bit style CMSG.
2625 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2626 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2627 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2629 clen64 = kcmsg32->cmsg_len;
2630 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2631 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2632 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2633 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2634 kcmsg32->cmsg_len = clen32;
2636 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2637 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2640 /* Copy back fixed up data, and adjust pointers. */
2641 bufsz = (wp - workbuf);
2642 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2644 kmsg->msg_control = (struct cmsghdr *)
2645 (((char *)orig_cmsg_uptr) + bufsz);
2646 kmsg->msg_controllen = space_avail - bufsz;
2648 kfree(workbuf);
2649 return;
2651 fail:
2652 /* If we leave the 64-bit format CMSG chunks in there,
2653 * the application could get confused and crash. So to
2654 * ensure greater recovery, we report no CMSGs.
2656 kmsg->msg_controllen += bufsz;
2657 kmsg->msg_control = (void *) orig_cmsg_uptr;
2660 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2662 struct socket *sock;
2663 char address[MAX_SOCK_ADDR];
2664 struct iovec iov[UIO_FASTIOV];
2665 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2666 unsigned char *ctl_buf = ctl;
2667 struct msghdr kern_msg;
2668 int err, total_len;
2670 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2671 return -EFAULT;
2672 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2673 return -EINVAL;
2674 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2675 if (err < 0)
2676 goto out;
2677 total_len = err;
2679 if(kern_msg.msg_controllen) {
2680 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2681 if(err)
2682 goto out_freeiov;
2683 ctl_buf = kern_msg.msg_control;
2685 kern_msg.msg_flags = user_flags;
2687 lock_kernel();
2688 sock = sockfd_lookup(fd, &err);
2689 if (sock != NULL) {
2690 if (sock->file->f_flags & O_NONBLOCK)
2691 kern_msg.msg_flags |= MSG_DONTWAIT;
2692 err = sock_sendmsg(sock, &kern_msg, total_len);
2693 sockfd_put(sock);
2695 unlock_kernel();
2697 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2698 if(ctl_buf != ctl)
2699 kfree(ctl_buf);
2700 out_freeiov:
2701 if(kern_msg.msg_iov != iov)
2702 kfree(kern_msg.msg_iov);
2703 out:
2704 return err;
2707 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2709 struct iovec iovstack[UIO_FASTIOV];
2710 struct msghdr kern_msg;
2711 char addr[MAX_SOCK_ADDR];
2712 struct socket *sock;
2713 struct iovec *iov = iovstack;
2714 struct sockaddr *uaddr;
2715 int *uaddr_len;
2716 unsigned long cmsg_ptr;
2717 int err, total_len, len = 0;
2719 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2720 return -EFAULT;
2721 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2722 return -EINVAL;
2724 uaddr = kern_msg.msg_name;
2725 uaddr_len = &user_msg->msg_namelen;
2726 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2727 if (err < 0)
2728 goto out;
2729 total_len = err;
2731 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2732 kern_msg.msg_flags = 0;
2734 lock_kernel();
2735 sock = sockfd_lookup(fd, &err);
2736 if (sock != NULL) {
2737 struct scm_cookie scm;
2739 if (sock->file->f_flags & O_NONBLOCK)
2740 user_flags |= MSG_DONTWAIT;
2741 memset(&scm, 0, sizeof(scm));
2742 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2743 user_flags, &scm);
2744 if(err >= 0) {
2745 len = err;
2746 if(!kern_msg.msg_control) {
2747 if(sock->passcred || scm.fp)
2748 kern_msg.msg_flags |= MSG_CTRUNC;
2749 if(scm.fp)
2750 __scm_destroy(&scm);
2751 } else {
2752 /* If recvmsg processing itself placed some
2753 * control messages into user space, it's is
2754 * using 64-bit CMSG processing, so we need
2755 * to fix it up before we tack on more stuff.
2757 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2758 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2760 /* Wheee... */
2761 if(sock->passcred)
2762 put_cmsg32(&kern_msg,
2763 SOL_SOCKET, SCM_CREDENTIALS,
2764 sizeof(scm.creds), &scm.creds);
2765 if(scm.fp != NULL)
2766 scm_detach_fds32(&kern_msg, &scm);
2769 sockfd_put(sock);
2771 unlock_kernel();
2773 if(uaddr != NULL && err >= 0)
2774 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2775 if(cmsg_ptr != 0 && err >= 0) {
2776 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2777 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2778 err |= __put_user(uclen, &user_msg->msg_controllen);
2780 if(err >= 0)
2781 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2782 if(kern_msg.msg_iov != iov)
2783 kfree(kern_msg.msg_iov);
2784 out:
2785 if(err < 0)
2786 return err;
2787 return len;
2790 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2791 char *optval, int optlen);
2793 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2794 char *optval, int optlen)
2796 if (optname == SO_ATTACH_FILTER) {
2797 struct sock_fprog32 {
2798 __u16 len;
2799 __u32 filter;
2800 } *fprog32 = (struct sock_fprog32 *)optval;
2801 struct sock_fprog kfprog;
2802 struct sock_filter *kfilter;
2803 unsigned int fsize;
2804 mm_segment_t old_fs;
2805 __u32 uptr;
2806 int ret;
2808 if (get_user(kfprog.len, &fprog32->len) ||
2809 __get_user(uptr, &fprog32->filter))
2810 return -EFAULT;
2811 kfprog.filter = (struct sock_filter *)A(uptr);
2812 fsize = kfprog.len * sizeof(struct sock_filter);
2813 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2814 if (kfilter == NULL)
2815 return -ENOMEM;
2816 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2817 kfree(kfilter);
2818 return -EFAULT;
2820 kfprog.filter = kfilter;
2821 old_fs = get_fs();
2822 set_fs(KERNEL_DS);
2823 ret = sys_setsockopt(fd, level, optname,
2824 (char *)&kfprog, sizeof(kfprog));
2825 set_fs(old_fs);
2826 kfree(kfilter);
2827 return ret;
2829 return sys_setsockopt(fd, level, optname, optval, optlen);
2832 extern void check_pending(int signum);
2834 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2836 struct k_sigaction new_ka, old_ka;
2837 int ret;
2839 if(sig < 0) {
2840 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2841 sig = -sig;
2844 if (act) {
2845 old_sigset_t32 mask;
2847 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2848 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2849 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2850 ret |= __get_user(mask, &act->sa_mask);
2851 if (ret)
2852 return ret;
2853 new_ka.ka_restorer = NULL;
2854 siginitset(&new_ka.sa.sa_mask, mask);
2857 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2859 if (!ret && oact) {
2860 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2861 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2862 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2863 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2866 return ret;
2869 asmlinkage int
2870 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2871 void *restorer, __kernel_size_t32 sigsetsize)
2873 struct k_sigaction new_ka, old_ka;
2874 int ret;
2875 sigset_t32 set32;
2877 /* XXX: Don't preclude handling different sized sigset_t's. */
2878 if (sigsetsize != sizeof(sigset_t32))
2879 return -EINVAL;
2881 /* All tasks which use RT signals (effectively) use
2882 * new style signals.
2884 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2886 if (act) {
2887 new_ka.ka_restorer = restorer;
2888 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2889 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2890 switch (_NSIG_WORDS) {
2891 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2892 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2893 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2894 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2896 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2897 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2898 if (ret)
2899 return -EFAULT;
2902 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2904 if (!ret && oact) {
2905 switch (_NSIG_WORDS) {
2906 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
2907 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
2908 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
2909 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
2911 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2912 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
2913 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2914 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2917 return ret;
2922 * count32() counts the number of arguments/envelopes
2924 static int count32(u32 * argv)
2926 int i = 0;
2928 if (argv != NULL) {
2929 for (;;) {
2930 u32 p; int error;
2932 error = get_user(p,argv);
2933 if (error) return error;
2934 if (!p) break;
2935 argv++; i++;
2938 return i;
2942 * 'copy_string32()' copies argument/envelope strings from user
2943 * memory to free pages in kernel mem. These are in a format ready
2944 * to be put directly into the top of new user memory.
2946 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
2948 while (argc-- > 0) {
2949 u32 str;
2950 int len;
2951 unsigned long pos;
2953 if (get_user(str, argv + argc) ||
2954 !str ||
2955 !(len = strnlen_user((char *)A(str), bprm->p)))
2956 return -EFAULT;
2958 if (bprm->p < len)
2959 return -E2BIG;
2961 bprm->p -= len;
2963 pos = bprm->p;
2964 while (len) {
2965 char *kaddr;
2966 struct page *page;
2967 int offset, bytes_to_copy, new, err;
2969 offset = pos % PAGE_SIZE;
2970 page = bprm->page[pos / PAGE_SIZE];
2971 new = 0;
2972 if (!page) {
2973 page = alloc_page(GFP_USER);
2974 bprm->page[pos / PAGE_SIZE] = page;
2975 if (!page)
2976 return -ENOMEM;
2977 new = 1;
2979 kaddr = (char *)kmap(page);
2981 if (new && offset)
2982 memset(kaddr, 0, offset);
2983 bytes_to_copy = PAGE_SIZE - offset;
2984 if (bytes_to_copy > len) {
2985 bytes_to_copy = len;
2986 if (new)
2987 memset(kaddr+offset+len, 0,
2988 PAGE_SIZE-offset-len);
2991 err = copy_from_user(kaddr + offset, (char *)A(str),
2992 bytes_to_copy);
2993 flush_page_to_ram(page);
2994 kunmap((unsigned long)kaddr);
2996 if (err)
2997 return -EFAULT;
2999 pos += bytes_to_copy;
3000 str += bytes_to_copy;
3001 len -= bytes_to_copy;
3004 return 0;
3008 * sys32_execve() executes a new program.
3010 static inline int
3011 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
3013 struct linux_binprm bprm;
3014 struct file * file;
3015 int retval;
3016 int i;
3018 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3019 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3021 file = open_exec(filename);
3023 retval = PTR_ERR(file);
3024 if (IS_ERR(file))
3025 return retval;
3027 bprm.file = file;
3028 bprm.filename = filename;
3029 bprm.sh_bang = 0;
3030 bprm.loader = 0;
3031 bprm.exec = 0;
3032 if ((bprm.argc = count32(argv)) < 0) {
3033 allow_write_access(file);
3034 fput(file);
3035 return bprm.argc;
3037 if ((bprm.envc = count32(envp)) < 0) {
3038 allow_write_access(file);
3039 fput(file);
3040 return bprm.envc;
3043 retval = prepare_binprm(&bprm);
3044 if (retval < 0)
3045 goto out;
3047 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3048 if (retval < 0)
3049 goto out;
3051 bprm.exec = bprm.p;
3052 retval = copy_strings32(bprm.envc, envp, &bprm);
3053 if (retval < 0)
3054 goto out;
3056 retval = copy_strings32(bprm.argc, argv, &bprm);
3057 if (retval < 0)
3058 goto out;
3060 retval = search_binary_handler(&bprm, regs);
3061 if (retval >= 0)
3062 /* execve success */
3063 return retval;
3065 out:
3066 /* Something went wrong, return the inode and free the argument pages*/
3067 allow_write_access(bprm.file);
3068 if (bprm.file)
3069 fput(bprm.file);
3071 for (i=0 ; i<MAX_ARG_PAGES ; i++)
3072 if (bprm.page[i])
3073 __free_page(bprm.page[i]);
3075 return retval;
3079 * sparc32_execve() executes a new program after the asm stub has set
3080 * things up for us. This should basically do what I want it to.
3082 asmlinkage int sparc32_execve(struct pt_regs *regs)
3084 int error, base = 0;
3085 char *filename;
3087 /* User register window flush is done by entry.S */
3089 /* Check for indirect call. */
3090 if((u32)regs->u_regs[UREG_G1] == 0)
3091 base = 1;
3093 filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
3094 error = PTR_ERR(filename);
3095 if(IS_ERR(filename))
3096 goto out;
3097 error = do_execve32(filename,
3098 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3099 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3100 putname(filename);
3102 if(!error) {
3103 fprs_write(0);
3104 current->thread.xfsr[0] = 0;
3105 current->thread.fpsaved[0] = 0;
3106 regs->tstate &= ~TSTATE_PEF;
3108 out:
3109 return error;
3112 #ifdef CONFIG_MODULES
3114 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3116 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3118 return sys_create_module(name_user, (size_t)size);
3121 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3123 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3124 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3126 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3128 return sys_init_module(name_user, mod_user);
3131 extern asmlinkage int sys_delete_module(const char *name_user);
3133 asmlinkage int sys32_delete_module(const char *name_user)
3135 return sys_delete_module(name_user);
3138 struct module_info32 {
3139 u32 addr;
3140 u32 size;
3141 u32 flags;
3142 s32 usecount;
3145 /* Query various bits about modules. */
3147 static inline long
3148 get_mod_name(const char *user_name, char **buf)
3150 unsigned long page;
3151 long retval;
3153 if ((unsigned long)user_name >= TASK_SIZE
3154 && !segment_eq(get_fs (), KERNEL_DS))
3155 return -EFAULT;
3157 page = __get_free_page(GFP_KERNEL);
3158 if (!page)
3159 return -ENOMEM;
3161 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3162 if (retval > 0) {
3163 if (retval < PAGE_SIZE) {
3164 *buf = (char *)page;
3165 return retval;
3167 retval = -ENAMETOOLONG;
3168 } else if (!retval)
3169 retval = -EINVAL;
3171 free_page(page);
3172 return retval;
3175 static inline void
3176 put_mod_name(char *buf)
3178 free_page((unsigned long)buf);
3181 static __inline__ struct module *find_module(const char *name)
3183 struct module *mod;
3185 for (mod = module_list; mod ; mod = mod->next) {
3186 if (mod->flags & MOD_DELETED)
3187 continue;
3188 if (!strcmp(mod->name, name))
3189 break;
3192 return mod;
3195 static int
3196 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3198 struct module *mod;
3199 size_t nmod, space, len;
3201 nmod = space = 0;
3203 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3204 len = strlen(mod->name)+1;
3205 if (len > bufsize)
3206 goto calc_space_needed;
3207 if (copy_to_user(buf, mod->name, len))
3208 return -EFAULT;
3209 buf += len;
3210 bufsize -= len;
3211 space += len;
3214 if (put_user(nmod, ret))
3215 return -EFAULT;
3216 else
3217 return 0;
3219 calc_space_needed:
3220 space += len;
3221 while ((mod = mod->next)->next != NULL)
3222 space += strlen(mod->name)+1;
3224 if (put_user(space, ret))
3225 return -EFAULT;
3226 else
3227 return -ENOSPC;
3230 static int
3231 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3233 size_t i, space, len;
3235 if (mod->next == NULL)
3236 return -EINVAL;
3237 if (!MOD_CAN_QUERY(mod))
3238 return put_user(0, ret);
3240 space = 0;
3241 for (i = 0; i < mod->ndeps; ++i) {
3242 const char *dep_name = mod->deps[i].dep->name;
3244 len = strlen(dep_name)+1;
3245 if (len > bufsize)
3246 goto calc_space_needed;
3247 if (copy_to_user(buf, dep_name, len))
3248 return -EFAULT;
3249 buf += len;
3250 bufsize -= len;
3251 space += len;
3254 return put_user(i, ret);
3256 calc_space_needed:
3257 space += len;
3258 while (++i < mod->ndeps)
3259 space += strlen(mod->deps[i].dep->name)+1;
3261 if (put_user(space, ret))
3262 return -EFAULT;
3263 else
3264 return -ENOSPC;
3267 static int
3268 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3270 size_t nrefs, space, len;
3271 struct module_ref *ref;
3273 if (mod->next == NULL)
3274 return -EINVAL;
3275 if (!MOD_CAN_QUERY(mod))
3276 if (put_user(0, ret))
3277 return -EFAULT;
3278 else
3279 return 0;
3281 space = 0;
3282 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3283 const char *ref_name = ref->ref->name;
3285 len = strlen(ref_name)+1;
3286 if (len > bufsize)
3287 goto calc_space_needed;
3288 if (copy_to_user(buf, ref_name, len))
3289 return -EFAULT;
3290 buf += len;
3291 bufsize -= len;
3292 space += len;
3295 if (put_user(nrefs, ret))
3296 return -EFAULT;
3297 else
3298 return 0;
3300 calc_space_needed:
3301 space += len;
3302 while ((ref = ref->next_ref) != NULL)
3303 space += strlen(ref->ref->name)+1;
3305 if (put_user(space, ret))
3306 return -EFAULT;
3307 else
3308 return -ENOSPC;
3311 static inline int
3312 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3314 size_t i, space, len;
3315 struct module_symbol *s;
3316 char *strings;
3317 unsigned *vals;
3319 if (!MOD_CAN_QUERY(mod))
3320 if (put_user(0, ret))
3321 return -EFAULT;
3322 else
3323 return 0;
3325 space = mod->nsyms * 2*sizeof(u32);
3327 i = len = 0;
3328 s = mod->syms;
3330 if (space > bufsize)
3331 goto calc_space_needed;
3333 if (!access_ok(VERIFY_WRITE, buf, space))
3334 return -EFAULT;
3336 bufsize -= space;
3337 vals = (unsigned *)buf;
3338 strings = buf+space;
3340 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3341 len = strlen(s->name)+1;
3342 if (len > bufsize)
3343 goto calc_space_needed;
3345 if (copy_to_user(strings, s->name, len)
3346 || __put_user(s->value, vals+0)
3347 || __put_user(space, vals+1))
3348 return -EFAULT;
3350 strings += len;
3351 bufsize -= len;
3352 space += len;
3355 if (put_user(i, ret))
3356 return -EFAULT;
3357 else
3358 return 0;
3360 calc_space_needed:
3361 for (; i < mod->nsyms; ++i, ++s)
3362 space += strlen(s->name)+1;
3364 if (put_user(space, ret))
3365 return -EFAULT;
3366 else
3367 return -ENOSPC;
3370 static inline int
3371 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3373 int error = 0;
3375 if (mod->next == NULL)
3376 return -EINVAL;
3378 if (sizeof(struct module_info32) <= bufsize) {
3379 struct module_info32 info;
3380 info.addr = (unsigned long)mod;
3381 info.size = mod->size;
3382 info.flags = mod->flags;
3383 info.usecount =
3384 ((mod_member_present(mod, can_unload)
3385 && mod->can_unload)
3386 ? -1 : atomic_read(&mod->uc.usecount));
3388 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3389 return -EFAULT;
3390 } else
3391 error = -ENOSPC;
3393 if (put_user(sizeof(struct module_info32), ret))
3394 return -EFAULT;
3396 return error;
3399 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3401 struct module *mod;
3402 int err;
3404 lock_kernel();
3405 if (name_user == 0) {
3406 /* This finds "kernel_module" which is not exported. */
3407 for(mod = module_list; mod->next != NULL; mod = mod->next)
3409 } else {
3410 long namelen;
3411 char *name;
3413 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3414 err = namelen;
3415 goto out;
3417 err = -ENOENT;
3418 if (namelen == 0) {
3419 /* This finds "kernel_module" which is not exported. */
3420 for(mod = module_list; mod->next != NULL; mod = mod->next)
3422 } else if ((mod = find_module(name)) == NULL) {
3423 put_mod_name(name);
3424 goto out;
3426 put_mod_name(name);
3429 switch (which)
3431 case 0:
3432 err = 0;
3433 break;
3434 case QM_MODULES:
3435 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3436 break;
3437 case QM_DEPS:
3438 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3439 break;
3440 case QM_REFS:
3441 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3442 break;
3443 case QM_SYMBOLS:
3444 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3445 break;
3446 case QM_INFO:
3447 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3448 break;
3449 default:
3450 err = -EINVAL;
3451 break;
3453 out:
3454 unlock_kernel();
3455 return err;
3458 struct kernel_sym32 {
3459 u32 value;
3460 char name[60];
3463 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3465 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3467 int len, i;
3468 struct kernel_sym *tbl;
3469 mm_segment_t old_fs;
3471 len = sys_get_kernel_syms(NULL);
3472 if (!table) return len;
3473 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3474 if (!tbl) return -ENOMEM;
3475 old_fs = get_fs();
3476 set_fs (KERNEL_DS);
3477 sys_get_kernel_syms(tbl);
3478 set_fs (old_fs);
3479 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3480 if (put_user (tbl[i].value, &table->value) ||
3481 copy_to_user (table->name, tbl[i].name, 60))
3482 break;
3484 kfree (tbl);
3485 return i;
3488 #else /* CONFIG_MODULES */
3490 asmlinkage unsigned long
3491 sys32_create_module(const char *name_user, size_t size)
3493 return -ENOSYS;
3496 asmlinkage int
3497 sys32_init_module(const char *name_user, struct module *mod_user)
3499 return -ENOSYS;
3502 asmlinkage int
3503 sys32_delete_module(const char *name_user)
3505 return -ENOSYS;
3508 asmlinkage int
3509 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3510 size_t *ret)
3512 /* Let the program know about the new interface. Not that
3513 it'll do them much good. */
3514 if (which == 0)
3515 return 0;
3517 return -ENOSYS;
3520 asmlinkage int
3521 sys32_get_kernel_syms(struct kernel_sym *table)
3523 return -ENOSYS;
3526 #endif /* CONFIG_MODULES */
3528 /* Stuff for NFS server syscalls... */
3529 struct nfsctl_svc32 {
3530 u16 svc32_port;
3531 s32 svc32_nthreads;
3534 struct nfsctl_client32 {
3535 s8 cl32_ident[NFSCLNT_IDMAX+1];
3536 s32 cl32_naddr;
3537 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3538 s32 cl32_fhkeytype;
3539 s32 cl32_fhkeylen;
3540 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3543 struct nfsctl_export32 {
3544 s8 ex32_client[NFSCLNT_IDMAX+1];
3545 s8 ex32_path[NFS_MAXPATHLEN+1];
3546 __kernel_dev_t32 ex32_dev;
3547 __kernel_ino_t32 ex32_ino;
3548 s32 ex32_flags;
3549 __kernel_uid_t32 ex32_anon_uid;
3550 __kernel_gid_t32 ex32_anon_gid;
3553 struct nfsctl_uidmap32 {
3554 u32 ug32_ident; /* char * */
3555 __kernel_uid_t32 ug32_uidbase;
3556 s32 ug32_uidlen;
3557 u32 ug32_udimap; /* uid_t * */
3558 __kernel_uid_t32 ug32_gidbase;
3559 s32 ug32_gidlen;
3560 u32 ug32_gdimap; /* gid_t * */
3563 struct nfsctl_fhparm32 {
3564 struct sockaddr gf32_addr;
3565 __kernel_dev_t32 gf32_dev;
3566 __kernel_ino_t32 gf32_ino;
3567 s32 gf32_version;
3570 struct nfsctl_fdparm32 {
3571 struct sockaddr gd32_addr;
3572 s8 gd32_path[NFS_MAXPATHLEN+1];
3573 s32 gd32_version;
3576 struct nfsctl_fsparm32 {
3577 struct sockaddr gd32_addr;
3578 s8 gd32_path[NFS_MAXPATHLEN+1];
3579 s32 gd32_maxlen;
3582 struct nfsctl_arg32 {
3583 s32 ca32_version; /* safeguard */
3584 union {
3585 struct nfsctl_svc32 u32_svc;
3586 struct nfsctl_client32 u32_client;
3587 struct nfsctl_export32 u32_export;
3588 struct nfsctl_uidmap32 u32_umap;
3589 struct nfsctl_fhparm32 u32_getfh;
3590 struct nfsctl_fdparm32 u32_getfd;
3591 struct nfsctl_fsparm32 u32_getfs;
3592 } u;
3593 #define ca32_svc u.u32_svc
3594 #define ca32_client u.u32_client
3595 #define ca32_export u.u32_export
3596 #define ca32_umap u.u32_umap
3597 #define ca32_getfh u.u32_getfh
3598 #define ca32_getfd u.u32_getfd
3599 #define ca32_getfs u.u32_getfs
3600 #define ca32_authd u.u32_authd
3603 union nfsctl_res32 {
3604 __u8 cr32_getfh[NFS_FHSIZE];
3605 struct knfsd_fh cr32_getfs;
3608 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3610 int err;
3612 err = __get_user(karg->ca_version, &arg32->ca32_version);
3613 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3614 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3615 return err;
3618 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3620 int err;
3622 err = __get_user(karg->ca_version, &arg32->ca32_version);
3623 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3624 &arg32->ca32_client.cl32_ident[0],
3625 NFSCLNT_IDMAX);
3626 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3627 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3628 &arg32->ca32_client.cl32_addrlist[0],
3629 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3630 err |= __get_user(karg->ca_client.cl_fhkeytype,
3631 &arg32->ca32_client.cl32_fhkeytype);
3632 err |= __get_user(karg->ca_client.cl_fhkeylen,
3633 &arg32->ca32_client.cl32_fhkeylen);
3634 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3635 &arg32->ca32_client.cl32_fhkey[0],
3636 NFSCLNT_KEYMAX);
3637 return err;
3640 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3642 int err;
3644 err = __get_user(karg->ca_version, &arg32->ca32_version);
3645 err |= copy_from_user(&karg->ca_export.ex_client[0],
3646 &arg32->ca32_export.ex32_client[0],
3647 NFSCLNT_IDMAX);
3648 err |= copy_from_user(&karg->ca_export.ex_path[0],
3649 &arg32->ca32_export.ex32_path[0],
3650 NFS_MAXPATHLEN);
3651 err |= __get_user(karg->ca_export.ex_dev,
3652 &arg32->ca32_export.ex32_dev);
3653 err |= __get_user(karg->ca_export.ex_ino,
3654 &arg32->ca32_export.ex32_ino);
3655 err |= __get_user(karg->ca_export.ex_flags,
3656 &arg32->ca32_export.ex32_flags);
3657 err |= __get_user(karg->ca_export.ex_anon_uid,
3658 &arg32->ca32_export.ex32_anon_uid);
3659 err |= __get_user(karg->ca_export.ex_anon_gid,
3660 &arg32->ca32_export.ex32_anon_gid);
3661 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3662 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3663 return err;
3666 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3668 u32 uaddr;
3669 int i;
3670 int err;
3672 memset(karg, 0, sizeof(*karg));
3673 if(__get_user(karg->ca_version, &arg32->ca32_version))
3674 return -EFAULT;
3675 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3676 if(!karg->ca_umap.ug_ident)
3677 return -ENOMEM;
3678 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3679 if(strncpy_from_user(karg->ca_umap.ug_ident,
3680 (char *)A(uaddr), PAGE_SIZE) <= 0)
3681 return -EFAULT;
3682 err |= __get_user(karg->ca_umap.ug_uidbase,
3683 &arg32->ca32_umap.ug32_uidbase);
3684 err |= __get_user(karg->ca_umap.ug_uidlen,
3685 &arg32->ca32_umap.ug32_uidlen);
3686 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3687 if (err)
3688 return -EFAULT;
3689 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3690 GFP_USER);
3691 if(!karg->ca_umap.ug_udimap)
3692 return -ENOMEM;
3693 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3694 err |= __get_user(karg->ca_umap.ug_udimap[i],
3695 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3696 err |= __get_user(karg->ca_umap.ug_gidbase,
3697 &arg32->ca32_umap.ug32_gidbase);
3698 err |= __get_user(karg->ca_umap.ug_uidlen,
3699 &arg32->ca32_umap.ug32_gidlen);
3700 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3701 if (err)
3702 return -EFAULT;
3703 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3704 GFP_USER);
3705 if(!karg->ca_umap.ug_gdimap)
3706 return -ENOMEM;
3707 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3708 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3709 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3711 return err;
3714 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3716 int err;
3718 err = __get_user(karg->ca_version, &arg32->ca32_version);
3719 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3720 &arg32->ca32_getfh.gf32_addr,
3721 (sizeof(struct sockaddr)));
3722 err |= __get_user(karg->ca_getfh.gf_dev,
3723 &arg32->ca32_getfh.gf32_dev);
3724 err |= __get_user(karg->ca_getfh.gf_ino,
3725 &arg32->ca32_getfh.gf32_ino);
3726 err |= __get_user(karg->ca_getfh.gf_version,
3727 &arg32->ca32_getfh.gf32_version);
3728 return err;
3731 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3733 int err;
3735 err = __get_user(karg->ca_version, &arg32->ca32_version);
3736 err |= copy_from_user(&karg->ca_getfd.gd_addr,
3737 &arg32->ca32_getfd.gd32_addr,
3738 (sizeof(struct sockaddr)));
3739 err |= copy_from_user(&karg->ca_getfd.gd_path,
3740 &arg32->ca32_getfd.gd32_path,
3741 (NFS_MAXPATHLEN+1));
3742 err |= __get_user(karg->ca_getfd.gd_version,
3743 &arg32->ca32_getfd.gd32_version);
3744 return err;
3747 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3749 int err;
3751 err = __get_user(karg->ca_version, &arg32->ca32_version);
3752 err |= copy_from_user(&karg->ca_getfs.gd_addr,
3753 &arg32->ca32_getfs.gd32_addr,
3754 (sizeof(struct sockaddr)));
3755 err |= copy_from_user(&karg->ca_getfs.gd_path,
3756 &arg32->ca32_getfs.gd32_path,
3757 (NFS_MAXPATHLEN+1));
3758 err |= __get_user(karg->ca_getfs.gd_maxlen,
3759 &arg32->ca32_getfs.gd32_maxlen);
3760 return err;
3763 /* This really doesn't need translations, we are only passing
3764 * back a union which contains opaque nfs file handle data.
3766 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3768 return copy_to_user(res32, kres, sizeof(*res32));
3771 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3773 struct nfsctl_arg *karg = NULL;
3774 union nfsctl_res *kres = NULL;
3775 mm_segment_t oldfs;
3776 int err;
3778 karg = kmalloc(sizeof(*karg), GFP_USER);
3779 if(!karg)
3780 return -ENOMEM;
3781 if(res32) {
3782 kres = kmalloc(sizeof(*kres), GFP_USER);
3783 if(!kres) {
3784 kfree(karg);
3785 return -ENOMEM;
3788 switch(cmd) {
3789 case NFSCTL_SVC:
3790 err = nfs_svc32_trans(karg, arg32);
3791 break;
3792 case NFSCTL_ADDCLIENT:
3793 err = nfs_clnt32_trans(karg, arg32);
3794 break;
3795 case NFSCTL_DELCLIENT:
3796 err = nfs_clnt32_trans(karg, arg32);
3797 break;
3798 case NFSCTL_EXPORT:
3799 case NFSCTL_UNEXPORT:
3800 err = nfs_exp32_trans(karg, arg32);
3801 break;
3802 /* This one is unimplemented, be we're ready for it. */
3803 case NFSCTL_UGIDUPDATE:
3804 err = nfs_uud32_trans(karg, arg32);
3805 break;
3806 case NFSCTL_GETFH:
3807 err = nfs_getfh32_trans(karg, arg32);
3808 break;
3809 case NFSCTL_GETFD:
3810 err = nfs_getfd32_trans(karg, arg32);
3811 break;
3812 case NFSCTL_GETFS:
3813 err = nfs_getfs32_trans(karg, arg32);
3814 break;
3815 default:
3816 err = -EINVAL;
3817 break;
3819 if(err)
3820 goto done;
3821 oldfs = get_fs();
3822 set_fs(KERNEL_DS);
3823 err = sys_nfsservctl(cmd, karg, kres);
3824 set_fs(oldfs);
3826 if (err)
3827 goto done;
3829 if((cmd == NFSCTL_GETFH) ||
3830 (cmd == NFSCTL_GETFD) ||
3831 (cmd == NFSCTL_GETFS))
3832 err = nfs_getfh32_res_trans(kres, res32);
3834 done:
3835 if(karg) {
3836 if(cmd == NFSCTL_UGIDUPDATE) {
3837 if(karg->ca_umap.ug_ident)
3838 kfree(karg->ca_umap.ug_ident);
3839 if(karg->ca_umap.ug_udimap)
3840 kfree(karg->ca_umap.ug_udimap);
3841 if(karg->ca_umap.ug_gdimap)
3842 kfree(karg->ca_umap.ug_gdimap);
3844 kfree(karg);
3846 if(kres)
3847 kfree(kres);
3848 return err;
3851 /* Translations due to time_t size differences. Which affects all
3852 sorts of things, like timeval and itimerval. */
3854 extern struct timezone sys_tz;
3855 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3857 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3859 if (tv) {
3860 struct timeval ktv;
3861 do_gettimeofday(&ktv);
3862 if (put_tv32(tv, &ktv))
3863 return -EFAULT;
3865 if (tz) {
3866 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3867 return -EFAULT;
3869 return 0;
3872 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3874 struct timeval ktv;
3875 struct timezone ktz;
3877 if (tv) {
3878 if (get_tv32(&ktv, tv))
3879 return -EFAULT;
3881 if (tz) {
3882 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3883 return -EFAULT;
3886 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3889 extern int do_getitimer(int which, struct itimerval *value);
3891 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3893 struct itimerval kit;
3894 int error;
3896 error = do_getitimer(which, &kit);
3897 if (!error && put_it32(it, &kit))
3898 error = -EFAULT;
3900 return error;
3903 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3905 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3907 struct itimerval kin, kout;
3908 int error;
3910 if (in) {
3911 if (get_it32(&kin, in))
3912 return -EFAULT;
3913 } else
3914 memset(&kin, 0, sizeof(kin));
3916 error = do_setitimer(which, &kin, out ? &kout : NULL);
3917 if (error || !out)
3918 return error;
3919 if (put_it32(out, &kout))
3920 return -EFAULT;
3922 return 0;
3926 asmlinkage int sys_utimes(char *, struct timeval *);
3928 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3930 char *kfilename;
3931 struct timeval ktvs[2];
3932 mm_segment_t old_fs;
3933 int ret;
3935 kfilename = getname32(filename);
3936 ret = PTR_ERR(kfilename);
3937 if (!IS_ERR(kfilename)) {
3938 if (tvs) {
3939 if (get_tv32(&ktvs[0], tvs) ||
3940 get_tv32(&ktvs[1], 1+tvs))
3941 return -EFAULT;
3944 old_fs = get_fs();
3945 set_fs(KERNEL_DS);
3946 ret = sys_utimes(kfilename, &ktvs[0]);
3947 set_fs(old_fs);
3949 putname(kfilename);
3951 return ret;
3954 /* These are here just in case some old sparc32 binary calls it. */
3955 asmlinkage int sys32_pause(void)
3957 current->state = TASK_INTERRUPTIBLE;
3958 schedule();
3959 return -ERESTARTNOHAND;
3962 /* PCI config space poking. */
3963 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3964 unsigned long dfn,
3965 unsigned long off,
3966 unsigned long len,
3967 unsigned char *buf);
3969 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3970 unsigned long dfn,
3971 unsigned long off,
3972 unsigned long len,
3973 unsigned char *buf);
3975 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3977 return sys_pciconfig_read((unsigned long) bus,
3978 (unsigned long) dfn,
3979 (unsigned long) off,
3980 (unsigned long) len,
3981 (unsigned char *)AA(ubuf));
3984 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3986 return sys_pciconfig_write((unsigned long) bus,
3987 (unsigned long) dfn,
3988 (unsigned long) off,
3989 (unsigned long) len,
3990 (unsigned char *)AA(ubuf));
3993 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
3994 unsigned long arg4, unsigned long arg5);
3996 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
3998 return sys_prctl(option,
3999 (unsigned long) arg2,
4000 (unsigned long) arg3,
4001 (unsigned long) arg4,
4002 (unsigned long) arg5);
4006 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4007 size_t count, loff_t pos);
4009 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4010 size_t count, loff_t pos);
4012 typedef __kernel_ssize_t32 ssize_t32;
4014 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
4015 __kernel_size_t32 count, u32 poshi, u32 poslo)
4017 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4020 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
4021 __kernel_size_t32 count, u32 poshi, u32 poslo)
4023 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4027 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4029 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4031 mm_segment_t old_fs = get_fs();
4032 int ret;
4033 off_t of;
4035 if (offset && get_user(of, offset))
4036 return -EFAULT;
4038 set_fs(KERNEL_DS);
4039 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4040 set_fs(old_fs);
4042 if (!ret && offset && put_user(of, offset))
4043 return -EFAULT;
4045 return ret;
4048 /* Handle adjtimex compatability. */
4050 struct timex32 {
4051 u32 modes;
4052 s32 offset, freq, maxerror, esterror;
4053 s32 status, constant, precision, tolerance;
4054 struct timeval32 time;
4055 s32 tick;
4056 s32 ppsfreq, jitter, shift, stabil;
4057 s32 jitcnt, calcnt, errcnt, stbcnt;
4058 s32 :32; s32 :32; s32 :32; s32 :32;
4059 s32 :32; s32 :32; s32 :32; s32 :32;
4060 s32 :32; s32 :32; s32 :32; s32 :32;
4063 extern int do_adjtimex(struct timex *);
4065 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4067 struct timex txc;
4068 int ret;
4070 memset(&txc, 0, sizeof(struct timex));
4072 if(get_user(txc.modes, &utp->modes) ||
4073 __get_user(txc.offset, &utp->offset) ||
4074 __get_user(txc.freq, &utp->freq) ||
4075 __get_user(txc.maxerror, &utp->maxerror) ||
4076 __get_user(txc.esterror, &utp->esterror) ||
4077 __get_user(txc.status, &utp->status) ||
4078 __get_user(txc.constant, &utp->constant) ||
4079 __get_user(txc.precision, &utp->precision) ||
4080 __get_user(txc.tolerance, &utp->tolerance) ||
4081 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4082 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4083 __get_user(txc.tick, &utp->tick) ||
4084 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4085 __get_user(txc.jitter, &utp->jitter) ||
4086 __get_user(txc.shift, &utp->shift) ||
4087 __get_user(txc.stabil, &utp->stabil) ||
4088 __get_user(txc.jitcnt, &utp->jitcnt) ||
4089 __get_user(txc.calcnt, &utp->calcnt) ||
4090 __get_user(txc.errcnt, &utp->errcnt) ||
4091 __get_user(txc.stbcnt, &utp->stbcnt))
4092 return -EFAULT;
4094 ret = do_adjtimex(&txc);
4096 if(put_user(txc.modes, &utp->modes) ||
4097 __put_user(txc.offset, &utp->offset) ||
4098 __put_user(txc.freq, &utp->freq) ||
4099 __put_user(txc.maxerror, &utp->maxerror) ||
4100 __put_user(txc.esterror, &utp->esterror) ||
4101 __put_user(txc.status, &utp->status) ||
4102 __put_user(txc.constant, &utp->constant) ||
4103 __put_user(txc.precision, &utp->precision) ||
4104 __put_user(txc.tolerance, &utp->tolerance) ||
4105 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4106 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4107 __put_user(txc.tick, &utp->tick) ||
4108 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4109 __put_user(txc.jitter, &utp->jitter) ||
4110 __put_user(txc.shift, &utp->shift) ||
4111 __put_user(txc.stabil, &utp->stabil) ||
4112 __put_user(txc.jitcnt, &utp->jitcnt) ||
4113 __put_user(txc.calcnt, &utp->calcnt) ||
4114 __put_user(txc.errcnt, &utp->errcnt) ||
4115 __put_user(txc.stbcnt, &utp->stbcnt))
4116 ret = -EFAULT;
4118 return ret;
4121 /* This is just a version for 32-bit applications which does
4122 * not force O_LARGEFILE on.
4125 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4127 char * tmp;
4128 int fd, error;
4130 tmp = getname(filename);
4131 fd = PTR_ERR(tmp);
4132 if (!IS_ERR(tmp)) {
4133 fd = get_unused_fd();
4134 if (fd >= 0) {
4135 struct file * f;
4136 lock_kernel();
4137 f = filp_open(tmp, flags, mode);
4138 unlock_kernel();
4139 error = PTR_ERR(f);
4140 if (IS_ERR(f))
4141 goto out_error;
4142 fd_install(fd, f);
4144 out:
4145 putname(tmp);
4147 return fd;
4149 out_error:
4150 put_unused_fd(fd);
4151 fd = error;
4152 goto out;
4155 extern unsigned long do_mremap(unsigned long addr,
4156 unsigned long old_len, unsigned long new_len,
4157 unsigned long flags, unsigned long new_addr);
4159 asmlinkage unsigned long sys32_mremap(unsigned long addr,
4160 unsigned long old_len, unsigned long new_len,
4161 unsigned long flags, u32 __new_addr)
4163 unsigned long ret = -EINVAL;
4164 unsigned long new_addr = AA(__new_addr);
4166 if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
4167 goto out;
4168 if (addr > 0xf0000000UL - old_len)
4169 goto out;
4170 down(&current->mm->mmap_sem);
4171 if (flags & MREMAP_FIXED) {
4172 if (new_addr > 0xf0000000UL - new_len)
4173 goto out_sem;
4174 } else if (addr > 0xf0000000UL - new_len) {
4175 ret = -ENOMEM;
4176 if (!(flags & MREMAP_MAYMOVE))
4177 goto out_sem;
4178 new_addr = get_unmapped_area (addr, new_len);
4179 if (!new_addr)
4180 goto out_sem;
4181 flags |= MREMAP_FIXED;
4183 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
4184 out_sem:
4185 up(&current->mm->mmap_sem);
4186 out:
4187 return ret;