Linux-2.4.0-test2
[davej-history.git] / arch / sparc64 / kernel / sys_sparc32.c
blob26c5faecdebd25113a501473bed0b7914d2229f8
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 lock_kernel();
3033 file = open_exec(filename);
3034 unlock_kernel();
3036 retval = PTR_ERR(file);
3037 if (IS_ERR(file))
3038 return retval;
3040 bprm.file = file;
3041 bprm.filename = filename;
3042 bprm.sh_bang = 0;
3043 bprm.loader = 0;
3044 bprm.exec = 0;
3045 if ((bprm.argc = count32(argv)) < 0) {
3046 fput(file);
3047 return bprm.argc;
3049 if ((bprm.envc = count32(envp)) < 0) {
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 if (bprm.file)
3079 fput(bprm.file);
3081 for (i=0 ; i<MAX_ARG_PAGES ; i++)
3082 if (bprm.page[i])
3083 __free_page(bprm.page[i]);
3085 return retval;
3089 * sparc32_execve() executes a new program after the asm stub has set
3090 * things up for us. This should basically do what I want it to.
3092 asmlinkage int sparc32_execve(struct pt_regs *regs)
3094 int error, base = 0;
3095 char *filename;
3097 /* User register window flush is done by entry.S */
3099 /* Check for indirect call. */
3100 if((u32)regs->u_regs[UREG_G1] == 0)
3101 base = 1;
3103 filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
3104 error = PTR_ERR(filename);
3105 if(IS_ERR(filename))
3106 goto out;
3107 error = do_execve32(filename,
3108 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3109 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3110 putname(filename);
3112 if(!error) {
3113 fprs_write(0);
3114 current->thread.xfsr[0] = 0;
3115 current->thread.fpsaved[0] = 0;
3116 regs->tstate &= ~TSTATE_PEF;
3118 out:
3119 return error;
3122 #ifdef CONFIG_MODULES
3124 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3126 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3128 return sys_create_module(name_user, (size_t)size);
3131 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3133 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3134 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3136 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3138 return sys_init_module(name_user, mod_user);
3141 extern asmlinkage int sys_delete_module(const char *name_user);
3143 asmlinkage int sys32_delete_module(const char *name_user)
3145 return sys_delete_module(name_user);
3148 struct module_info32 {
3149 u32 addr;
3150 u32 size;
3151 u32 flags;
3152 s32 usecount;
3155 /* Query various bits about modules. */
3157 static inline long
3158 get_mod_name(const char *user_name, char **buf)
3160 unsigned long page;
3161 long retval;
3163 if ((unsigned long)user_name >= TASK_SIZE
3164 && !segment_eq(get_fs (), KERNEL_DS))
3165 return -EFAULT;
3167 page = __get_free_page(GFP_KERNEL);
3168 if (!page)
3169 return -ENOMEM;
3171 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3172 if (retval > 0) {
3173 if (retval < PAGE_SIZE) {
3174 *buf = (char *)page;
3175 return retval;
3177 retval = -ENAMETOOLONG;
3178 } else if (!retval)
3179 retval = -EINVAL;
3181 free_page(page);
3182 return retval;
3185 static inline void
3186 put_mod_name(char *buf)
3188 free_page((unsigned long)buf);
3191 static __inline__ struct module *find_module(const char *name)
3193 struct module *mod;
3195 for (mod = module_list; mod ; mod = mod->next) {
3196 if (mod->flags & MOD_DELETED)
3197 continue;
3198 if (!strcmp(mod->name, name))
3199 break;
3202 return mod;
3205 static int
3206 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3208 struct module *mod;
3209 size_t nmod, space, len;
3211 nmod = space = 0;
3213 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3214 len = strlen(mod->name)+1;
3215 if (len > bufsize)
3216 goto calc_space_needed;
3217 if (copy_to_user(buf, mod->name, len))
3218 return -EFAULT;
3219 buf += len;
3220 bufsize -= len;
3221 space += len;
3224 if (put_user(nmod, ret))
3225 return -EFAULT;
3226 else
3227 return 0;
3229 calc_space_needed:
3230 space += len;
3231 while ((mod = mod->next)->next != NULL)
3232 space += strlen(mod->name)+1;
3234 if (put_user(space, ret))
3235 return -EFAULT;
3236 else
3237 return -ENOSPC;
3240 static int
3241 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3243 size_t i, space, len;
3245 if (mod->next == NULL)
3246 return -EINVAL;
3247 if (!MOD_CAN_QUERY(mod))
3248 return put_user(0, ret);
3250 space = 0;
3251 for (i = 0; i < mod->ndeps; ++i) {
3252 const char *dep_name = mod->deps[i].dep->name;
3254 len = strlen(dep_name)+1;
3255 if (len > bufsize)
3256 goto calc_space_needed;
3257 if (copy_to_user(buf, dep_name, len))
3258 return -EFAULT;
3259 buf += len;
3260 bufsize -= len;
3261 space += len;
3264 return put_user(i, ret);
3266 calc_space_needed:
3267 space += len;
3268 while (++i < mod->ndeps)
3269 space += strlen(mod->deps[i].dep->name)+1;
3271 if (put_user(space, ret))
3272 return -EFAULT;
3273 else
3274 return -ENOSPC;
3277 static int
3278 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3280 size_t nrefs, space, len;
3281 struct module_ref *ref;
3283 if (mod->next == NULL)
3284 return -EINVAL;
3285 if (!MOD_CAN_QUERY(mod))
3286 if (put_user(0, ret))
3287 return -EFAULT;
3288 else
3289 return 0;
3291 space = 0;
3292 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3293 const char *ref_name = ref->ref->name;
3295 len = strlen(ref_name)+1;
3296 if (len > bufsize)
3297 goto calc_space_needed;
3298 if (copy_to_user(buf, ref_name, len))
3299 return -EFAULT;
3300 buf += len;
3301 bufsize -= len;
3302 space += len;
3305 if (put_user(nrefs, ret))
3306 return -EFAULT;
3307 else
3308 return 0;
3310 calc_space_needed:
3311 space += len;
3312 while ((ref = ref->next_ref) != NULL)
3313 space += strlen(ref->ref->name)+1;
3315 if (put_user(space, ret))
3316 return -EFAULT;
3317 else
3318 return -ENOSPC;
3321 static inline int
3322 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3324 size_t i, space, len;
3325 struct module_symbol *s;
3326 char *strings;
3327 unsigned *vals;
3329 if (!MOD_CAN_QUERY(mod))
3330 if (put_user(0, ret))
3331 return -EFAULT;
3332 else
3333 return 0;
3335 space = mod->nsyms * 2*sizeof(u32);
3337 i = len = 0;
3338 s = mod->syms;
3340 if (space > bufsize)
3341 goto calc_space_needed;
3343 if (!access_ok(VERIFY_WRITE, buf, space))
3344 return -EFAULT;
3346 bufsize -= space;
3347 vals = (unsigned *)buf;
3348 strings = buf+space;
3350 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3351 len = strlen(s->name)+1;
3352 if (len > bufsize)
3353 goto calc_space_needed;
3355 if (copy_to_user(strings, s->name, len)
3356 || __put_user(s->value, vals+0)
3357 || __put_user(space, vals+1))
3358 return -EFAULT;
3360 strings += len;
3361 bufsize -= len;
3362 space += len;
3365 if (put_user(i, ret))
3366 return -EFAULT;
3367 else
3368 return 0;
3370 calc_space_needed:
3371 for (; i < mod->nsyms; ++i, ++s)
3372 space += strlen(s->name)+1;
3374 if (put_user(space, ret))
3375 return -EFAULT;
3376 else
3377 return -ENOSPC;
3380 static inline int
3381 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3383 int error = 0;
3385 if (mod->next == NULL)
3386 return -EINVAL;
3388 if (sizeof(struct module_info32) <= bufsize) {
3389 struct module_info32 info;
3390 info.addr = (unsigned long)mod;
3391 info.size = mod->size;
3392 info.flags = mod->flags;
3393 info.usecount =
3394 ((mod_member_present(mod, can_unload)
3395 && mod->can_unload)
3396 ? -1 : atomic_read(&mod->uc.usecount));
3398 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3399 return -EFAULT;
3400 } else
3401 error = -ENOSPC;
3403 if (put_user(sizeof(struct module_info32), ret))
3404 return -EFAULT;
3406 return error;
3409 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3411 struct module *mod;
3412 int err;
3414 lock_kernel();
3415 if (name_user == 0) {
3416 /* This finds "kernel_module" which is not exported. */
3417 for(mod = module_list; mod->next != NULL; mod = mod->next)
3419 } else {
3420 long namelen;
3421 char *name;
3423 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3424 err = namelen;
3425 goto out;
3427 err = -ENOENT;
3428 if (namelen == 0) {
3429 /* This finds "kernel_module" which is not exported. */
3430 for(mod = module_list; mod->next != NULL; mod = mod->next)
3432 } else if ((mod = find_module(name)) == NULL) {
3433 put_mod_name(name);
3434 goto out;
3436 put_mod_name(name);
3439 switch (which)
3441 case 0:
3442 err = 0;
3443 break;
3444 case QM_MODULES:
3445 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3446 break;
3447 case QM_DEPS:
3448 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3449 break;
3450 case QM_REFS:
3451 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3452 break;
3453 case QM_SYMBOLS:
3454 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3455 break;
3456 case QM_INFO:
3457 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3458 break;
3459 default:
3460 err = -EINVAL;
3461 break;
3463 out:
3464 unlock_kernel();
3465 return err;
3468 struct kernel_sym32 {
3469 u32 value;
3470 char name[60];
3473 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3475 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3477 int len, i;
3478 struct kernel_sym *tbl;
3479 mm_segment_t old_fs;
3481 len = sys_get_kernel_syms(NULL);
3482 if (!table) return len;
3483 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3484 if (!tbl) return -ENOMEM;
3485 old_fs = get_fs();
3486 set_fs (KERNEL_DS);
3487 sys_get_kernel_syms(tbl);
3488 set_fs (old_fs);
3489 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3490 if (put_user (tbl[i].value, &table->value) ||
3491 copy_to_user (table->name, tbl[i].name, 60))
3492 break;
3494 kfree (tbl);
3495 return i;
3498 #else /* CONFIG_MODULES */
3500 asmlinkage unsigned long
3501 sys32_create_module(const char *name_user, size_t size)
3503 return -ENOSYS;
3506 asmlinkage int
3507 sys32_init_module(const char *name_user, struct module *mod_user)
3509 return -ENOSYS;
3512 asmlinkage int
3513 sys32_delete_module(const char *name_user)
3515 return -ENOSYS;
3518 asmlinkage int
3519 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3520 size_t *ret)
3522 /* Let the program know about the new interface. Not that
3523 it'll do them much good. */
3524 if (which == 0)
3525 return 0;
3527 return -ENOSYS;
3530 asmlinkage int
3531 sys32_get_kernel_syms(struct kernel_sym *table)
3533 return -ENOSYS;
3536 #endif /* CONFIG_MODULES */
3538 /* Stuff for NFS server syscalls... */
3539 struct nfsctl_svc32 {
3540 u16 svc32_port;
3541 s32 svc32_nthreads;
3544 struct nfsctl_client32 {
3545 s8 cl32_ident[NFSCLNT_IDMAX+1];
3546 s32 cl32_naddr;
3547 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3548 s32 cl32_fhkeytype;
3549 s32 cl32_fhkeylen;
3550 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3553 struct nfsctl_export32 {
3554 s8 ex32_client[NFSCLNT_IDMAX+1];
3555 s8 ex32_path[NFS_MAXPATHLEN+1];
3556 __kernel_dev_t32 ex32_dev;
3557 __kernel_ino_t32 ex32_ino;
3558 s32 ex32_flags;
3559 __kernel_uid_t32 ex32_anon_uid;
3560 __kernel_gid_t32 ex32_anon_gid;
3563 struct nfsctl_uidmap32 {
3564 u32 ug32_ident; /* char * */
3565 __kernel_uid_t32 ug32_uidbase;
3566 s32 ug32_uidlen;
3567 u32 ug32_udimap; /* uid_t * */
3568 __kernel_uid_t32 ug32_gidbase;
3569 s32 ug32_gidlen;
3570 u32 ug32_gdimap; /* gid_t * */
3573 struct nfsctl_fhparm32 {
3574 struct sockaddr gf32_addr;
3575 __kernel_dev_t32 gf32_dev;
3576 __kernel_ino_t32 gf32_ino;
3577 s32 gf32_version;
3580 struct nfsctl_fdparm32 {
3581 struct sockaddr gd32_addr;
3582 s8 gd32_path[NFS_MAXPATHLEN+1];
3583 s32 gd32_version;
3586 struct nfsctl_fsparm32 {
3587 struct sockaddr gd32_addr;
3588 s8 gd32_path[NFS_MAXPATHLEN+1];
3589 s32 gd32_maxlen;
3592 struct nfsctl_arg32 {
3593 s32 ca32_version; /* safeguard */
3594 union {
3595 struct nfsctl_svc32 u32_svc;
3596 struct nfsctl_client32 u32_client;
3597 struct nfsctl_export32 u32_export;
3598 struct nfsctl_uidmap32 u32_umap;
3599 struct nfsctl_fhparm32 u32_getfh;
3600 struct nfsctl_fdparm32 u32_getfd;
3601 struct nfsctl_fsparm32 u32_getfs;
3602 } u;
3603 #define ca32_svc u.u32_svc
3604 #define ca32_client u.u32_client
3605 #define ca32_export u.u32_export
3606 #define ca32_umap u.u32_umap
3607 #define ca32_getfh u.u32_getfh
3608 #define ca32_getfd u.u32_getfd
3609 #define ca32_getfs u.u32_getfs
3610 #define ca32_authd u.u32_authd
3613 union nfsctl_res32 {
3614 __u8 cr32_getfh[NFS_FHSIZE];
3615 struct knfsd_fh cr32_getfs;
3618 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3620 int err;
3622 err = __get_user(karg->ca_version, &arg32->ca32_version);
3623 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3624 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3625 return err;
3628 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3630 int err;
3632 err = __get_user(karg->ca_version, &arg32->ca32_version);
3633 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3634 &arg32->ca32_client.cl32_ident[0],
3635 NFSCLNT_IDMAX);
3636 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3637 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3638 &arg32->ca32_client.cl32_addrlist[0],
3639 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3640 err |= __get_user(karg->ca_client.cl_fhkeytype,
3641 &arg32->ca32_client.cl32_fhkeytype);
3642 err |= __get_user(karg->ca_client.cl_fhkeylen,
3643 &arg32->ca32_client.cl32_fhkeylen);
3644 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3645 &arg32->ca32_client.cl32_fhkey[0],
3646 NFSCLNT_KEYMAX);
3647 return err;
3650 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3652 int err;
3654 err = __get_user(karg->ca_version, &arg32->ca32_version);
3655 err |= copy_from_user(&karg->ca_export.ex_client[0],
3656 &arg32->ca32_export.ex32_client[0],
3657 NFSCLNT_IDMAX);
3658 err |= copy_from_user(&karg->ca_export.ex_path[0],
3659 &arg32->ca32_export.ex32_path[0],
3660 NFS_MAXPATHLEN);
3661 err |= __get_user(karg->ca_export.ex_dev,
3662 &arg32->ca32_export.ex32_dev);
3663 err |= __get_user(karg->ca_export.ex_ino,
3664 &arg32->ca32_export.ex32_ino);
3665 err |= __get_user(karg->ca_export.ex_flags,
3666 &arg32->ca32_export.ex32_flags);
3667 err |= __get_user(karg->ca_export.ex_anon_uid,
3668 &arg32->ca32_export.ex32_anon_uid);
3669 err |= __get_user(karg->ca_export.ex_anon_gid,
3670 &arg32->ca32_export.ex32_anon_gid);
3671 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3672 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3673 return err;
3676 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3678 u32 uaddr;
3679 int i;
3680 int err;
3682 memset(karg, 0, sizeof(*karg));
3683 if(__get_user(karg->ca_version, &arg32->ca32_version))
3684 return -EFAULT;
3685 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3686 if(!karg->ca_umap.ug_ident)
3687 return -ENOMEM;
3688 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3689 if(strncpy_from_user(karg->ca_umap.ug_ident,
3690 (char *)A(uaddr), PAGE_SIZE) <= 0)
3691 return -EFAULT;
3692 err |= __get_user(karg->ca_umap.ug_uidbase,
3693 &arg32->ca32_umap.ug32_uidbase);
3694 err |= __get_user(karg->ca_umap.ug_uidlen,
3695 &arg32->ca32_umap.ug32_uidlen);
3696 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3697 if (err)
3698 return -EFAULT;
3699 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3700 GFP_USER);
3701 if(!karg->ca_umap.ug_udimap)
3702 return -ENOMEM;
3703 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3704 err |= __get_user(karg->ca_umap.ug_udimap[i],
3705 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3706 err |= __get_user(karg->ca_umap.ug_gidbase,
3707 &arg32->ca32_umap.ug32_gidbase);
3708 err |= __get_user(karg->ca_umap.ug_uidlen,
3709 &arg32->ca32_umap.ug32_gidlen);
3710 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3711 if (err)
3712 return -EFAULT;
3713 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3714 GFP_USER);
3715 if(!karg->ca_umap.ug_gdimap)
3716 return -ENOMEM;
3717 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3718 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3719 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3721 return err;
3724 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3726 int err;
3728 err = __get_user(karg->ca_version, &arg32->ca32_version);
3729 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3730 &arg32->ca32_getfh.gf32_addr,
3731 (sizeof(struct sockaddr)));
3732 err |= __get_user(karg->ca_getfh.gf_dev,
3733 &arg32->ca32_getfh.gf32_dev);
3734 err |= __get_user(karg->ca_getfh.gf_ino,
3735 &arg32->ca32_getfh.gf32_ino);
3736 err |= __get_user(karg->ca_getfh.gf_version,
3737 &arg32->ca32_getfh.gf32_version);
3738 return err;
3741 static int nfs_getfd32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3743 int err;
3745 err = __get_user(karg->ca_version, &arg32->ca32_version);
3746 err |= copy_from_user(&karg->ca_getfd.gd_addr,
3747 &arg32->ca32_getfd.gd32_addr,
3748 (sizeof(struct sockaddr)));
3749 err |= copy_from_user(&karg->ca_getfd.gd_path,
3750 &arg32->ca32_getfd.gd32_path,
3751 (NFS_MAXPATHLEN+1));
3752 err |= __get_user(karg->ca_getfd.gd_version,
3753 &arg32->ca32_getfd.gd32_version);
3754 return err;
3757 static int nfs_getfs32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3759 int err;
3761 err = __get_user(karg->ca_version, &arg32->ca32_version);
3762 err |= copy_from_user(&karg->ca_getfs.gd_addr,
3763 &arg32->ca32_getfs.gd32_addr,
3764 (sizeof(struct sockaddr)));
3765 err |= copy_from_user(&karg->ca_getfs.gd_path,
3766 &arg32->ca32_getfs.gd32_path,
3767 (NFS_MAXPATHLEN+1));
3768 err |= __get_user(karg->ca_getfs.gd_maxlen,
3769 &arg32->ca32_getfs.gd32_maxlen);
3770 return err;
3773 /* This really doesn't need translations, we are only passing
3774 * back a union which contains opaque nfs file handle data.
3776 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3778 return copy_to_user(res32, kres, sizeof(*res32));
3781 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3783 struct nfsctl_arg *karg = NULL;
3784 union nfsctl_res *kres = NULL;
3785 mm_segment_t oldfs;
3786 int err;
3788 karg = kmalloc(sizeof(*karg), GFP_USER);
3789 if(!karg)
3790 return -ENOMEM;
3791 if(res32) {
3792 kres = kmalloc(sizeof(*kres), GFP_USER);
3793 if(!kres) {
3794 kfree(karg);
3795 return -ENOMEM;
3798 switch(cmd) {
3799 case NFSCTL_SVC:
3800 err = nfs_svc32_trans(karg, arg32);
3801 break;
3802 case NFSCTL_ADDCLIENT:
3803 err = nfs_clnt32_trans(karg, arg32);
3804 break;
3805 case NFSCTL_DELCLIENT:
3806 err = nfs_clnt32_trans(karg, arg32);
3807 break;
3808 case NFSCTL_EXPORT:
3809 case NFSCTL_UNEXPORT:
3810 err = nfs_exp32_trans(karg, arg32);
3811 break;
3812 /* This one is unimplemented, be we're ready for it. */
3813 case NFSCTL_UGIDUPDATE:
3814 err = nfs_uud32_trans(karg, arg32);
3815 break;
3816 case NFSCTL_GETFH:
3817 err = nfs_getfh32_trans(karg, arg32);
3818 break;
3819 case NFSCTL_GETFD:
3820 err = nfs_getfd32_trans(karg, arg32);
3821 break;
3822 case NFSCTL_GETFS:
3823 err = nfs_getfs32_trans(karg, arg32);
3824 break;
3825 default:
3826 err = -EINVAL;
3827 break;
3829 if(err)
3830 goto done;
3831 oldfs = get_fs();
3832 set_fs(KERNEL_DS);
3833 err = sys_nfsservctl(cmd, karg, kres);
3834 set_fs(oldfs);
3836 if (err)
3837 goto done;
3839 if((cmd == NFSCTL_GETFH) ||
3840 (cmd == NFSCTL_GETFD) ||
3841 (cmd == NFSCTL_GETFS))
3842 err = nfs_getfh32_res_trans(kres, res32);
3844 done:
3845 if(karg) {
3846 if(cmd == NFSCTL_UGIDUPDATE) {
3847 if(karg->ca_umap.ug_ident)
3848 kfree(karg->ca_umap.ug_ident);
3849 if(karg->ca_umap.ug_udimap)
3850 kfree(karg->ca_umap.ug_udimap);
3851 if(karg->ca_umap.ug_gdimap)
3852 kfree(karg->ca_umap.ug_gdimap);
3854 kfree(karg);
3856 if(kres)
3857 kfree(kres);
3858 return err;
3861 /* Translations due to time_t size differences. Which affects all
3862 sorts of things, like timeval and itimerval. */
3864 extern struct timezone sys_tz;
3865 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3867 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3869 if (tv) {
3870 struct timeval ktv;
3871 do_gettimeofday(&ktv);
3872 if (put_tv32(tv, &ktv))
3873 return -EFAULT;
3875 if (tz) {
3876 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3877 return -EFAULT;
3879 return 0;
3882 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3884 struct timeval ktv;
3885 struct timezone ktz;
3887 if (tv) {
3888 if (get_tv32(&ktv, tv))
3889 return -EFAULT;
3891 if (tz) {
3892 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3893 return -EFAULT;
3896 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3899 extern int do_getitimer(int which, struct itimerval *value);
3901 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3903 struct itimerval kit;
3904 int error;
3906 error = do_getitimer(which, &kit);
3907 if (!error && put_it32(it, &kit))
3908 error = -EFAULT;
3910 return error;
3913 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3915 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3917 struct itimerval kin, kout;
3918 int error;
3920 if (in) {
3921 if (get_it32(&kin, in))
3922 return -EFAULT;
3923 } else
3924 memset(&kin, 0, sizeof(kin));
3926 error = do_setitimer(which, &kin, out ? &kout : NULL);
3927 if (error || !out)
3928 return error;
3929 if (put_it32(out, &kout))
3930 return -EFAULT;
3932 return 0;
3936 asmlinkage int sys_utimes(char *, struct timeval *);
3938 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3940 char *kfilename;
3941 struct timeval ktvs[2];
3942 mm_segment_t old_fs;
3943 int ret;
3945 kfilename = getname32(filename);
3946 ret = PTR_ERR(kfilename);
3947 if (!IS_ERR(kfilename)) {
3948 if (tvs) {
3949 if (get_tv32(&ktvs[0], tvs) ||
3950 get_tv32(&ktvs[1], 1+tvs))
3951 return -EFAULT;
3954 old_fs = get_fs();
3955 set_fs(KERNEL_DS);
3956 ret = sys_utimes(kfilename, &ktvs[0]);
3957 set_fs(old_fs);
3959 putname(kfilename);
3961 return ret;
3964 /* These are here just in case some old sparc32 binary calls it. */
3965 asmlinkage int sys32_pause(void)
3967 current->state = TASK_INTERRUPTIBLE;
3968 schedule();
3969 return -ERESTARTNOHAND;
3972 /* PCI config space poking. */
3973 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3974 unsigned long dfn,
3975 unsigned long off,
3976 unsigned long len,
3977 unsigned char *buf);
3979 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3980 unsigned long dfn,
3981 unsigned long off,
3982 unsigned long len,
3983 unsigned char *buf);
3985 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3987 return sys_pciconfig_read((unsigned long) bus,
3988 (unsigned long) dfn,
3989 (unsigned long) off,
3990 (unsigned long) len,
3991 (unsigned char *)AA(ubuf));
3994 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3996 return sys_pciconfig_write((unsigned long) bus,
3997 (unsigned long) dfn,
3998 (unsigned long) off,
3999 (unsigned long) len,
4000 (unsigned char *)AA(ubuf));
4003 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
4004 unsigned long arg4, unsigned long arg5);
4006 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
4008 return sys_prctl(option,
4009 (unsigned long) arg2,
4010 (unsigned long) arg3,
4011 (unsigned long) arg4,
4012 (unsigned long) arg5);
4016 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4017 size_t count, loff_t pos);
4019 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4020 size_t count, loff_t pos);
4022 typedef __kernel_ssize_t32 ssize_t32;
4024 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
4025 __kernel_size_t32 count, u32 poshi, u32 poslo)
4027 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4030 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
4031 __kernel_size_t32 count, u32 poshi, u32 poslo)
4033 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4037 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4039 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4041 mm_segment_t old_fs = get_fs();
4042 int ret;
4043 off_t of;
4045 if (offset && get_user(of, offset))
4046 return -EFAULT;
4048 set_fs(KERNEL_DS);
4049 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4050 set_fs(old_fs);
4052 if (!ret && offset && put_user(of, offset))
4053 return -EFAULT;
4055 return ret;
4058 /* Handle adjtimex compatability. */
4060 struct timex32 {
4061 u32 modes;
4062 s32 offset, freq, maxerror, esterror;
4063 s32 status, constant, precision, tolerance;
4064 struct timeval32 time;
4065 s32 tick;
4066 s32 ppsfreq, jitter, shift, stabil;
4067 s32 jitcnt, calcnt, errcnt, stbcnt;
4068 s32 :32; s32 :32; s32 :32; s32 :32;
4069 s32 :32; s32 :32; s32 :32; s32 :32;
4070 s32 :32; s32 :32; s32 :32; s32 :32;
4073 extern int do_adjtimex(struct timex *);
4075 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4077 struct timex txc;
4078 int ret;
4080 memset(&txc, 0, sizeof(struct timex));
4082 if(get_user(txc.modes, &utp->modes) ||
4083 __get_user(txc.offset, &utp->offset) ||
4084 __get_user(txc.freq, &utp->freq) ||
4085 __get_user(txc.maxerror, &utp->maxerror) ||
4086 __get_user(txc.esterror, &utp->esterror) ||
4087 __get_user(txc.status, &utp->status) ||
4088 __get_user(txc.constant, &utp->constant) ||
4089 __get_user(txc.precision, &utp->precision) ||
4090 __get_user(txc.tolerance, &utp->tolerance) ||
4091 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4092 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4093 __get_user(txc.tick, &utp->tick) ||
4094 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4095 __get_user(txc.jitter, &utp->jitter) ||
4096 __get_user(txc.shift, &utp->shift) ||
4097 __get_user(txc.stabil, &utp->stabil) ||
4098 __get_user(txc.jitcnt, &utp->jitcnt) ||
4099 __get_user(txc.calcnt, &utp->calcnt) ||
4100 __get_user(txc.errcnt, &utp->errcnt) ||
4101 __get_user(txc.stbcnt, &utp->stbcnt))
4102 return -EFAULT;
4104 ret = do_adjtimex(&txc);
4106 if(put_user(txc.modes, &utp->modes) ||
4107 __put_user(txc.offset, &utp->offset) ||
4108 __put_user(txc.freq, &utp->freq) ||
4109 __put_user(txc.maxerror, &utp->maxerror) ||
4110 __put_user(txc.esterror, &utp->esterror) ||
4111 __put_user(txc.status, &utp->status) ||
4112 __put_user(txc.constant, &utp->constant) ||
4113 __put_user(txc.precision, &utp->precision) ||
4114 __put_user(txc.tolerance, &utp->tolerance) ||
4115 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4116 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4117 __put_user(txc.tick, &utp->tick) ||
4118 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4119 __put_user(txc.jitter, &utp->jitter) ||
4120 __put_user(txc.shift, &utp->shift) ||
4121 __put_user(txc.stabil, &utp->stabil) ||
4122 __put_user(txc.jitcnt, &utp->jitcnt) ||
4123 __put_user(txc.calcnt, &utp->calcnt) ||
4124 __put_user(txc.errcnt, &utp->errcnt) ||
4125 __put_user(txc.stbcnt, &utp->stbcnt))
4126 ret = -EFAULT;
4128 return ret;
4131 /* This is just a version for 32-bit applications which does
4132 * not force O_LARGEFILE on.
4135 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4137 char * tmp;
4138 int fd, error;
4140 tmp = getname(filename);
4141 fd = PTR_ERR(tmp);
4142 if (!IS_ERR(tmp)) {
4143 fd = get_unused_fd();
4144 if (fd >= 0) {
4145 struct file * f;
4146 lock_kernel();
4147 f = filp_open(tmp, flags, mode);
4148 unlock_kernel();
4149 error = PTR_ERR(f);
4150 if (IS_ERR(f))
4151 goto out_error;
4152 fd_install(fd, f);
4154 out:
4155 putname(tmp);
4157 return fd;
4159 out_error:
4160 put_unused_fd(fd);
4161 fd = error;
4162 goto out;
4165 extern unsigned long do_mremap(unsigned long addr,
4166 unsigned long old_len, unsigned long new_len,
4167 unsigned long flags, unsigned long new_addr);
4169 asmlinkage unsigned long sys32_mremap(unsigned long addr,
4170 unsigned long old_len, unsigned long new_len,
4171 unsigned long flags, u32 __new_addr)
4173 unsigned long ret = -EINVAL;
4174 unsigned long new_addr = AA(__new_addr);
4176 if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)
4177 goto out;
4178 if (addr > 0xf0000000UL - old_len)
4179 goto out;
4180 down(&current->mm->mmap_sem);
4181 if (flags & MREMAP_FIXED) {
4182 if (new_addr > 0xf0000000UL - new_len)
4183 goto out_sem;
4184 } else if (addr > 0xf0000000UL - new_len) {
4185 ret = -ENOMEM;
4186 if (!(flags & MREMAP_MAYMOVE))
4187 goto out_sem;
4188 new_addr = get_unmapped_area (addr, new_len);
4189 if (!new_addr)
4190 goto out_sem;
4191 flags |= MREMAP_FIXED;
4193 ret = do_mremap(addr, old_len, new_len, flags, new_addr);
4194 out_sem:
4195 up(&current->mm->mmap_sem);
4196 out:
4197 return ret;