Import 2.4.0-test3pre1
[davej-history.git] / arch / sparc64 / kernel / sys_sparc32.c
blobe27892de30d7e2bbeb56317300a2532acf574d12
1 /* $Id: sys_sparc32.c,v 1.152 2000/06/22 17:44:47 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 lock_kernel();
1270 error = vfs_readdir(file, fillonedir, &buf);
1271 if (error < 0)
1272 goto out_putf;
1273 error = buf.count;
1275 out_putf:
1276 unlock_kernel();
1277 fput(file);
1278 out:
1279 return error;
1282 struct linux_dirent32 {
1283 u32 d_ino;
1284 u32 d_off;
1285 unsigned short d_reclen;
1286 char d_name[1];
1289 struct getdents_callback32 {
1290 struct linux_dirent32 * current_dir;
1291 struct linux_dirent32 * previous;
1292 int count;
1293 int error;
1296 static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
1298 struct linux_dirent32 * dirent;
1299 struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1300 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1302 buf->error = -EINVAL; /* only used if we fail.. */
1303 if (reclen > buf->count)
1304 return -EINVAL;
1305 dirent = buf->previous;
1306 if (dirent)
1307 put_user(offset, &dirent->d_off);
1308 dirent = buf->current_dir;
1309 buf->previous = dirent;
1310 put_user(ino, &dirent->d_ino);
1311 put_user(reclen, &dirent->d_reclen);
1312 copy_to_user(dirent->d_name, name, namlen);
1313 put_user(0, dirent->d_name + namlen);
1314 ((char *) dirent) += reclen;
1315 buf->current_dir = dirent;
1316 buf->count -= reclen;
1317 return 0;
1320 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1322 struct file * file;
1323 struct linux_dirent32 * lastdirent;
1324 struct getdents_callback32 buf;
1325 int error = -EBADF;
1327 file = fget(fd);
1328 if (!file)
1329 goto out;
1331 buf.current_dir = dirent;
1332 buf.previous = NULL;
1333 buf.count = count;
1334 buf.error = 0;
1336 lock_kernel();
1337 error = vfs_readdir(file, filldir, &buf);
1338 if (error < 0)
1339 goto out_putf;
1340 lastdirent = buf.previous;
1341 error = buf.error;
1342 if(lastdirent) {
1343 put_user(file->f_pos, &lastdirent->d_off);
1344 error = count - buf.count;
1346 out_putf:
1347 unlock_kernel();
1348 fput(file);
1349 out:
1350 return error;
1353 /* end of readdir & getdents */
1356 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1357 * 64-bit unsigned longs.
1360 static inline int
1361 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1363 if (ufdset) {
1364 unsigned long odd;
1366 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1367 return -EFAULT;
1369 odd = n & 1UL;
1370 n &= ~1UL;
1371 while (n) {
1372 unsigned long h, l;
1373 __get_user(l, ufdset);
1374 __get_user(h, ufdset+1);
1375 ufdset += 2;
1376 *fdset++ = h << 32 | l;
1377 n -= 2;
1379 if (odd)
1380 __get_user(*fdset, ufdset);
1381 } else {
1382 /* Tricky, must clear full unsigned long in the
1383 * kernel fdset at the end, this makes sure that
1384 * actually happens.
1386 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1388 return 0;
1391 static inline void
1392 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1394 unsigned long odd;
1396 if (!ufdset)
1397 return;
1399 odd = n & 1UL;
1400 n &= ~1UL;
1401 while (n) {
1402 unsigned long h, l;
1403 l = *fdset++;
1404 h = l >> 32;
1405 __put_user(l, ufdset);
1406 __put_user(h, ufdset+1);
1407 ufdset += 2;
1408 n -= 2;
1410 if (odd)
1411 __put_user(*fdset, ufdset);
1414 #define MAX_SELECT_SECONDS \
1415 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1417 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1419 fd_set_bits fds;
1420 struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1421 char *bits;
1422 unsigned long nn;
1423 long timeout;
1424 int ret, size;
1426 timeout = MAX_SCHEDULE_TIMEOUT;
1427 if (tvp) {
1428 time_t sec, usec;
1430 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1431 || (ret = __get_user(sec, &tvp->tv_sec))
1432 || (ret = __get_user(usec, &tvp->tv_usec)))
1433 goto out_nofds;
1435 ret = -EINVAL;
1436 if(sec < 0 || usec < 0)
1437 goto out_nofds;
1439 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1440 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1441 timeout += sec * (unsigned long) HZ;
1445 ret = -EINVAL;
1446 if (n < 0)
1447 goto out_nofds;
1448 if (n > current->files->max_fdset)
1449 n = current->files->max_fdset;
1452 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1453 * since we used fdset we need to allocate memory in units of
1454 * long-words.
1456 ret = -ENOMEM;
1457 size = FDS_BYTES(n);
1458 bits = kmalloc(6 * size, GFP_KERNEL);
1459 if (!bits)
1460 goto out_nofds;
1461 fds.in = (unsigned long *) bits;
1462 fds.out = (unsigned long *) (bits + size);
1463 fds.ex = (unsigned long *) (bits + 2*size);
1464 fds.res_in = (unsigned long *) (bits + 3*size);
1465 fds.res_out = (unsigned long *) (bits + 4*size);
1466 fds.res_ex = (unsigned long *) (bits + 5*size);
1468 nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1469 if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1470 (ret = get_fd_set32(nn, fds.out, outp)) ||
1471 (ret = get_fd_set32(nn, fds.ex, exp)))
1472 goto out;
1473 zero_fd_set(n, fds.res_in);
1474 zero_fd_set(n, fds.res_out);
1475 zero_fd_set(n, fds.res_ex);
1477 ret = do_select(n, &fds, &timeout);
1479 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1480 time_t sec = 0, usec = 0;
1481 if (timeout) {
1482 sec = timeout / HZ;
1483 usec = timeout % HZ;
1484 usec *= (1000000/HZ);
1486 put_user(sec, &tvp->tv_sec);
1487 put_user(usec, &tvp->tv_usec);
1490 if (ret < 0)
1491 goto out;
1492 if (!ret) {
1493 ret = -ERESTARTNOHAND;
1494 if (signal_pending(current))
1495 goto out;
1496 ret = 0;
1499 set_fd_set32(nn, inp, fds.res_in);
1500 set_fd_set32(nn, outp, fds.res_out);
1501 set_fd_set32(nn, exp, fds.res_ex);
1503 out:
1504 kfree(bits);
1505 out_nofds:
1506 return ret;
1509 static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1511 unsigned long ino, blksize, blocks;
1512 kdev_t dev, rdev;
1513 umode_t mode;
1514 nlink_t nlink;
1515 uid_t uid;
1516 gid_t gid;
1517 off_t size;
1518 time_t atime, mtime, ctime;
1519 int err;
1521 /* Stream the loads of inode data into the load buffer,
1522 * then we push it all into the store buffer below. This
1523 * should give optimal cache performance.
1525 ino = inode->i_ino;
1526 dev = inode->i_dev;
1527 mode = inode->i_mode;
1528 nlink = inode->i_nlink;
1529 uid = inode->i_uid;
1530 gid = inode->i_gid;
1531 rdev = inode->i_rdev;
1532 size = inode->i_size;
1533 atime = inode->i_atime;
1534 mtime = inode->i_mtime;
1535 ctime = inode->i_ctime;
1536 blksize = inode->i_blksize;
1537 blocks = inode->i_blocks;
1539 err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1540 err |= put_user(ino, &statbuf->st_ino);
1541 err |= put_user(mode, &statbuf->st_mode);
1542 err |= put_user(nlink, &statbuf->st_nlink);
1543 err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1544 err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1545 err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1546 err |= put_user(size, &statbuf->st_size);
1547 err |= put_user(atime, &statbuf->st_atime);
1548 err |= put_user(0, &statbuf->__unused1);
1549 err |= put_user(mtime, &statbuf->st_mtime);
1550 err |= put_user(0, &statbuf->__unused2);
1551 err |= put_user(ctime, &statbuf->st_ctime);
1552 err |= put_user(0, &statbuf->__unused3);
1553 if (blksize) {
1554 err |= put_user(blksize, &statbuf->st_blksize);
1555 err |= put_user(blocks, &statbuf->st_blocks);
1556 } else {
1557 unsigned int tmp_blocks;
1559 #define D_B 7
1560 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
1561 tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1562 if (tmp_blocks > D_B) {
1563 unsigned int indirect;
1565 indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1566 tmp_blocks += indirect;
1567 if (indirect > 1) {
1568 indirect = (indirect - 1 + I_B - 1) / I_B;
1569 tmp_blocks += indirect;
1570 if (indirect > 1)
1571 tmp_blocks++;
1574 err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1575 err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1576 #undef D_B
1577 #undef I_B
1579 err |= put_user(0, &statbuf->__unused4[0]);
1580 err |= put_user(0, &statbuf->__unused4[1]);
1582 return err;
1585 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1587 struct nameidata nd;
1588 int error;
1590 lock_kernel();
1591 error = user_path_walk(filename, &nd);
1592 if (!error) {
1593 struct inode *inode = nd.dentry->d_inode;
1595 if (inode->i_op &&
1596 inode->i_op->revalidate)
1597 error = inode->i_op->revalidate(nd.dentry);
1598 else
1599 error = 0;
1600 if (!error)
1601 error = cp_new_stat32(inode, statbuf);
1603 path_release(&nd);
1605 unlock_kernel();
1606 return error;
1609 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1611 struct nameidata nd;
1612 int error;
1614 lock_kernel();
1615 error = user_path_walk_link(filename, &nd);
1616 if (!error) {
1617 struct inode *inode = nd.dentry->d_inode;
1619 if (inode->i_op &&
1620 inode->i_op->revalidate)
1621 error = inode->i_op->revalidate(nd.dentry);
1622 else
1623 error = 0;
1624 if (!error)
1625 error = cp_new_stat32(inode, statbuf);
1627 path_release(&nd);
1629 unlock_kernel();
1630 return error;
1633 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1635 struct file *f;
1636 int err = -EBADF;
1638 lock_kernel();
1639 f = fget(fd);
1640 if (f) {
1641 struct dentry *dentry = f->f_dentry;
1642 struct inode *inode = dentry->d_inode;
1644 if (inode->i_op &&
1645 inode->i_op->revalidate)
1646 err = inode->i_op->revalidate(dentry);
1647 else
1648 err = 0;
1649 if (!err)
1650 err = cp_new_stat32(inode, statbuf);
1652 fput(f);
1654 unlock_kernel();
1655 return err;
1658 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1660 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1662 return sys_sysfs(option, arg1, arg2);
1665 struct ncp_mount_data32 {
1666 int version;
1667 unsigned int ncp_fd;
1668 __kernel_uid_t32 mounted_uid;
1669 __kernel_pid_t32 wdog_pid;
1670 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1671 unsigned int time_out;
1672 unsigned int retry_count;
1673 unsigned int flags;
1674 __kernel_uid_t32 uid;
1675 __kernel_gid_t32 gid;
1676 __kernel_mode_t32 file_mode;
1677 __kernel_mode_t32 dir_mode;
1680 static void *do_ncp_super_data_conv(void *raw_data)
1682 struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
1683 struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
1685 n->dir_mode = n32->dir_mode;
1686 n->file_mode = n32->file_mode;
1687 n->gid = low2highgid(n32->gid);
1688 n->uid = low2highuid(n32->uid);
1689 memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
1690 n->wdog_pid = n32->wdog_pid;
1691 n->mounted_uid = low2highuid(n32->mounted_uid);
1692 return raw_data;
1695 struct smb_mount_data32 {
1696 int version;
1697 __kernel_uid_t32 mounted_uid;
1698 __kernel_uid_t32 uid;
1699 __kernel_gid_t32 gid;
1700 __kernel_mode_t32 file_mode;
1701 __kernel_mode_t32 dir_mode;
1704 static void *do_smb_super_data_conv(void *raw_data)
1706 struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
1707 struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1709 s->version = s32->version;
1710 s->mounted_uid = low2highuid(s32->mounted_uid);
1711 s->uid = low2highuid(s32->uid);
1712 s->gid = low2highgid(s32->gid);
1713 s->file_mode = s32->file_mode;
1714 s->dir_mode = s32->dir_mode;
1715 return raw_data;
1718 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1720 int i;
1721 unsigned long page;
1722 struct vm_area_struct *vma;
1724 *kernel = 0;
1725 if(!user)
1726 return 0;
1727 vma = find_vma(current->mm, (unsigned long)user);
1728 if(!vma || (unsigned long)user < vma->vm_start)
1729 return -EFAULT;
1730 if(!(vma->vm_flags & VM_READ))
1731 return -EFAULT;
1732 i = vma->vm_end - (unsigned long) user;
1733 if(PAGE_SIZE <= (unsigned long) i)
1734 i = PAGE_SIZE - 1;
1735 if(!(page = __get_free_page(GFP_KERNEL)))
1736 return -ENOMEM;
1737 if(copy_from_user((void *) page, user, i)) {
1738 free_page(page);
1739 return -EFAULT;
1741 *kernel = page;
1742 return 0;
1745 #define SMBFS_NAME "smbfs"
1746 #define NCPFS_NAME "ncpfs"
1748 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1750 unsigned long type_page = 0;
1751 unsigned long data_page = 0;
1752 unsigned long dev_page = 0;
1753 unsigned long dir_page = 0;
1754 int err, is_smb, is_ncp;
1756 is_smb = is_ncp = 0;
1758 lock_kernel();
1759 err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1760 if (err)
1761 goto out;
1763 if (!type_page) {
1764 err = -EINVAL;
1765 goto out;
1768 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1769 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1771 err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1772 if (err)
1773 goto type_out;
1775 err = copy_mount_stuff_to_kernel(dev_name, &dev_page);
1776 if (err)
1777 goto data_out;
1779 err = copy_mount_stuff_to_kernel(dir_name, &dir_page);
1780 if (err)
1781 goto dev_out;
1783 if (!is_smb && !is_ncp) {
1784 err = do_mount((char*)dev_page, (char*)dir_page,
1785 (char*)type_page, new_flags, (char*)data_page);
1786 } else {
1787 if (is_ncp)
1788 do_ncp_super_data_conv((void *)data_page);
1789 else
1790 do_smb_super_data_conv((void *)data_page);
1792 err = do_mount((char*)dev_page, (char*)dir_page,
1793 (char*)type_page, new_flags, (char*)data_page);
1795 free_page(dir_page);
1797 dev_out:
1798 free_page(dev_page);
1800 data_out:
1801 free_page(data_page);
1803 type_out:
1804 free_page(type_page);
1806 out:
1807 unlock_kernel();
1808 return err;
1811 struct rusage32 {
1812 struct timeval32 ru_utime;
1813 struct timeval32 ru_stime;
1814 s32 ru_maxrss;
1815 s32 ru_ixrss;
1816 s32 ru_idrss;
1817 s32 ru_isrss;
1818 s32 ru_minflt;
1819 s32 ru_majflt;
1820 s32 ru_nswap;
1821 s32 ru_inblock;
1822 s32 ru_oublock;
1823 s32 ru_msgsnd;
1824 s32 ru_msgrcv;
1825 s32 ru_nsignals;
1826 s32 ru_nvcsw;
1827 s32 ru_nivcsw;
1830 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1832 int err;
1834 err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1835 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1836 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1837 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1838 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1839 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1840 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1841 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1842 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1843 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1844 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1845 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1846 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1847 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1848 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1849 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1850 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1851 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1852 return err;
1855 extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
1856 int options, struct rusage * ru);
1858 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1860 if (!ru)
1861 return sys_wait4(pid, stat_addr, options, NULL);
1862 else {
1863 struct rusage r;
1864 int ret;
1865 unsigned int status;
1866 mm_segment_t old_fs = get_fs();
1868 set_fs (KERNEL_DS);
1869 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1870 set_fs (old_fs);
1871 if (put_rusage (ru, &r)) return -EFAULT;
1872 if (stat_addr && put_user (status, stat_addr))
1873 return -EFAULT;
1874 return ret;
1878 struct sysinfo32 {
1879 s32 uptime;
1880 u32 loads[3];
1881 u32 totalram;
1882 u32 freeram;
1883 u32 sharedram;
1884 u32 bufferram;
1885 u32 totalswap;
1886 u32 freeswap;
1887 unsigned short procs;
1888 char _f[22];
1891 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1893 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1895 struct sysinfo s;
1896 int ret, err;
1897 mm_segment_t old_fs = get_fs ();
1899 set_fs (KERNEL_DS);
1900 ret = sys_sysinfo(&s);
1901 set_fs (old_fs);
1902 err = put_user (s.uptime, &info->uptime);
1903 err |= __put_user (s.loads[0], &info->loads[0]);
1904 err |= __put_user (s.loads[1], &info->loads[1]);
1905 err |= __put_user (s.loads[2], &info->loads[2]);
1906 err |= __put_user (s.totalram, &info->totalram);
1907 err |= __put_user (s.freeram, &info->freeram);
1908 err |= __put_user (s.sharedram, &info->sharedram);
1909 err |= __put_user (s.bufferram, &info->bufferram);
1910 err |= __put_user (s.totalswap, &info->totalswap);
1911 err |= __put_user (s.freeswap, &info->freeswap);
1912 err |= __put_user (s.procs, &info->procs);
1913 if (err)
1914 return -EFAULT;
1915 return ret;
1918 struct timespec32 {
1919 s32 tv_sec;
1920 s32 tv_nsec;
1923 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1925 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1927 struct timespec t;
1928 int ret;
1929 mm_segment_t old_fs = get_fs ();
1931 set_fs (KERNEL_DS);
1932 ret = sys_sched_rr_get_interval(pid, &t);
1933 set_fs (old_fs);
1934 if (put_user (t.tv_sec, &interval->tv_sec) ||
1935 __put_user (t.tv_nsec, &interval->tv_nsec))
1936 return -EFAULT;
1937 return ret;
1940 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1942 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1944 struct timespec t;
1945 int ret;
1946 mm_segment_t old_fs = get_fs ();
1948 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1949 __get_user (t.tv_nsec, &rqtp->tv_nsec))
1950 return -EFAULT;
1951 set_fs (KERNEL_DS);
1952 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1953 set_fs (old_fs);
1954 if (rmtp && ret == -EINTR) {
1955 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1956 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1957 return -EFAULT;
1959 return ret;
1962 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1964 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1966 old_sigset_t s;
1967 int ret;
1968 mm_segment_t old_fs = get_fs();
1970 if (set && get_user (s, set)) return -EFAULT;
1971 set_fs (KERNEL_DS);
1972 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1973 set_fs (old_fs);
1974 if (ret) return ret;
1975 if (oset && put_user (s, oset)) return -EFAULT;
1976 return 0;
1979 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
1981 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
1983 sigset_t s;
1984 sigset_t32 s32;
1985 int ret;
1986 mm_segment_t old_fs = get_fs();
1988 if (set) {
1989 if (copy_from_user (&s32, set, sizeof(sigset_t32)))
1990 return -EFAULT;
1991 switch (_NSIG_WORDS) {
1992 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
1993 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
1994 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
1995 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
1998 set_fs (KERNEL_DS);
1999 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
2000 set_fs (old_fs);
2001 if (ret) return ret;
2002 if (oset) {
2003 switch (_NSIG_WORDS) {
2004 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2005 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2006 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2007 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2009 if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
2010 return -EFAULT;
2012 return 0;
2015 extern asmlinkage int sys_sigpending(old_sigset_t *set);
2017 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
2019 old_sigset_t s;
2020 int ret;
2021 mm_segment_t old_fs = get_fs();
2023 set_fs (KERNEL_DS);
2024 ret = sys_sigpending(&s);
2025 set_fs (old_fs);
2026 if (put_user (s, set)) return -EFAULT;
2027 return ret;
2030 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
2032 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
2034 sigset_t s;
2035 sigset_t32 s32;
2036 int ret;
2037 mm_segment_t old_fs = get_fs();
2039 set_fs (KERNEL_DS);
2040 ret = sys_rt_sigpending(&s, sigsetsize);
2041 set_fs (old_fs);
2042 if (!ret) {
2043 switch (_NSIG_WORDS) {
2044 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2045 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2046 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2047 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2049 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
2050 return -EFAULT;
2052 return ret;
2055 asmlinkage int
2056 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
2057 struct timespec32 *uts, __kernel_size_t32 sigsetsize)
2059 int ret, sig;
2060 sigset_t these;
2061 sigset_t32 these32;
2062 struct timespec ts;
2063 siginfo_t info;
2064 long timeout = 0;
2066 /* XXX: Don't preclude handling different sized sigset_t's. */
2067 if (sigsetsize != sizeof(sigset_t))
2068 return -EINVAL;
2070 if (copy_from_user (&these32, uthese, sizeof(sigset_t32)))
2071 return -EFAULT;
2073 switch (_NSIG_WORDS) {
2074 case 4: these.sig[3] = these32.sig[6] | (((long)these32.sig[7]) << 32);
2075 case 3: these.sig[2] = these32.sig[4] | (((long)these32.sig[5]) << 32);
2076 case 2: these.sig[1] = these32.sig[2] | (((long)these32.sig[3]) << 32);
2077 case 1: these.sig[0] = these32.sig[0] | (((long)these32.sig[1]) << 32);
2081 * Invert the set of allowed signals to get those we
2082 * want to block.
2084 sigdelsetmask(&these, sigmask(SIGKILL)|sigmask(SIGSTOP));
2085 signotset(&these);
2087 if (uts) {
2088 if (get_user (ts.tv_sec, &uts->tv_sec) ||
2089 get_user (ts.tv_nsec, &uts->tv_nsec))
2090 return -EINVAL;
2091 if (ts.tv_nsec >= 1000000000L || ts.tv_nsec < 0
2092 || ts.tv_sec < 0)
2093 return -EINVAL;
2096 spin_lock_irq(&current->sigmask_lock);
2097 sig = dequeue_signal(&these, &info);
2098 if (!sig) {
2099 /* None ready -- temporarily unblock those we're interested
2100 in so that we'll be awakened when they arrive. */
2101 sigset_t oldblocked = current->blocked;
2102 sigandsets(&current->blocked, &current->blocked, &these);
2103 recalc_sigpending(current);
2104 spin_unlock_irq(&current->sigmask_lock);
2106 timeout = MAX_SCHEDULE_TIMEOUT;
2107 if (uts)
2108 timeout = (timespec_to_jiffies(&ts)
2109 + (ts.tv_sec || ts.tv_nsec));
2111 current->state = TASK_INTERRUPTIBLE;
2112 timeout = schedule_timeout(timeout);
2114 spin_lock_irq(&current->sigmask_lock);
2115 sig = dequeue_signal(&these, &info);
2116 current->blocked = oldblocked;
2117 recalc_sigpending(current);
2119 spin_unlock_irq(&current->sigmask_lock);
2121 if (sig) {
2122 ret = sig;
2123 if (uinfo) {
2124 if (copy_siginfo_to_user32(uinfo, &info))
2125 ret = -EFAULT;
2127 } else {
2128 ret = -EAGAIN;
2129 if (timeout)
2130 ret = -EINTR;
2133 return ret;
2136 extern asmlinkage int
2137 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2139 asmlinkage int
2140 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2142 siginfo_t info;
2143 int ret;
2144 mm_segment_t old_fs = get_fs();
2146 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2147 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2148 return -EFAULT;
2149 set_fs (KERNEL_DS);
2150 ret = sys_rt_sigqueueinfo(pid, sig, &info);
2151 set_fs (old_fs);
2152 return ret;
2155 struct tms32 {
2156 __kernel_clock_t32 tms_utime;
2157 __kernel_clock_t32 tms_stime;
2158 __kernel_clock_t32 tms_cutime;
2159 __kernel_clock_t32 tms_cstime;
2162 extern asmlinkage long sys_times(struct tms * tbuf);
2164 asmlinkage long sys32_times(struct tms32 *tbuf)
2166 struct tms t;
2167 long ret;
2168 mm_segment_t old_fs = get_fs ();
2169 int err;
2171 set_fs (KERNEL_DS);
2172 ret = sys_times(tbuf ? &t : NULL);
2173 set_fs (old_fs);
2174 if (tbuf) {
2175 err = put_user (t.tms_utime, &tbuf->tms_utime);
2176 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2177 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2178 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2179 if (err)
2180 ret = -EFAULT;
2182 return ret;
2185 #define RLIM_INFINITY32 0x7fffffff
2186 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2188 struct rlimit32 {
2189 u32 rlim_cur;
2190 u32 rlim_max;
2193 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2195 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2197 struct rlimit r;
2198 int ret;
2199 mm_segment_t old_fs = get_fs ();
2201 set_fs (KERNEL_DS);
2202 ret = sys_getrlimit(resource, &r);
2203 set_fs (old_fs);
2204 if (!ret) {
2205 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2206 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2208 return ret;
2211 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2213 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2215 struct rlimit r;
2216 int ret;
2217 mm_segment_t old_fs = get_fs ();
2219 if (resource >= RLIM_NLIMITS) return -EINVAL;
2220 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2221 __get_user (r.rlim_max, &rlim->rlim_max))
2222 return -EFAULT;
2223 if (r.rlim_cur == RLIM_INFINITY32)
2224 r.rlim_cur = RLIM_INFINITY;
2225 if (r.rlim_max == RLIM_INFINITY32)
2226 r.rlim_max = RLIM_INFINITY;
2227 set_fs (KERNEL_DS);
2228 ret = sys_setrlimit(resource, &r);
2229 set_fs (old_fs);
2230 return ret;
2233 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2235 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2237 struct rusage r;
2238 int ret;
2239 mm_segment_t old_fs = get_fs();
2241 set_fs (KERNEL_DS);
2242 ret = sys_getrusage(who, &r);
2243 set_fs (old_fs);
2244 if (put_rusage (ru, &r)) return -EFAULT;
2245 return ret;
2248 /* XXX This really belongs in some header file... -DaveM */
2249 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2250 16 for IP, 16 for IPX,
2251 24 for IPv6,
2252 about 80 for AX.25 */
2254 /* XXX These as well... */
2255 extern __inline__ struct socket *socki_lookup(struct inode *inode)
2257 return &inode->u.socket_i;
2260 extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
2262 struct file *file;
2263 struct inode *inode;
2265 if (!(file = fget(fd)))
2267 *err = -EBADF;
2268 return NULL;
2271 inode = file->f_dentry->d_inode;
2272 if (!inode || !inode->i_sock || !socki_lookup(inode))
2274 *err = -ENOTSOCK;
2275 fput(file);
2276 return NULL;
2279 return socki_lookup(inode);
2282 extern __inline__ void sockfd_put(struct socket *sock)
2284 fput(sock->file);
2287 struct msghdr32 {
2288 u32 msg_name;
2289 int msg_namelen;
2290 u32 msg_iov;
2291 __kernel_size_t32 msg_iovlen;
2292 u32 msg_control;
2293 __kernel_size_t32 msg_controllen;
2294 unsigned msg_flags;
2297 struct cmsghdr32 {
2298 __kernel_size_t32 cmsg_len;
2299 int cmsg_level;
2300 int cmsg_type;
2303 /* Bleech... */
2304 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2305 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2307 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2309 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2310 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2311 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2313 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2314 (struct cmsghdr32 *)(ctl) : \
2315 (struct cmsghdr32 *)NULL)
2316 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2318 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2319 struct cmsghdr32 *__cmsg, int __cmsg_len)
2321 struct cmsghdr32 * __ptr;
2323 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2324 CMSG32_ALIGN(__cmsg_len));
2325 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2326 return NULL;
2328 return __ptr;
2331 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2332 struct cmsghdr32 *__cmsg,
2333 int __cmsg_len)
2335 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2336 __cmsg, __cmsg_len);
2339 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2340 struct iovec32 *uiov32,
2341 int niov)
2343 int tot_len = 0;
2345 while(niov > 0) {
2346 u32 len, buf;
2348 if(get_user(len, &uiov32->iov_len) ||
2349 get_user(buf, &uiov32->iov_base)) {
2350 tot_len = -EFAULT;
2351 break;
2353 tot_len += len;
2354 kiov->iov_base = (void *)A(buf);
2355 kiov->iov_len = (__kernel_size_t) len;
2356 uiov32++;
2357 kiov++;
2358 niov--;
2360 return tot_len;
2363 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2364 struct msghdr32 *umsg)
2366 u32 tmp1, tmp2, tmp3;
2367 int err;
2369 err = get_user(tmp1, &umsg->msg_name);
2370 err |= __get_user(tmp2, &umsg->msg_iov);
2371 err |= __get_user(tmp3, &umsg->msg_control);
2372 if (err)
2373 return -EFAULT;
2375 kmsg->msg_name = (void *)A(tmp1);
2376 kmsg->msg_iov = (struct iovec *)A(tmp2);
2377 kmsg->msg_control = (void *)A(tmp3);
2379 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2380 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2381 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2382 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2384 return err;
2387 /* I've named the args so it is easy to tell whose space the pointers are in. */
2388 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2389 char *kern_address, int mode)
2391 int tot_len;
2393 if(kern_msg->msg_namelen) {
2394 if(mode==VERIFY_READ) {
2395 int err = move_addr_to_kernel(kern_msg->msg_name,
2396 kern_msg->msg_namelen,
2397 kern_address);
2398 if(err < 0)
2399 return err;
2401 kern_msg->msg_name = kern_address;
2402 } else
2403 kern_msg->msg_name = NULL;
2405 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2406 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2407 GFP_KERNEL);
2408 if(!kern_iov)
2409 return -ENOMEM;
2412 tot_len = iov_from_user32_to_kern(kern_iov,
2413 (struct iovec32 *)kern_msg->msg_iov,
2414 kern_msg->msg_iovlen);
2415 if(tot_len >= 0)
2416 kern_msg->msg_iov = kern_iov;
2417 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2418 kfree(kern_iov);
2420 return tot_len;
2423 /* There is a lot of hair here because the alignment rules (and
2424 * thus placement) of cmsg headers and length are different for
2425 * 32-bit apps. -DaveM
2427 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2428 unsigned char *stackbuf, int stackbuf_size)
2430 struct cmsghdr32 *ucmsg;
2431 struct cmsghdr *kcmsg, *kcmsg_base;
2432 __kernel_size_t32 ucmlen;
2433 __kernel_size_t kcmlen, tmp;
2435 kcmlen = 0;
2436 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2437 ucmsg = CMSG32_FIRSTHDR(kmsg);
2438 while(ucmsg != NULL) {
2439 if(get_user(ucmlen, &ucmsg->cmsg_len))
2440 return -EFAULT;
2442 /* Catch bogons. */
2443 if(CMSG32_ALIGN(ucmlen) <
2444 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2445 return -EINVAL;
2446 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2447 + ucmlen) > kmsg->msg_controllen)
2448 return -EINVAL;
2450 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2451 CMSG_ALIGN(sizeof(struct cmsghdr)));
2452 kcmlen += tmp;
2453 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2455 if(kcmlen == 0)
2456 return -EINVAL;
2458 /* The kcmlen holds the 64-bit version of the control length.
2459 * It may not be modified as we do not stick it into the kmsg
2460 * until we have successfully copied over all of the data
2461 * from the user.
2463 if(kcmlen > stackbuf_size)
2464 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2465 if(kcmsg == NULL)
2466 return -ENOBUFS;
2468 /* Now copy them over neatly. */
2469 memset(kcmsg, 0, kcmlen);
2470 ucmsg = CMSG32_FIRSTHDR(kmsg);
2471 while(ucmsg != NULL) {
2472 __get_user(ucmlen, &ucmsg->cmsg_len);
2473 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2474 CMSG_ALIGN(sizeof(struct cmsghdr)));
2475 kcmsg->cmsg_len = tmp;
2476 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2477 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2479 /* Copy over the data. */
2480 if(copy_from_user(CMSG_DATA(kcmsg),
2481 CMSG32_DATA(ucmsg),
2482 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2483 goto out_free_efault;
2485 /* Advance. */
2486 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2487 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2490 /* Ok, looks like we made it. Hook it up and return success. */
2491 kmsg->msg_control = kcmsg_base;
2492 kmsg->msg_controllen = kcmlen;
2493 return 0;
2495 out_free_efault:
2496 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2497 kfree(kcmsg_base);
2498 return -EFAULT;
2501 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2502 int len, void *data)
2504 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2505 struct cmsghdr32 cmhdr;
2506 int cmlen = CMSG32_LEN(len);
2508 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2509 kmsg->msg_flags |= MSG_CTRUNC;
2510 return;
2513 if(kmsg->msg_controllen < cmlen) {
2514 kmsg->msg_flags |= MSG_CTRUNC;
2515 cmlen = kmsg->msg_controllen;
2517 cmhdr.cmsg_level = level;
2518 cmhdr.cmsg_type = type;
2519 cmhdr.cmsg_len = cmlen;
2521 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2522 return;
2523 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2524 return;
2525 cmlen = CMSG32_SPACE(len);
2526 kmsg->msg_control += cmlen;
2527 kmsg->msg_controllen -= cmlen;
2530 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2532 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2533 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2534 int fdnum = scm->fp->count;
2535 struct file **fp = scm->fp->fp;
2536 int *cmfptr;
2537 int err = 0, i;
2539 if (fdnum < fdmax)
2540 fdmax = fdnum;
2542 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2543 int new_fd;
2544 err = get_unused_fd();
2545 if (err < 0)
2546 break;
2547 new_fd = err;
2548 err = put_user(new_fd, cmfptr);
2549 if (err) {
2550 put_unused_fd(new_fd);
2551 break;
2553 /* Bump the usage count and install the file. */
2554 get_file(fp[i]);
2555 fd_install(new_fd, fp[i]);
2558 if (i > 0) {
2559 int cmlen = CMSG32_LEN(i * sizeof(int));
2560 if (!err)
2561 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2562 if (!err)
2563 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2564 if (!err)
2565 err = put_user(cmlen, &cm->cmsg_len);
2566 if (!err) {
2567 cmlen = CMSG32_SPACE(i * sizeof(int));
2568 kmsg->msg_control += cmlen;
2569 kmsg->msg_controllen -= cmlen;
2572 if (i < fdnum)
2573 kmsg->msg_flags |= MSG_CTRUNC;
2576 * All of the files that fit in the message have had their
2577 * usage counts incremented, so we just free the list.
2579 __scm_destroy(scm);
2582 /* In these cases we (currently) can just copy to data over verbatim
2583 * because all CMSGs created by the kernel have well defined types which
2584 * have the same layout in both the 32-bit and 64-bit API. One must add
2585 * some special cased conversions here if we start sending control messages
2586 * with incompatible types.
2588 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2589 * we do our work. The remaining cases are:
2591 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2592 * IP_TTL int 32-bit clean
2593 * IP_TOS __u8 32-bit clean
2594 * IP_RECVOPTS variable length 32-bit clean
2595 * IP_RETOPTS variable length 32-bit clean
2596 * (these last two are clean because the types are defined
2597 * by the IPv4 protocol)
2598 * IP_RECVERR struct sock_extended_err +
2599 * struct sockaddr_in 32-bit clean
2600 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2601 * struct sockaddr_in6 32-bit clean
2602 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2603 * IPV6_HOPLIMIT int 32-bit clean
2604 * IPV6_FLOWINFO u32 32-bit clean
2605 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2606 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2607 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2608 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2610 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2612 unsigned char *workbuf, *wp;
2613 unsigned long bufsz, space_avail;
2614 struct cmsghdr *ucmsg;
2616 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2617 space_avail = kmsg->msg_controllen + bufsz;
2618 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2619 if(workbuf == NULL)
2620 goto fail;
2622 /* To make this more sane we assume the kernel sends back properly
2623 * formatted control messages. Because of how the kernel will truncate
2624 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2626 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2627 while(((unsigned long)ucmsg) <=
2628 (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
2629 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2630 int clen64, clen32;
2632 /* UCMSG is the 64-bit format CMSG entry in user-space.
2633 * KCMSG32 is within the kernel space temporary buffer
2634 * we use to convert into a 32-bit style CMSG.
2636 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2637 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2638 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2640 clen64 = kcmsg32->cmsg_len;
2641 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2642 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2643 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2644 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2645 kcmsg32->cmsg_len = clen32;
2647 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2648 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2651 /* Copy back fixed up data, and adjust pointers. */
2652 bufsz = (wp - workbuf);
2653 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2655 kmsg->msg_control = (struct cmsghdr *)
2656 (((char *)orig_cmsg_uptr) + bufsz);
2657 kmsg->msg_controllen = space_avail - bufsz;
2659 kfree(workbuf);
2660 return;
2662 fail:
2663 /* If we leave the 64-bit format CMSG chunks in there,
2664 * the application could get confused and crash. So to
2665 * ensure greater recovery, we report no CMSGs.
2667 kmsg->msg_controllen += bufsz;
2668 kmsg->msg_control = (void *) orig_cmsg_uptr;
2671 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2673 struct socket *sock;
2674 char address[MAX_SOCK_ADDR];
2675 struct iovec iov[UIO_FASTIOV];
2676 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2677 unsigned char *ctl_buf = ctl;
2678 struct msghdr kern_msg;
2679 int err, total_len;
2681 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2682 return -EFAULT;
2683 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2684 return -EINVAL;
2685 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2686 if (err < 0)
2687 goto out;
2688 total_len = err;
2690 if(kern_msg.msg_controllen) {
2691 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2692 if(err)
2693 goto out_freeiov;
2694 ctl_buf = kern_msg.msg_control;
2696 kern_msg.msg_flags = user_flags;
2698 lock_kernel();
2699 sock = sockfd_lookup(fd, &err);
2700 if (sock != NULL) {
2701 if (sock->file->f_flags & O_NONBLOCK)
2702 kern_msg.msg_flags |= MSG_DONTWAIT;
2703 err = sock_sendmsg(sock, &kern_msg, total_len);
2704 sockfd_put(sock);
2706 unlock_kernel();
2708 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2709 if(ctl_buf != ctl)
2710 kfree(ctl_buf);
2711 out_freeiov:
2712 if(kern_msg.msg_iov != iov)
2713 kfree(kern_msg.msg_iov);
2714 out:
2715 return err;
2718 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2720 struct iovec iovstack[UIO_FASTIOV];
2721 struct msghdr kern_msg;
2722 char addr[MAX_SOCK_ADDR];
2723 struct socket *sock;
2724 struct iovec *iov = iovstack;
2725 struct sockaddr *uaddr;
2726 int *uaddr_len;
2727 unsigned long cmsg_ptr;
2728 int err, total_len, len = 0;
2730 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2731 return -EFAULT;
2732 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2733 return -EINVAL;
2735 uaddr = kern_msg.msg_name;
2736 uaddr_len = &user_msg->msg_namelen;
2737 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2738 if (err < 0)
2739 goto out;
2740 total_len = err;
2742 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2743 kern_msg.msg_flags = 0;
2745 lock_kernel();
2746 sock = sockfd_lookup(fd, &err);
2747 if (sock != NULL) {
2748 struct scm_cookie scm;
2750 if (sock->file->f_flags & O_NONBLOCK)
2751 user_flags |= MSG_DONTWAIT;
2752 memset(&scm, 0, sizeof(scm));
2753 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2754 user_flags, &scm);
2755 if(err >= 0) {
2756 len = err;
2757 if(!kern_msg.msg_control) {
2758 if(sock->passcred || scm.fp)
2759 kern_msg.msg_flags |= MSG_CTRUNC;
2760 if(scm.fp)
2761 __scm_destroy(&scm);
2762 } else {
2763 /* If recvmsg processing itself placed some
2764 * control messages into user space, it's is
2765 * using 64-bit CMSG processing, so we need
2766 * to fix it up before we tack on more stuff.
2768 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2769 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2771 /* Wheee... */
2772 if(sock->passcred)
2773 put_cmsg32(&kern_msg,
2774 SOL_SOCKET, SCM_CREDENTIALS,
2775 sizeof(scm.creds), &scm.creds);
2776 if(scm.fp != NULL)
2777 scm_detach_fds32(&kern_msg, &scm);
2780 sockfd_put(sock);
2782 unlock_kernel();
2784 if(uaddr != NULL && err >= 0)
2785 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2786 if(cmsg_ptr != 0 && err >= 0) {
2787 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2788 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2789 err |= __put_user(uclen, &user_msg->msg_controllen);
2791 if(err >= 0)
2792 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2793 if(kern_msg.msg_iov != iov)
2794 kfree(kern_msg.msg_iov);
2795 out:
2796 if(err < 0)
2797 return err;
2798 return len;
2801 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2802 char *optval, int optlen);
2804 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2805 char *optval, int optlen)
2807 if (optname == SO_ATTACH_FILTER) {
2808 struct sock_fprog32 {
2809 __u16 len;
2810 __u32 filter;
2811 } *fprog32 = (struct sock_fprog32 *)optval;
2812 struct sock_fprog kfprog;
2813 struct sock_filter *kfilter;
2814 unsigned int fsize;
2815 mm_segment_t old_fs;
2816 __u32 uptr;
2817 int ret;
2819 if (get_user(kfprog.len, &fprog32->len) ||
2820 __get_user(uptr, &fprog32->filter))
2821 return -EFAULT;
2822 kfprog.filter = (struct sock_filter *)A(uptr);
2823 fsize = kfprog.len * sizeof(struct sock_filter);
2824 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2825 if (kfilter == NULL)
2826 return -ENOMEM;
2827 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2828 kfree(kfilter);
2829 return -EFAULT;
2831 kfprog.filter = kfilter;
2832 old_fs = get_fs();
2833 set_fs(KERNEL_DS);
2834 ret = sys_setsockopt(fd, level, optname,
2835 (char *)&kfprog, sizeof(kfprog));
2836 set_fs(old_fs);
2837 kfree(kfilter);
2838 return ret;
2840 return sys_setsockopt(fd, level, optname, optval, optlen);
2843 extern void check_pending(int signum);
2845 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2847 struct k_sigaction new_ka, old_ka;
2848 int ret;
2850 if(sig < 0) {
2851 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2852 sig = -sig;
2855 if (act) {
2856 old_sigset_t32 mask;
2858 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2859 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2860 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2861 ret |= __get_user(mask, &act->sa_mask);
2862 if (ret)
2863 return ret;
2864 new_ka.ka_restorer = NULL;
2865 siginitset(&new_ka.sa.sa_mask, mask);
2868 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2870 if (!ret && oact) {
2871 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2872 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2873 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2874 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2877 return ret;
2880 asmlinkage int
2881 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2882 void *restorer, __kernel_size_t32 sigsetsize)
2884 struct k_sigaction new_ka, old_ka;
2885 int ret;
2886 sigset_t32 set32;
2888 /* XXX: Don't preclude handling different sized sigset_t's. */
2889 if (sigsetsize != sizeof(sigset_t32))
2890 return -EINVAL;
2892 /* All tasks which use RT signals (effectively) use
2893 * new style signals.
2895 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2897 if (act) {
2898 new_ka.ka_restorer = restorer;
2899 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2900 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2901 switch (_NSIG_WORDS) {
2902 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2903 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2904 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2905 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2907 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2908 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2909 if (ret)
2910 return -EFAULT;
2913 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2915 if (!ret && oact) {
2916 switch (_NSIG_WORDS) {
2917 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
2918 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
2919 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
2920 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
2922 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2923 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
2924 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2925 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2928 return ret;
2933 * count32() counts the number of arguments/envelopes
2935 static int count32(u32 * argv)
2937 int i = 0;
2939 if (argv != NULL) {
2940 for (;;) {
2941 u32 p; int error;
2943 error = get_user(p,argv);
2944 if (error) return error;
2945 if (!p) break;
2946 argv++; i++;
2949 return i;
2953 * 'copy_string32()' copies argument/envelope strings from user
2954 * memory to free pages in kernel mem. These are in a format ready
2955 * to be put directly into the top of new user memory.
2957 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
2959 while (argc-- > 0) {
2960 u32 str;
2961 int len;
2962 unsigned long pos;
2964 if (get_user(str, argv + argc) ||
2965 !str ||
2966 !(len = strnlen_user((char *)A(str), bprm->p)))
2967 return -EFAULT;
2969 if (bprm->p < len)
2970 return -E2BIG;
2972 bprm->p -= len;
2974 pos = bprm->p;
2975 while (len) {
2976 char *kaddr;
2977 struct page *page;
2978 int offset, bytes_to_copy, new, err;
2980 offset = pos % PAGE_SIZE;
2981 page = bprm->page[pos / PAGE_SIZE];
2982 new = 0;
2983 if (!page) {
2984 page = alloc_page(GFP_USER);
2985 bprm->page[pos / PAGE_SIZE] = page;
2986 if (!page)
2987 return -ENOMEM;
2988 new = 1;
2990 kaddr = (char *)kmap(page);
2992 if (new && offset)
2993 memset(kaddr, 0, offset);
2994 bytes_to_copy = PAGE_SIZE - offset;
2995 if (bytes_to_copy > len) {
2996 bytes_to_copy = len;
2997 if (new)
2998 memset(kaddr+offset+len, 0,
2999 PAGE_SIZE-offset-len);
3002 err = copy_from_user(kaddr + offset, (char *)A(str),
3003 bytes_to_copy);
3004 flush_page_to_ram(page);
3005 kunmap((unsigned long)kaddr);
3007 if (err)
3008 return -EFAULT;
3010 pos += bytes_to_copy;
3011 str += bytes_to_copy;
3012 len -= bytes_to_copy;
3015 return 0;
3019 * sys32_execve() executes a new program.
3021 static inline int
3022 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
3024 struct linux_binprm bprm;
3025 struct file * file;
3026 int retval;
3027 int i;
3029 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3030 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3032 file = open_exec(filename);
3034 retval = PTR_ERR(file);
3035 if (IS_ERR(file))
3036 return retval;
3038 bprm.file = file;
3039 bprm.filename = filename;
3040 bprm.sh_bang = 0;
3041 bprm.loader = 0;
3042 bprm.exec = 0;
3043 if ((bprm.argc = count32(argv)) < 0) {
3044 allow_write_access(file);
3045 fput(file);
3046 return bprm.argc;
3048 if ((bprm.envc = count32(envp)) < 0) {
3049 allow_write_access(file);
3050 fput(file);
3051 return bprm.envc;
3054 retval = prepare_binprm(&bprm);
3055 if (retval < 0)
3056 goto out;
3058 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3059 if (retval < 0)
3060 goto out;
3062 bprm.exec = bprm.p;
3063 retval = copy_strings32(bprm.envc, envp, &bprm);
3064 if (retval < 0)
3065 goto out;
3067 retval = copy_strings32(bprm.argc, argv, &bprm);
3068 if (retval < 0)
3069 goto out;
3071 retval = search_binary_handler(&bprm, regs);
3072 if (retval >= 0)
3073 /* execve success */
3074 return retval;
3076 out:
3077 /* Something went wrong, return the inode and free the argument pages*/
3078 allow_write_access(bprm.file);
3079 if (bprm.file)
3080 fput(bprm.file);
3082 for (i=0 ; i<MAX_ARG_PAGES ; i++)
3083 if (bprm.page[i])
3084 __free_page(bprm.page[i]);
3086 return retval;
3090 * sparc32_execve() executes a new program after the asm stub has set
3091 * things up for us. This should basically do what I want it to.
3093 asmlinkage int sparc32_execve(struct pt_regs *regs)
3095 int error, base = 0;
3096 char *filename;
3098 /* User register window flush is done by entry.S */
3100 /* Check for indirect call. */
3101 if((u32)regs->u_regs[UREG_G1] == 0)
3102 base = 1;
3104 filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
3105 error = PTR_ERR(filename);
3106 if(IS_ERR(filename))
3107 goto out;
3108 error = do_execve32(filename,
3109 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3110 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3111 putname(filename);
3113 if(!error) {
3114 fprs_write(0);
3115 current->thread.xfsr[0] = 0;
3116 current->thread.fpsaved[0] = 0;
3117 regs->tstate &= ~TSTATE_PEF;
3119 out:
3120 return error;
3123 #ifdef CONFIG_MODULES
3125 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3127 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3129 return sys_create_module(name_user, (size_t)size);
3132 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3134 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3135 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3137 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3139 return sys_init_module(name_user, mod_user);
3142 extern asmlinkage int sys_delete_module(const char *name_user);
3144 asmlinkage int sys32_delete_module(const char *name_user)
3146 return sys_delete_module(name_user);
3149 struct module_info32 {
3150 u32 addr;
3151 u32 size;
3152 u32 flags;
3153 s32 usecount;
3156 /* Query various bits about modules. */
3158 static inline long
3159 get_mod_name(const char *user_name, char **buf)
3161 unsigned long page;
3162 long retval;
3164 if ((unsigned long)user_name >= TASK_SIZE
3165 && !segment_eq(get_fs (), KERNEL_DS))
3166 return -EFAULT;
3168 page = __get_free_page(GFP_KERNEL);
3169 if (!page)
3170 return -ENOMEM;
3172 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3173 if (retval > 0) {
3174 if (retval < PAGE_SIZE) {
3175 *buf = (char *)page;
3176 return retval;
3178 retval = -ENAMETOOLONG;
3179 } else if (!retval)
3180 retval = -EINVAL;
3182 free_page(page);
3183 return retval;
3186 static inline void
3187 put_mod_name(char *buf)
3189 free_page((unsigned long)buf);
3192 static __inline__ struct module *find_module(const char *name)
3194 struct module *mod;
3196 for (mod = module_list; mod ; mod = mod->next) {
3197 if (mod->flags & MOD_DELETED)
3198 continue;
3199 if (!strcmp(mod->name, name))
3200 break;
3203 return mod;
3206 static int
3207 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3209 struct module *mod;
3210 size_t nmod, space, len;
3212 nmod = space = 0;
3214 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3215 len = strlen(mod->name)+1;
3216 if (len > bufsize)
3217 goto calc_space_needed;
3218 if (copy_to_user(buf, mod->name, len))
3219 return -EFAULT;
3220 buf += len;
3221 bufsize -= len;
3222 space += len;
3225 if (put_user(nmod, ret))
3226 return -EFAULT;
3227 else
3228 return 0;
3230 calc_space_needed:
3231 space += len;
3232 while ((mod = mod->next)->next != NULL)
3233 space += strlen(mod->name)+1;
3235 if (put_user(space, ret))
3236 return -EFAULT;
3237 else
3238 return -ENOSPC;
3241 static int
3242 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3244 size_t i, space, len;
3246 if (mod->next == NULL)
3247 return -EINVAL;
3248 if (!MOD_CAN_QUERY(mod))
3249 return put_user(0, ret);
3251 space = 0;
3252 for (i = 0; i < mod->ndeps; ++i) {
3253 const char *dep_name = mod->deps[i].dep->name;
3255 len = strlen(dep_name)+1;
3256 if (len > bufsize)
3257 goto calc_space_needed;
3258 if (copy_to_user(buf, dep_name, len))
3259 return -EFAULT;
3260 buf += len;
3261 bufsize -= len;
3262 space += len;
3265 return put_user(i, ret);
3267 calc_space_needed:
3268 space += len;
3269 while (++i < mod->ndeps)
3270 space += strlen(mod->deps[i].dep->name)+1;
3272 if (put_user(space, ret))
3273 return -EFAULT;
3274 else
3275 return -ENOSPC;
3278 static int
3279 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3281 size_t nrefs, space, len;
3282 struct module_ref *ref;
3284 if (mod->next == NULL)
3285 return -EINVAL;
3286 if (!MOD_CAN_QUERY(mod))
3287 if (put_user(0, ret))
3288 return -EFAULT;
3289 else
3290 return 0;
3292 space = 0;
3293 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3294 const char *ref_name = ref->ref->name;
3296 len = strlen(ref_name)+1;
3297 if (len > bufsize)
3298 goto calc_space_needed;
3299 if (copy_to_user(buf, ref_name, len))
3300 return -EFAULT;
3301 buf += len;
3302 bufsize -= len;
3303 space += len;
3306 if (put_user(nrefs, ret))
3307 return -EFAULT;
3308 else
3309 return 0;
3311 calc_space_needed:
3312 space += len;
3313 while ((ref = ref->next_ref) != NULL)
3314 space += strlen(ref->ref->name)+1;
3316 if (put_user(space, ret))
3317 return -EFAULT;
3318 else
3319 return -ENOSPC;
3322 static inline int
3323 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3325 size_t i, space, len;
3326 struct module_symbol *s;
3327 char *strings;
3328 unsigned *vals;
3330 if (!MOD_CAN_QUERY(mod))
3331 if (put_user(0, ret))
3332 return -EFAULT;
3333 else
3334 return 0;
3336 space = mod->nsyms * 2*sizeof(u32);
3338 i = len = 0;
3339 s = mod->syms;
3341 if (space > bufsize)
3342 goto calc_space_needed;
3344 if (!access_ok(VERIFY_WRITE, buf, space))
3345 return -EFAULT;
3347 bufsize -= space;
3348 vals = (unsigned *)buf;
3349 strings = buf+space;
3351 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3352 len = strlen(s->name)+1;
3353 if (len > bufsize)
3354 goto calc_space_needed;
3356 if (copy_to_user(strings, s->name, len)
3357 || __put_user(s->value, vals+0)
3358 || __put_user(space, vals+1))
3359 return -EFAULT;
3361 strings += len;
3362 bufsize -= len;
3363 space += len;
3366 if (put_user(i, ret))
3367 return -EFAULT;
3368 else
3369 return 0;
3371 calc_space_needed:
3372 for (; i < mod->nsyms; ++i, ++s)
3373 space += strlen(s->name)+1;
3375 if (put_user(space, ret))
3376 return -EFAULT;
3377 else
3378 return -ENOSPC;
3381 static inline int
3382 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3384 int error = 0;
3386 if (mod->next == NULL)
3387 return -EINVAL;
3389 if (sizeof(struct module_info32) <= bufsize) {
3390 struct module_info32 info;
3391 info.addr = (unsigned long)mod;
3392 info.size = mod->size;
3393 info.flags = mod->flags;
3394 info.usecount =
3395 ((mod_member_present(mod, can_unload)
3396 && mod->can_unload)
3397 ? -1 : atomic_read(&mod->uc.usecount));
3399 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3400 return -EFAULT;
3401 } else
3402 error = -ENOSPC;
3404 if (put_user(sizeof(struct module_info32), ret))
3405 return -EFAULT;
3407 return error;
3410 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3412 struct module *mod;
3413 int err;
3415 lock_kernel();
3416 if (name_user == 0) {
3417 /* This finds "kernel_module" which is not exported. */
3418 for(mod = module_list; mod->next != NULL; mod = mod->next)
3420 } else {
3421 long namelen;
3422 char *name;
3424 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3425 err = namelen;
3426 goto out;
3428 err = -ENOENT;
3429 if (namelen == 0) {
3430 /* This finds "kernel_module" which is not exported. */
3431 for(mod = module_list; mod->next != NULL; mod = mod->next)
3433 } else if ((mod = find_module(name)) == NULL) {
3434 put_mod_name(name);
3435 goto out;
3437 put_mod_name(name);
3440 switch (which)
3442 case 0:
3443 err = 0;
3444 break;
3445 case QM_MODULES:
3446 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3447 break;
3448 case QM_DEPS:
3449 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3450 break;
3451 case QM_REFS:
3452 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3453 break;
3454 case QM_SYMBOLS:
3455 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3456 break;
3457 case QM_INFO:
3458 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3459 break;
3460 default:
3461 err = -EINVAL;
3462 break;
3464 out:
3465 unlock_kernel();
3466 return err;
3469 struct kernel_sym32 {
3470 u32 value;
3471 char name[60];
3474 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3476 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3478 int len, i;
3479 struct kernel_sym *tbl;
3480 mm_segment_t old_fs;
3482 len = sys_get_kernel_syms(NULL);
3483 if (!table) return len;
3484 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3485 if (!tbl) return -ENOMEM;
3486 old_fs = get_fs();
3487 set_fs (KERNEL_DS);
3488 sys_get_kernel_syms(tbl);
3489 set_fs (old_fs);
3490 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3491 if (put_user (tbl[i].value, &table->value) ||
3492 copy_to_user (table->name, tbl[i].name, 60))
3493 break;
3495 kfree (tbl);
3496 return i;
3499 #else /* CONFIG_MODULES */
3501 asmlinkage unsigned long
3502 sys32_create_module(const char *name_user, size_t size)
3504 return -ENOSYS;
3507 asmlinkage int
3508 sys32_init_module(const char *name_user, struct module *mod_user)
3510 return -ENOSYS;
3513 asmlinkage int
3514 sys32_delete_module(const char *name_user)
3516 return -ENOSYS;
3519 asmlinkage int
3520 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3521 size_t *ret)
3523 /* Let the program know about the new interface. Not that
3524 it'll do them much good. */
3525 if (which == 0)
3526 return 0;
3528 return -ENOSYS;
3531 asmlinkage int
3532 sys32_get_kernel_syms(struct kernel_sym *table)
3534 return -ENOSYS;
3537 #endif /* CONFIG_MODULES */
3539 /* Stuff for NFS server syscalls... */
3540 struct nfsctl_svc32 {
3541 u16 svc32_port;
3542 s32 svc32_nthreads;
3545 struct nfsctl_client32 {
3546 s8 cl32_ident[NFSCLNT_IDMAX+1];
3547 s32 cl32_naddr;
3548 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3549 s32 cl32_fhkeytype;
3550 s32 cl32_fhkeylen;
3551 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3554 struct nfsctl_export32 {
3555 s8 ex32_client[NFSCLNT_IDMAX+1];
3556 s8 ex32_path[NFS_MAXPATHLEN+1];
3557 __kernel_dev_t32 ex32_dev;
3558 __kernel_ino_t32 ex32_ino;
3559 s32 ex32_flags;
3560 __kernel_uid_t32 ex32_anon_uid;
3561 __kernel_gid_t32 ex32_anon_gid;
3564 struct nfsctl_uidmap32 {
3565 u32 ug32_ident; /* char * */
3566 __kernel_uid_t32 ug32_uidbase;
3567 s32 ug32_uidlen;
3568 u32 ug32_udimap; /* uid_t * */
3569 __kernel_uid_t32 ug32_gidbase;
3570 s32 ug32_gidlen;
3571 u32 ug32_gdimap; /* gid_t * */
3574 struct nfsctl_fhparm32 {
3575 struct sockaddr gf32_addr;
3576 __kernel_dev_t32 gf32_dev;
3577 __kernel_ino_t32 gf32_ino;
3578 s32 gf32_version;
3581 struct nfsctl_fdparm32 {
3582 struct sockaddr gd32_addr;
3583 s8 gd32_path[NFS_MAXPATHLEN+1];
3584 s32 gd32_version;
3587 struct nfsctl_fsparm32 {
3588 struct sockaddr gd32_addr;
3589 s8 gd32_path[NFS_MAXPATHLEN+1];
3590 s32 gd32_maxlen;
3593 struct nfsctl_arg32 {
3594 s32 ca32_version; /* safeguard */
3595 union {
3596 struct nfsctl_svc32 u32_svc;
3597 struct nfsctl_client32 u32_client;
3598 struct nfsctl_export32 u32_export;
3599 struct nfsctl_uidmap32 u32_umap;
3600 struct nfsctl_fhparm32 u32_getfh;
3601 struct nfsctl_fdparm32 u32_getfd;
3602 struct nfsctl_fsparm32 u32_getfs;
3603 } u;
3604 #define ca32_svc u.u32_svc
3605 #define ca32_client u.u32_client
3606 #define ca32_export u.u32_export
3607 #define ca32_umap u.u32_umap
3608 #define ca32_getfh u.u32_getfh
3609 #define ca32_getfd u.u32_getfd
3610 #define ca32_getfs u.u32_getfs
3611 #define ca32_authd u.u32_authd
3614 union nfsctl_res32 {
3615 __u8 cr32_getfh[NFS_FHSIZE];
3616 struct knfsd_fh cr32_getfs;
3619 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3621 int err;
3623 err = __get_user(karg->ca_version, &arg32->ca32_version);
3624 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3625 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3626 return err;
3629 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3631 int err;
3633 err = __get_user(karg->ca_version, &arg32->ca32_version);
3634 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3635 &arg32->ca32_client.cl32_ident[0],
3636 NFSCLNT_IDMAX);
3637 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3638 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3639 &arg32->ca32_client.cl32_addrlist[0],
3640 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3641 err |= __get_user(karg->ca_client.cl_fhkeytype,
3642 &arg32->ca32_client.cl32_fhkeytype);
3643 err |= __get_user(karg->ca_client.cl_fhkeylen,
3644 &arg32->ca32_client.cl32_fhkeylen);
3645 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3646 &arg32->ca32_client.cl32_fhkey[0],
3647 NFSCLNT_KEYMAX);
3648 return err;
3651 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3653 int err;
3655 err = __get_user(karg->ca_version, &arg32->ca32_version);
3656 err |= copy_from_user(&karg->ca_export.ex_client[0],
3657 &arg32->ca32_export.ex32_client[0],
3658 NFSCLNT_IDMAX);
3659 err |= copy_from_user(&karg->ca_export.ex_path[0],
3660 &arg32->ca32_export.ex32_path[0],
3661 NFS_MAXPATHLEN);
3662 err |= __get_user(karg->ca_export.ex_dev,
3663 &arg32->ca32_export.ex32_dev);
3664 err |= __get_user(karg->ca_export.ex_ino,
3665 &arg32->ca32_export.ex32_ino);
3666 err |= __get_user(karg->ca_export.ex_flags,
3667 &arg32->ca32_export.ex32_flags);
3668 err |= __get_user(karg->ca_export.ex_anon_uid,
3669 &arg32->ca32_export.ex32_anon_uid);
3670 err |= __get_user(karg->ca_export.ex_anon_gid,
3671 &arg32->ca32_export.ex32_anon_gid);
3672 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3673 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3674 return err;
3677 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3679 u32 uaddr;
3680 int i;
3681 int err;
3683 memset(karg, 0, sizeof(*karg));
3684 if(__get_user(karg->ca_version, &arg32->ca32_version))
3685 return -EFAULT;
3686 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3687 if(!karg->ca_umap.ug_ident)
3688 return -ENOMEM;
3689 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3690 if(strncpy_from_user(karg->ca_umap.ug_ident,
3691 (char *)A(uaddr), PAGE_SIZE) <= 0)
3692 return -EFAULT;
3693 err |= __get_user(karg->ca_umap.ug_uidbase,
3694 &arg32->ca32_umap.ug32_uidbase);
3695 err |= __get_user(karg->ca_umap.ug_uidlen,
3696 &arg32->ca32_umap.ug32_uidlen);
3697 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3698 if (err)
3699 return -EFAULT;
3700 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3701 GFP_USER);
3702 if(!karg->ca_umap.ug_udimap)
3703 return -ENOMEM;
3704 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3705 err |= __get_user(karg->ca_umap.ug_udimap[i],
3706 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3707 err |= __get_user(karg->ca_umap.ug_gidbase,
3708 &arg32->ca32_umap.ug32_gidbase);
3709 err |= __get_user(karg->ca_umap.ug_uidlen,
3710 &arg32->ca32_umap.ug32_gidlen);
3711 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3712 if (err)
3713 return -EFAULT;
3714 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3715 GFP_USER);
3716 if(!karg->ca_umap.ug_gdimap)
3717 return -ENOMEM;
3718 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3719 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3720 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3722 return err;
3725 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3727 int err;
3729 err = __get_user(karg->ca_version, &arg32->ca32_version);
3730 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3731 &arg32->ca32_getfh.gf32_addr,
3732 (sizeof(struct sockaddr)));
3733 err |= __get_user(karg->ca_getfh.gf_dev,
3734 &arg32->ca32_getfh.gf32_dev);
3735 err |= __get_user(karg->ca_getfh.gf_ino,
3736 &arg32->ca32_getfh.gf32_ino);
3737 err |= __get_user(karg->ca_getfh.gf_version,
3738 &arg32->ca32_getfh.gf32_version);
3739 return err;
3742 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3744 int err;
3746 err = __get_user(karg->ca_version, &arg32->ca32_version);
3747 err |= copy_from_user(&karg->ca_getfd.gd_addr,
3748 &arg32->ca32_getfd.gd32_addr,
3749 (sizeof(struct sockaddr)));
3750 err |= copy_from_user(&karg->ca_getfd.gd_path,
3751 &arg32->ca32_getfd.gd32_path,
3752 (NFS_MAXPATHLEN+1));
3753 err |= __get_user(karg->ca_getfd.gd_version,
3754 &arg32->ca32_getfd.gd32_version);
3755 return err;
3758 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3760 int err;
3762 err = __get_user(karg->ca_version, &arg32->ca32_version);
3763 err |= copy_from_user(&karg->ca_getfs.gd_addr,
3764 &arg32->ca32_getfs.gd32_addr,
3765 (sizeof(struct sockaddr)));
3766 err |= copy_from_user(&karg->ca_getfs.gd_path,
3767 &arg32->ca32_getfs.gd32_path,
3768 (NFS_MAXPATHLEN+1));
3769 err |= __get_user(karg->ca_getfs.gd_maxlen,
3770 &arg32->ca32_getfs.gd32_maxlen);
3771 return err;
3774 /* This really doesn't need translations, we are only passing
3775 * back a union which contains opaque nfs file handle data.
3777 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3779 return copy_to_user(res32, kres, sizeof(*res32));
3782 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3784 struct nfsctl_arg *karg = NULL;
3785 union nfsctl_res *kres = NULL;
3786 mm_segment_t oldfs;
3787 int err;
3789 karg = kmalloc(sizeof(*karg), GFP_USER);
3790 if(!karg)
3791 return -ENOMEM;
3792 if(res32) {
3793 kres = kmalloc(sizeof(*kres), GFP_USER);
3794 if(!kres) {
3795 kfree(karg);
3796 return -ENOMEM;
3799 switch(cmd) {
3800 case NFSCTL_SVC:
3801 err = nfs_svc32_trans(karg, arg32);
3802 break;
3803 case NFSCTL_ADDCLIENT:
3804 err = nfs_clnt32_trans(karg, arg32);
3805 break;
3806 case NFSCTL_DELCLIENT:
3807 err = nfs_clnt32_trans(karg, arg32);
3808 break;
3809 case NFSCTL_EXPORT:
3810 case NFSCTL_UNEXPORT:
3811 err = nfs_exp32_trans(karg, arg32);
3812 break;
3813 /* This one is unimplemented, be we're ready for it. */
3814 case NFSCTL_UGIDUPDATE:
3815 err = nfs_uud32_trans(karg, arg32);
3816 break;
3817 case NFSCTL_GETFH:
3818 err = nfs_getfh32_trans(karg, arg32);
3819 break;
3820 case NFSCTL_GETFD:
3821 err = nfs_getfd32_trans(karg, arg32);
3822 break;
3823 case NFSCTL_GETFS:
3824 err = nfs_getfs32_trans(karg, arg32);
3825 break;
3826 default:
3827 err = -EINVAL;
3828 break;
3830 if(err)
3831 goto done;
3832 oldfs = get_fs();
3833 set_fs(KERNEL_DS);
3834 err = sys_nfsservctl(cmd, karg, kres);
3835 set_fs(oldfs);
3837 if (err)
3838 goto done;
3840 if((cmd == NFSCTL_GETFH) ||
3841 (cmd == NFSCTL_GETFD) ||
3842 (cmd == NFSCTL_GETFS))
3843 err = nfs_getfh32_res_trans(kres, res32);
3845 done:
3846 if(karg) {
3847 if(cmd == NFSCTL_UGIDUPDATE) {
3848 if(karg->ca_umap.ug_ident)
3849 kfree(karg->ca_umap.ug_ident);
3850 if(karg->ca_umap.ug_udimap)
3851 kfree(karg->ca_umap.ug_udimap);
3852 if(karg->ca_umap.ug_gdimap)
3853 kfree(karg->ca_umap.ug_gdimap);
3855 kfree(karg);
3857 if(kres)
3858 kfree(kres);
3859 return err;
3862 /* Translations due to time_t size differences. Which affects all
3863 sorts of things, like timeval and itimerval. */
3865 extern struct timezone sys_tz;
3866 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3868 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3870 if (tv) {
3871 struct timeval ktv;
3872 do_gettimeofday(&ktv);
3873 if (put_tv32(tv, &ktv))
3874 return -EFAULT;
3876 if (tz) {
3877 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3878 return -EFAULT;
3880 return 0;
3883 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3885 struct timeval ktv;
3886 struct timezone ktz;
3888 if (tv) {
3889 if (get_tv32(&ktv, tv))
3890 return -EFAULT;
3892 if (tz) {
3893 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3894 return -EFAULT;
3897 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3900 extern int do_getitimer(int which, struct itimerval *value);
3902 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3904 struct itimerval kit;
3905 int error;
3907 error = do_getitimer(which, &kit);
3908 if (!error && put_it32(it, &kit))
3909 error = -EFAULT;
3911 return error;
3914 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3916 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3918 struct itimerval kin, kout;
3919 int error;
3921 if (in) {
3922 if (get_it32(&kin, in))
3923 return -EFAULT;
3924 } else
3925 memset(&kin, 0, sizeof(kin));
3927 error = do_setitimer(which, &kin, out ? &kout : NULL);
3928 if (error || !out)
3929 return error;
3930 if (put_it32(out, &kout))
3931 return -EFAULT;
3933 return 0;
3937 asmlinkage int sys_utimes(char *, struct timeval *);
3939 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3941 char *kfilename;
3942 struct timeval ktvs[2];
3943 mm_segment_t old_fs;
3944 int ret;
3946 kfilename = getname32(filename);
3947 ret = PTR_ERR(kfilename);
3948 if (!IS_ERR(kfilename)) {
3949 if (tvs) {
3950 if (get_tv32(&ktvs[0], tvs) ||
3951 get_tv32(&ktvs[1], 1+tvs))
3952 return -EFAULT;
3955 old_fs = get_fs();
3956 set_fs(KERNEL_DS);
3957 ret = sys_utimes(kfilename, &ktvs[0]);
3958 set_fs(old_fs);
3960 putname(kfilename);
3962 return ret;
3965 /* These are here just in case some old sparc32 binary calls it. */
3966 asmlinkage int sys32_pause(void)
3968 current->state = TASK_INTERRUPTIBLE;
3969 schedule();
3970 return -ERESTARTNOHAND;
3973 /* PCI config space poking. */
3974 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3975 unsigned long dfn,
3976 unsigned long off,
3977 unsigned long len,
3978 unsigned char *buf);
3980 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3981 unsigned long dfn,
3982 unsigned long off,
3983 unsigned long len,
3984 unsigned char *buf);
3986 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3988 return sys_pciconfig_read((unsigned long) bus,
3989 (unsigned long) dfn,
3990 (unsigned long) off,
3991 (unsigned long) len,
3992 (unsigned char *)AA(ubuf));
3995 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3997 return sys_pciconfig_write((unsigned long) bus,
3998 (unsigned long) dfn,
3999 (unsigned long) off,
4000 (unsigned long) len,
4001 (unsigned char *)AA(ubuf));
4004 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
4005 unsigned long arg4, unsigned long arg5);
4007 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
4009 return sys_prctl(option,
4010 (unsigned long) arg2,
4011 (unsigned long) arg3,
4012 (unsigned long) arg4,
4013 (unsigned long) arg5);
4017 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4018 size_t count, loff_t pos);
4020 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4021 size_t count, loff_t pos);
4023 typedef __kernel_ssize_t32 ssize_t32;
4025 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
4026 __kernel_size_t32 count, u32 poshi, u32 poslo)
4028 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4031 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
4032 __kernel_size_t32 count, u32 poshi, u32 poslo)
4034 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4038 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4040 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4042 mm_segment_t old_fs = get_fs();
4043 int ret;
4044 off_t of;
4046 if (offset && get_user(of, offset))
4047 return -EFAULT;
4049 set_fs(KERNEL_DS);
4050 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4051 set_fs(old_fs);
4053 if (!ret && offset && put_user(of, offset))
4054 return -EFAULT;
4056 return ret;
4059 /* Handle adjtimex compatability. */
4061 struct timex32 {
4062 u32 modes;
4063 s32 offset, freq, maxerror, esterror;
4064 s32 status, constant, precision, tolerance;
4065 struct timeval32 time;
4066 s32 tick;
4067 s32 ppsfreq, jitter, shift, stabil;
4068 s32 jitcnt, calcnt, errcnt, stbcnt;
4069 s32 :32; s32 :32; s32 :32; s32 :32;
4070 s32 :32; s32 :32; s32 :32; s32 :32;
4071 s32 :32; s32 :32; s32 :32; s32 :32;
4074 extern int do_adjtimex(struct timex *);
4076 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4078 struct timex txc;
4079 int ret;
4081 memset(&txc, 0, sizeof(struct timex));
4083 if(get_user(txc.modes, &utp->modes) ||
4084 __get_user(txc.offset, &utp->offset) ||
4085 __get_user(txc.freq, &utp->freq) ||
4086 __get_user(txc.maxerror, &utp->maxerror) ||
4087 __get_user(txc.esterror, &utp->esterror) ||
4088 __get_user(txc.status, &utp->status) ||
4089 __get_user(txc.constant, &utp->constant) ||
4090 __get_user(txc.precision, &utp->precision) ||
4091 __get_user(txc.tolerance, &utp->tolerance) ||
4092 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4093 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4094 __get_user(txc.tick, &utp->tick) ||
4095 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4096 __get_user(txc.jitter, &utp->jitter) ||
4097 __get_user(txc.shift, &utp->shift) ||
4098 __get_user(txc.stabil, &utp->stabil) ||
4099 __get_user(txc.jitcnt, &utp->jitcnt) ||
4100 __get_user(txc.calcnt, &utp->calcnt) ||
4101 __get_user(txc.errcnt, &utp->errcnt) ||
4102 __get_user(txc.stbcnt, &utp->stbcnt))
4103 return -EFAULT;
4105 ret = do_adjtimex(&txc);
4107 if(put_user(txc.modes, &utp->modes) ||
4108 __put_user(txc.offset, &utp->offset) ||
4109 __put_user(txc.freq, &utp->freq) ||
4110 __put_user(txc.maxerror, &utp->maxerror) ||
4111 __put_user(txc.esterror, &utp->esterror) ||
4112 __put_user(txc.status, &utp->status) ||
4113 __put_user(txc.constant, &utp->constant) ||
4114 __put_user(txc.precision, &utp->precision) ||
4115 __put_user(txc.tolerance, &utp->tolerance) ||
4116 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4117 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4118 __put_user(txc.tick, &utp->tick) ||
4119 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4120 __put_user(txc.jitter, &utp->jitter) ||
4121 __put_user(txc.shift, &utp->shift) ||
4122 __put_user(txc.stabil, &utp->stabil) ||
4123 __put_user(txc.jitcnt, &utp->jitcnt) ||
4124 __put_user(txc.calcnt, &utp->calcnt) ||
4125 __put_user(txc.errcnt, &utp->errcnt) ||
4126 __put_user(txc.stbcnt, &utp->stbcnt))
4127 ret = -EFAULT;
4129 return ret;
4132 /* This is just a version for 32-bit applications which does
4133 * not force O_LARGEFILE on.
4136 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4138 char * tmp;
4139 int fd, error;
4141 tmp = getname(filename);
4142 fd = PTR_ERR(tmp);
4143 if (!IS_ERR(tmp)) {
4144 fd = get_unused_fd();
4145 if (fd >= 0) {
4146 struct file * f;
4147 lock_kernel();
4148 f = filp_open(tmp, flags, mode);
4149 unlock_kernel();
4150 error = PTR_ERR(f);
4151 if (IS_ERR(f))
4152 goto out_error;
4153 fd_install(fd, f);
4155 out:
4156 putname(tmp);
4158 return fd;
4160 out_error:
4161 put_unused_fd(fd);
4162 fd = error;
4163 goto out;
4166 extern unsigned long do_mremap(unsigned long addr,
4167 unsigned long old_len, unsigned long new_len,
4168 unsigned long flags, unsigned long new_addr);
4170 asmlinkage unsigned long sys32_mremap(unsigned long addr,
4171 unsigned long old_len, unsigned long new_len,
4172 unsigned long flags, u32 __new_addr)
4174 unsigned long ret = -EINVAL;
4175 unsigned long new_addr = AA(__new_addr);
4177 if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
4178 goto out;
4179 if (addr > 0xf0000000UL - old_len)
4180 goto out;
4181 down(&current->mm->mmap_sem);
4182 if (flags & MREMAP_FIXED) {
4183 if (new_addr > 0xf0000000UL - new_len)
4184 goto out_sem;
4185 } else if (addr > 0xf0000000UL - new_len) {
4186 ret = -ENOMEM;
4187 if (!(flags & MREMAP_MAYMOVE))
4188 goto out_sem;
4189 new_addr = get_unmapped_area (addr, new_len);
4190 if (!new_addr)
4191 goto out_sem;
4192 flags |= MREMAP_FIXED;
4194 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
4195 out_sem:
4196 up(&current->mm->mmap_sem);
4197 out:
4198 return ret;