Merge with Linux 2.3.40.
[linux-2.6/linux-mips.git] / arch / sparc64 / kernel / sys_sparc32.c
blob4083680603df97b590f19fe67ff931c35651116f
1 /* $Id: sys_sparc32.c,v 1.130 2000/01/14 09:40:07 jj 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>
48 #include <asm/types.h>
49 #include <asm/ipc.h>
50 #include <asm/uaccess.h>
51 #include <asm/fpumacro.h>
52 #include <asm/semaphore.h>
54 #include <net/scm.h>
56 /* Use this to get at 32-bit user passed pointers. */
57 /* Things to consider: the low-level assembly stub does
58 srl x, 0, x for first four arguments, so if you have
59 pointer to something in the first four arguments, just
60 declare it as a pointer, not u32. On the other side,
61 arguments from 5th onwards should be declared as u32
62 for pointers, and need AA() around each usage.
63 A() macro should be used for places where you e.g.
64 have some internal variable u32 and just want to get
65 rid of a compiler warning. AA() has to be used in
66 places where you want to convert a function argument
67 to 32bit pointer or when you e.g. access pt_regs
68 structure and want to consider 32bit registers only.
69 -jj
71 #define A(__x) ((unsigned long)(__x))
72 #define AA(__x) \
73 ({ unsigned long __ret; \
74 __asm__ ("srl %0, 0, %0" \
75 : "=r" (__ret) \
76 : "0" (__x)); \
77 __ret; \
80 extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
81 extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
82 extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
83 extern asmlinkage long sys_setregid(gid_t, gid_t);
84 extern asmlinkage long sys_setgid(gid_t);
85 extern asmlinkage long sys_setreuid(uid_t, uid_t);
86 extern asmlinkage long sys_setuid(uid_t);
87 extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
88 extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
89 extern asmlinkage long sys_setfsuid(uid_t);
90 extern asmlinkage long sys_setfsgid(gid_t);
92 /* For this source file, we want overflow handling. */
94 #undef high2lowuid
95 #undef high2lowgid
96 #undef low2highuid
97 #undef low2highgid
98 #undef SET_UID16
99 #undef SET_GID16
100 #undef NEW_TO_OLD_UID
101 #undef NEW_TO_OLD_GID
102 #undef SET_OLDSTAT_UID
103 #undef SET_OLDSTAT_GID
104 #undef SET_STAT_UID
105 #undef SET_STAT_GID
107 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
108 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
109 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
110 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
111 #define SET_UID16(var, uid) var = high2lowuid(uid)
112 #define SET_GID16(var, gid) var = high2lowgid(gid)
113 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
114 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
115 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
116 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
117 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
118 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
120 asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
122 return sys_chown(filename, low2highuid(user), low2highgid(group));
125 asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
127 return sys_lchown(filename, low2highuid(user), low2highgid(group));
130 asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
132 return sys_fchown(fd, low2highuid(user), low2highgid(group));
135 asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
137 return sys_setregid(low2highgid(rgid), low2highgid(egid));
140 asmlinkage long sys32_setgid16(u16 gid)
142 return sys_setgid((gid_t)gid);
145 asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
147 return sys_setreuid(low2highuid(ruid), low2highuid(euid));
150 asmlinkage long sys32_setuid16(u16 uid)
152 return sys_setuid((uid_t)uid);
155 asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
157 return sys_setresuid(low2highuid(ruid), low2highuid(euid),
158 low2highuid(suid));
161 asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
163 int retval;
165 if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
166 !(retval = put_user(high2lowuid(current->euid), euid)))
167 retval = put_user(high2lowuid(current->suid), suid);
169 return retval;
172 asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
174 return sys_setresgid(low2highgid(rgid), low2highgid(egid),
175 low2highgid(sgid));
178 asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
180 int retval;
182 if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
183 !(retval = put_user(high2lowgid(current->egid), egid)))
184 retval = put_user(high2lowgid(current->sgid), sgid);
186 return retval;
189 asmlinkage long sys32_setfsuid16(u16 uid)
191 return sys_setfsuid((uid_t)uid);
194 asmlinkage long sys32_setfsgid16(u16 gid)
196 return sys_setfsgid((gid_t)gid);
199 asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
201 u16 groups[NGROUPS];
202 int i,j;
204 if (gidsetsize < 0)
205 return -EINVAL;
206 i = current->ngroups;
207 if (gidsetsize) {
208 if (i > gidsetsize)
209 return -EINVAL;
210 for(j=0;j<i;j++)
211 groups[j] = current->groups[j];
212 if (copy_to_user(grouplist, groups, sizeof(u16)*i))
213 return -EFAULT;
215 return i;
218 asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
220 u16 groups[NGROUPS];
221 int i;
223 if (!capable(CAP_SETGID))
224 return -EPERM;
225 if ((unsigned) gidsetsize > NGROUPS)
226 return -EINVAL;
227 if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
228 return -EFAULT;
229 for (i = 0 ; i < gidsetsize ; i++)
230 current->groups[i] = (gid_t)groups[i];
231 current->ngroups = gidsetsize;
232 return 0;
235 asmlinkage long sys32_getuid16(void)
237 return high2lowuid(current->uid);
240 asmlinkage long sys32_geteuid16(void)
242 return high2lowuid(current->euid);
245 asmlinkage long sys32_getgid16(void)
247 return high2lowgid(current->gid);
250 asmlinkage long sys32_getegid16(void)
252 return high2lowgid(current->egid);
255 /* In order to reduce some races, while at the same time doing additional
256 * checking and hopefully speeding things up, we copy filenames to the
257 * kernel data space before using them..
259 * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
261 static inline int do_getname32(const char *filename, char *page)
263 int retval;
265 /* 32bit pointer will be always far below TASK_SIZE :)) */
266 retval = strncpy_from_user((char *)page, (char *)filename, PAGE_SIZE);
267 if (retval > 0) {
268 if (retval < PAGE_SIZE)
269 return 0;
270 return -ENAMETOOLONG;
271 } else if (!retval)
272 retval = -ENOENT;
273 return retval;
276 char * getname32(const char *filename)
278 char *tmp, *result;
280 result = ERR_PTR(-ENOMEM);
281 tmp = (char *)__get_free_page(GFP_KERNEL);
282 if (tmp) {
283 int retval = do_getname32(filename, tmp);
285 result = tmp;
286 if (retval < 0) {
287 putname(tmp);
288 result = ERR_PTR(retval);
291 return result;
294 /* 32-bit timeval and related flotsam. */
296 struct timeval32
298 int tv_sec, tv_usec;
301 struct itimerval32
303 struct timeval32 it_interval;
304 struct timeval32 it_value;
307 static inline long get_tv32(struct timeval *o, struct timeval32 *i)
309 return (!access_ok(VERIFY_READ, tv32, sizeof(*tv32)) ||
310 (__get_user(o->tv_sec, &i->tv_sec) |
311 __get_user(o->tv_usec, &i->tv_usec)));
314 static inline long put_tv32(struct timeval32 *o, struct timeval *i)
316 return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
317 (__put_user(i->tv_sec, &o->tv_sec) |
318 __put_user(i->tv_usec, &o->tv_usec)));
321 static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
323 return (!access_ok(VERIFY_READ, i32, sizeof(*i32)) ||
324 (__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
325 __get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) |
326 __get_user(o->it_value.tv_sec, &i->it_value.tv_sec) |
327 __get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
330 static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
332 return (!access_ok(VERIFY_WRITE, i32, sizeof(*i32)) ||
333 (__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
334 __put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) |
335 __put_user(i->it_value.tv_sec, &o->it_value.tv_sec) |
336 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
339 extern asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
341 asmlinkage int sys32_ioperm(u32 from, u32 num, int on)
343 return sys_ioperm((unsigned long)from, (unsigned long)num, on);
346 struct msgbuf32 { s32 mtype; char mtext[1]; };
348 struct ipc_perm32
350 key_t key;
351 __kernel_uid_t32 uid;
352 __kernel_gid_t32 gid;
353 __kernel_uid_t32 cuid;
354 __kernel_gid_t32 cgid;
355 __kernel_mode_t32 mode;
356 unsigned short seq;
359 struct semid_ds32 {
360 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
361 __kernel_time_t32 sem_otime; /* last semop time */
362 __kernel_time_t32 sem_ctime; /* last change time */
363 u32 sem_base; /* ptr to first semaphore in array */
364 u32 sem_pending; /* pending operations to be processed */
365 u32 sem_pending_last; /* last pending operation */
366 u32 undo; /* undo requests on this array */
367 unsigned short sem_nsems; /* no. of semaphores in array */
370 struct semid64_ds32 {
371 struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
372 unsigned int __pad1;
373 __kernel_time_t32 sem_otime;
374 unsigned int __pad2;
375 __kernel_time_t32 sem_ctime;
376 u32 sem_nsems;
377 u32 __unused1;
378 u32 __unused2;
381 struct msqid_ds32
383 struct ipc_perm32 msg_perm;
384 u32 msg_first;
385 u32 msg_last;
386 __kernel_time_t32 msg_stime;
387 __kernel_time_t32 msg_rtime;
388 __kernel_time_t32 msg_ctime;
389 u32 wwait;
390 u32 rwait;
391 unsigned short msg_cbytes;
392 unsigned short msg_qnum;
393 unsigned short msg_qbytes;
394 __kernel_ipc_pid_t32 msg_lspid;
395 __kernel_ipc_pid_t32 msg_lrpid;
398 struct msqid64_ds32 {
399 struct ipc64_perm msg_perm;
400 unsigned int __pad1;
401 __kernel_time_t32 msg_stime;
402 unsigned int __pad2;
403 __kernel_time_t32 msg_rtime;
404 unsigned int __pad3;
405 __kernel_time_t32 msg_ctime;
406 unsigned int msg_cbytes;
407 unsigned int msg_qnum;
408 unsigned int msg_qbytes;
409 __kernel_pid_t32 msg_lspid;
410 __kernel_pid_t32 msg_lrpid;
411 unsigned int __unused1;
412 unsigned int __unused2;
416 struct shmid_ds32 {
417 struct ipc_perm32 shm_perm;
418 int shm_segsz;
419 __kernel_time_t32 shm_atime;
420 __kernel_time_t32 shm_dtime;
421 __kernel_time_t32 shm_ctime;
422 __kernel_ipc_pid_t32 shm_cpid;
423 __kernel_ipc_pid_t32 shm_lpid;
424 unsigned short shm_nattch;
427 struct shmid64_ds32 {
428 struct ipc64_perm shm_perm;
429 unsigned int __pad1;
430 __kernel_time_t32 shm_atime;
431 unsigned int __pad2;
432 __kernel_time_t32 shm_dtime;
433 unsigned int __pad3;
434 __kernel_time_t32 shm_ctime;
435 __kernel_size_t32 shm_segsz;
436 __kernel_pid_t32 shm_cpid;
437 __kernel_pid_t32 shm_lpid;
438 unsigned int shm_nattch;
439 unsigned int __unused1;
440 unsigned int __unused2;
445 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
447 * This is really horribly ugly.
449 #define IPCOP_MASK(__x) (1UL << (__x))
450 static int do_sys32_semctl(int first, int second, int third, void *uptr)
452 union semun fourth;
453 u32 pad;
454 int err = -EINVAL;
456 if (!uptr)
457 goto out;
458 err = -EFAULT;
459 if (get_user (pad, (u32 *)uptr))
460 goto out;
461 if(third == SETVAL)
462 fourth.val = (int)pad;
463 else
464 fourth.__pad = (void *)A(pad);
465 if (IPCOP_MASK (third) &
466 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SEM_INFO) | IPCOP_MASK (GETVAL) |
467 IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
468 IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
469 err = sys_semctl (first, second, third, fourth);
470 } else if (third & IPC_64) {
471 struct semid64_ds s;
472 struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
473 mm_segment_t old_fs;
474 int need_back_translation;
476 if (third == (IPC_SET|IPC_64)) {
477 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
478 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
479 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
480 if (err)
481 goto out;
482 fourth.__pad = &s;
484 need_back_translation =
485 (IPCOP_MASK (third) &
486 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
487 if (need_back_translation)
488 fourth.__pad = &s;
489 old_fs = get_fs ();
490 set_fs (KERNEL_DS);
491 err = sys_semctl (first, second, third, fourth);
492 set_fs (old_fs);
493 if (need_back_translation) {
494 int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
495 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
496 if (err2) err = -EFAULT;
498 } else {
499 struct semid_ds s;
500 struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
501 mm_segment_t old_fs;
502 int need_back_translation;
504 if (third == IPC_SET) {
505 err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
506 err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
507 err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
508 if (err)
509 goto out;
510 fourth.__pad = &s;
512 need_back_translation =
513 (IPCOP_MASK (third) &
514 (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
515 if (need_back_translation)
516 fourth.__pad = &s;
517 old_fs = get_fs ();
518 set_fs (KERNEL_DS);
519 err = sys_semctl (first, second, third, fourth);
520 set_fs (old_fs);
521 if (need_back_translation) {
522 int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
523 err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
524 err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
525 err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
526 err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
527 err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
528 err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
529 err2 |= __put_user (s.sem_otime, &usp->sem_otime);
530 err2 |= __put_user (s.sem_ctime, &usp->sem_ctime);
531 err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
532 if (err2) err = -EFAULT;
535 out:
536 return err;
539 static int do_sys32_msgsnd (int first, int second, int third, void *uptr)
541 struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
542 struct msgbuf32 *up = (struct msgbuf32 *)uptr;
543 mm_segment_t old_fs;
544 int err;
546 if (!p)
547 return -ENOMEM;
548 err = get_user (p->mtype, &up->mtype);
549 err |= __copy_from_user (p->mtext, &up->mtext, second);
550 if (err)
551 goto out;
552 old_fs = get_fs ();
553 set_fs (KERNEL_DS);
554 err = sys_msgsnd (first, p, second, third);
555 set_fs (old_fs);
556 out:
557 kfree (p);
558 return err;
561 static int do_sys32_msgrcv (int first, int second, int msgtyp, int third,
562 int version, void *uptr)
564 struct msgbuf32 *up;
565 struct msgbuf *p;
566 mm_segment_t old_fs;
567 int err;
569 if (!version) {
570 struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
571 struct ipc_kludge ipck;
573 err = -EINVAL;
574 if (!uptr)
575 goto out;
576 err = -EFAULT;
577 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
578 goto out;
579 uptr = (void *)A(ipck.msgp);
580 msgtyp = ipck.msgtyp;
582 err = -ENOMEM;
583 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
584 if (!p)
585 goto out;
586 old_fs = get_fs ();
587 set_fs (KERNEL_DS);
588 err = sys_msgrcv (first, p, second + 4, msgtyp, third);
589 set_fs (old_fs);
590 if (err < 0)
591 goto free_then_out;
592 up = (struct msgbuf32 *)uptr;
593 if (put_user (p->mtype, &up->mtype) ||
594 __copy_to_user (&up->mtext, p->mtext, err))
595 err = -EFAULT;
596 free_then_out:
597 kfree (p);
598 out:
599 return err;
602 static int do_sys32_msgctl (int first, int second, void *uptr)
604 int err;
606 if (IPCOP_MASK (second) &
607 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
608 IPCOP_MASK (IPC_RMID))) {
609 err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
610 } else if (second & IPC_64) {
611 struct msqid64_ds m;
612 struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
613 mm_segment_t old_fs;
615 if (second == (IPC_SET|IPC_64)) {
616 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
617 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
618 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
619 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
620 if (err)
621 goto out;
623 old_fs = get_fs ();
624 set_fs (KERNEL_DS);
625 err = sys_msgctl (first, second, (struct msqid_ds *)&m);
626 set_fs (old_fs);
627 if (IPCOP_MASK (second) &
628 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
629 int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
630 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
631 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
632 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
633 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
634 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
635 if (err2)
636 err = -EFAULT;
638 } else {
639 struct msqid_ds m;
640 struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
641 mm_segment_t old_fs;
643 if (second == IPC_SET) {
644 err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
645 err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
646 err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
647 err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
648 if (err)
649 goto out;
651 old_fs = get_fs ();
652 set_fs (KERNEL_DS);
653 err = sys_msgctl (first, second, &m);
654 set_fs (old_fs);
655 if (IPCOP_MASK (second) &
656 (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
657 int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
658 err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
659 err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
660 err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
661 err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
662 err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
663 err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
664 err2 |= __put_user (m.msg_stime, &up->msg_stime);
665 err2 |= __put_user (m.msg_rtime, &up->msg_rtime);
666 err2 |= __put_user (m.msg_ctime, &up->msg_ctime);
667 err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
668 err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
669 err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
670 err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
671 err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
672 if (err2)
673 err = -EFAULT;
677 out:
678 return err;
681 static int do_sys32_shmat (int first, int second, int third, int version, void *uptr)
683 unsigned long raddr;
684 u32 *uaddr = (u32 *)A((u32)third);
685 int err = -EINVAL;
687 if (version == 1)
688 goto out;
689 err = sys_shmat (first, uptr, second, &raddr);
690 if (err)
691 goto out;
692 err = put_user (raddr, uaddr);
693 out:
694 return err;
697 static int do_sys32_shmctl (int first, int second, void *uptr)
699 int err;
701 if (IPCOP_MASK (second) &
702 (IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
703 IPCOP_MASK (IPC_RMID))) {
704 if (second == (IPC_INFO|IPC_64))
705 second = IPC_INFO; /* So that we don't have to translate it */
706 err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
707 } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
708 struct shmid64_ds s;
709 struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
710 mm_segment_t old_fs;
712 if (second == (IPC_SET|IPC_64)) {
713 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
714 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
715 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
716 if (err)
717 goto out;
719 old_fs = get_fs ();
720 set_fs (KERNEL_DS);
721 err = sys_shmctl (first, second, (struct shmid_ds *)&s);
722 set_fs (old_fs);
723 if (err < 0)
724 goto out;
726 /* Mask it even in this case so it becomes a CSE. */
727 if (IPCOP_MASK (second) &
728 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
729 int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
730 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
731 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
732 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
733 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
734 if (err2)
735 err = -EFAULT;
737 } else {
738 struct shmid_ds s;
739 struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
740 mm_segment_t old_fs;
742 second &= ~IPC_64;
743 if (second == IPC_SET) {
744 err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
745 err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
746 err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
747 if (err)
748 goto out;
750 old_fs = get_fs ();
751 set_fs (KERNEL_DS);
752 err = sys_shmctl (first, second, &s);
753 set_fs (old_fs);
754 if (err < 0)
755 goto out;
757 /* Mask it even in this case so it becomes a CSE. */
758 if (second == SHM_INFO) {
759 struct shm_info32 {
760 int used_ids;
761 u32 shm_tot, shm_rss, shm_swp;
762 u32 swap_attempts, swap_successes;
763 } *uip = (struct shm_info32 *)uptr;
764 struct shm_info *kp = (struct shm_info *)&s;
765 int err2 = put_user (kp->used_ids, &uip->used_ids);
766 err2 |= __put_user (kp->shm_tot, &uip->shm_tot);
767 err2 |= __put_user (kp->shm_rss, &uip->shm_rss);
768 err2 |= __put_user (kp->shm_swp, &uip->shm_swp);
769 err2 |= __put_user (kp->swap_attempts, &uip->swap_attempts);
770 err2 |= __put_user (kp->swap_successes, &uip->swap_successes);
771 if (err2)
772 err = -EFAULT;
773 } else if (IPCOP_MASK (second) &
774 (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
775 int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
776 err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
777 err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
778 err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
779 err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
780 err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
781 err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
782 err2 |= __put_user (s.shm_atime, &up->shm_atime);
783 err2 |= __put_user (s.shm_dtime, &up->shm_dtime);
784 err2 |= __put_user (s.shm_ctime, &up->shm_ctime);
785 err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
786 err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
787 err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
788 err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
789 if (err2)
790 err = -EFAULT;
793 out:
794 return err;
797 asmlinkage int sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
799 int version, err;
801 lock_kernel();
802 version = call >> 16; /* hack for backward compatibility */
803 call &= 0xffff;
805 if (call <= SEMCTL)
806 switch (call) {
807 case SEMOP:
808 /* struct sembuf is the same on 32 and 64bit :)) */
809 err = sys_semop (first, (struct sembuf *)AA(ptr), second);
810 goto out;
811 case SEMGET:
812 err = sys_semget (first, second, third);
813 goto out;
814 case SEMCTL:
815 err = do_sys32_semctl (first, second, third, (void *)AA(ptr));
816 goto out;
817 default:
818 err = -EINVAL;
819 goto out;
821 if (call <= MSGCTL)
822 switch (call) {
823 case MSGSND:
824 err = do_sys32_msgsnd (first, second, third, (void *)AA(ptr));
825 goto out;
826 case MSGRCV:
827 err = do_sys32_msgrcv (first, second, fifth, third,
828 version, (void *)AA(ptr));
829 goto out;
830 case MSGGET:
831 err = sys_msgget ((key_t) first, second);
832 goto out;
833 case MSGCTL:
834 err = do_sys32_msgctl (first, second, (void *)AA(ptr));
835 goto out;
836 default:
837 err = -EINVAL;
838 goto out;
840 if (call <= SHMCTL)
841 switch (call) {
842 case SHMAT:
843 err = do_sys32_shmat (first, second, third,
844 version, (void *)AA(ptr));
845 goto out;
846 case SHMDT:
847 err = sys_shmdt ((char *)AA(ptr));
848 goto out;
849 case SHMGET:
850 err = sys_shmget (first, second, third);
851 goto out;
852 case SHMCTL:
853 err = do_sys32_shmctl (first, second, (void *)AA(ptr));
854 goto out;
855 default:
856 err = -EINVAL;
857 goto out;
860 err = -EINVAL;
862 out:
863 unlock_kernel();
864 return err;
867 static inline int get_flock(struct flock *kfl, struct flock32 *ufl)
869 int err;
871 err = get_user(kfl->l_type, &ufl->l_type);
872 err |= __get_user(kfl->l_whence, &ufl->l_whence);
873 err |= __get_user(kfl->l_start, &ufl->l_start);
874 err |= __get_user(kfl->l_len, &ufl->l_len);
875 err |= __get_user(kfl->l_pid, &ufl->l_pid);
876 return err;
879 static inline int put_flock(struct flock *kfl, struct flock32 *ufl)
881 int err;
883 err = __put_user(kfl->l_type, &ufl->l_type);
884 err |= __put_user(kfl->l_whence, &ufl->l_whence);
885 err |= __put_user(kfl->l_start, &ufl->l_start);
886 err |= __put_user(kfl->l_len, &ufl->l_len);
887 err |= __put_user(kfl->l_pid, &ufl->l_pid);
888 return err;
891 extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);
893 asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
895 switch (cmd) {
896 case F_GETLK:
897 case F_SETLK:
898 case F_SETLKW:
900 struct flock f;
901 mm_segment_t old_fs;
902 long ret;
904 if(get_flock(&f, (struct flock32 *)arg))
905 return -EFAULT;
906 old_fs = get_fs(); set_fs (KERNEL_DS);
907 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
908 set_fs (old_fs);
909 if(put_flock(&f, (struct flock32 *)arg))
910 return -EFAULT;
911 return ret;
913 default:
914 return sys_fcntl(fd, cmd, (unsigned long)arg);
918 struct dqblk32 {
919 __u32 dqb_bhardlimit;
920 __u32 dqb_bsoftlimit;
921 __u32 dqb_curblocks;
922 __u32 dqb_ihardlimit;
923 __u32 dqb_isoftlimit;
924 __u32 dqb_curinodes;
925 __kernel_time_t32 dqb_btime;
926 __kernel_time_t32 dqb_itime;
929 extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
931 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
933 int cmds = cmd >> SUBCMDSHIFT;
934 int err;
935 struct dqblk d;
936 mm_segment_t old_fs;
937 char *spec;
939 switch (cmds) {
940 case Q_GETQUOTA:
941 break;
942 case Q_SETQUOTA:
943 case Q_SETUSE:
944 case Q_SETQLIM:
945 if (copy_from_user (&d, (struct dqblk32 *)addr,
946 sizeof (struct dqblk32)))
947 return -EFAULT;
948 d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
949 d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
950 break;
951 default:
952 return sys_quotactl(cmd, special,
953 id, (caddr_t)addr);
955 spec = getname32 (special);
956 err = PTR_ERR(spec);
957 if (IS_ERR(spec)) return err;
958 old_fs = get_fs ();
959 set_fs (KERNEL_DS);
960 err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
961 set_fs (old_fs);
962 putname (spec);
963 if (cmds == Q_GETQUOTA) {
964 __kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
965 ((struct dqblk32 *)&d)->dqb_itime = i;
966 ((struct dqblk32 *)&d)->dqb_btime = b;
967 if (copy_to_user ((struct dqblk32 *)addr, &d,
968 sizeof (struct dqblk32)))
969 return -EFAULT;
971 return err;
974 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
976 int err;
978 err = put_user (kbuf->f_type, &ubuf->f_type);
979 err |= __put_user (kbuf->f_bsize, &ubuf->f_bsize);
980 err |= __put_user (kbuf->f_blocks, &ubuf->f_blocks);
981 err |= __put_user (kbuf->f_bfree, &ubuf->f_bfree);
982 err |= __put_user (kbuf->f_bavail, &ubuf->f_bavail);
983 err |= __put_user (kbuf->f_files, &ubuf->f_files);
984 err |= __put_user (kbuf->f_ffree, &ubuf->f_ffree);
985 err |= __put_user (kbuf->f_namelen, &ubuf->f_namelen);
986 err |= __put_user (kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]);
987 err |= __put_user (kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]);
988 return err;
991 extern asmlinkage int sys_statfs(const char * path, struct statfs * buf);
993 asmlinkage int sys32_statfs(const char * path, struct statfs32 *buf)
995 int ret;
996 struct statfs s;
997 mm_segment_t old_fs = get_fs();
998 char *pth;
1000 pth = getname32 (path);
1001 ret = PTR_ERR(pth);
1002 if (!IS_ERR(pth)) {
1003 set_fs (KERNEL_DS);
1004 ret = sys_statfs((const char *)pth, &s);
1005 set_fs (old_fs);
1006 putname (pth);
1007 if (put_statfs(buf, &s))
1008 return -EFAULT;
1010 return ret;
1013 extern asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf);
1015 asmlinkage int sys32_fstatfs(unsigned int fd, struct statfs32 *buf)
1017 int ret;
1018 struct statfs s;
1019 mm_segment_t old_fs = get_fs();
1021 set_fs (KERNEL_DS);
1022 ret = sys_fstatfs(fd, &s);
1023 set_fs (old_fs);
1024 if (put_statfs(buf, &s))
1025 return -EFAULT;
1026 return ret;
1029 extern asmlinkage long sys_truncate(const char * path, unsigned long length);
1030 extern asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
1032 asmlinkage int sys32_truncate64(const char * path, unsigned long high, unsigned long low)
1034 if ((int)high < 0)
1035 return -EINVAL;
1036 else
1037 return sys_truncate(path, (high << 32) | low);
1040 asmlinkage int sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low)
1042 if ((int)high < 0)
1043 return -EINVAL;
1044 else
1045 return sys_ftruncate(fd, (high << 32) | low);
1048 extern asmlinkage int sys_utime(char * filename, struct utimbuf * times);
1050 struct utimbuf32 {
1051 __kernel_time_t32 actime, modtime;
1054 asmlinkage int sys32_utime(char * filename, struct utimbuf32 *times)
1056 struct utimbuf t;
1057 mm_segment_t old_fs;
1058 int ret;
1059 char *filenam;
1061 if (!times)
1062 return sys_utime(filename, NULL);
1063 if (get_user (t.actime, &times->actime) ||
1064 __get_user (t.modtime, &times->modtime))
1065 return -EFAULT;
1066 filenam = getname32 (filename);
1067 ret = PTR_ERR(filenam);
1068 if (!IS_ERR(filenam)) {
1069 old_fs = get_fs();
1070 set_fs (KERNEL_DS);
1071 ret = sys_utime(filenam, &t);
1072 set_fs (old_fs);
1073 putname (filenam);
1075 return ret;
1078 struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };
1080 typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);
1082 static long do_readv_writev32(int type, struct file *file,
1083 const struct iovec32 *vector, u32 count)
1085 unsigned long tot_len;
1086 struct iovec iovstack[UIO_FASTIOV];
1087 struct iovec *iov=iovstack, *ivp;
1088 struct inode *inode;
1089 long retval, i;
1090 IO_fn_t fn;
1092 /* First get the "struct iovec" from user memory and
1093 * verify all the pointers
1095 if (!count)
1096 return 0;
1097 if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))
1098 return -EFAULT;
1099 if (count > UIO_MAXIOV)
1100 return -EINVAL;
1101 if (count > UIO_FASTIOV) {
1102 iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);
1103 if (!iov)
1104 return -ENOMEM;
1107 tot_len = 0;
1108 i = count;
1109 ivp = iov;
1110 while(i > 0) {
1111 u32 len;
1112 u32 buf;
1114 __get_user(len, &vector->iov_len);
1115 __get_user(buf, &vector->iov_base);
1116 tot_len += len;
1117 ivp->iov_base = (void *)A(buf);
1118 ivp->iov_len = (__kernel_size_t) len;
1119 vector++;
1120 ivp++;
1121 i--;
1124 inode = file->f_dentry->d_inode;
1125 /* VERIFY_WRITE actually means a read, as we write to user space */
1126 retval = locks_verify_area((type == VERIFY_WRITE
1127 ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),
1128 inode, file, file->f_pos, tot_len);
1129 if (retval) {
1130 if (iov != iovstack)
1131 kfree(iov);
1132 return retval;
1135 /* Then do the actual IO. Note that sockets need to be handled
1136 * specially as they have atomicity guarantees and can handle
1137 * iovec's natively
1139 if (inode->i_sock) {
1140 int err;
1141 err = sock_readv_writev(type, inode, file, iov, count, tot_len);
1142 if (iov != iovstack)
1143 kfree(iov);
1144 return err;
1147 if (!file->f_op) {
1148 if (iov != iovstack)
1149 kfree(iov);
1150 return -EINVAL;
1152 /* VERIFY_WRITE actually means a read, as we write to user space */
1153 fn = file->f_op->read;
1154 if (type == VERIFY_READ)
1155 fn = (IO_fn_t) file->f_op->write;
1156 ivp = iov;
1157 while (count > 0) {
1158 void * base;
1159 int len, nr;
1161 base = ivp->iov_base;
1162 len = ivp->iov_len;
1163 ivp++;
1164 count--;
1165 nr = fn(file, base, len, &file->f_pos);
1166 if (nr < 0) {
1167 if (retval)
1168 break;
1169 retval = nr;
1170 break;
1172 retval += nr;
1173 if (nr != len)
1174 break;
1176 if (iov != iovstack)
1177 kfree(iov);
1178 return retval;
1181 asmlinkage long sys32_readv(int fd, struct iovec32 *vector, u32 count)
1183 struct file *file;
1184 long ret = -EBADF;
1186 lock_kernel();
1188 file = fget(fd);
1189 if(!file)
1190 goto bad_file;
1192 if (file->f_op && file->f_op->read && (file->f_mode & FMODE_READ))
1193 ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);
1194 fput(file);
1196 bad_file:
1197 unlock_kernel();
1198 return ret;
1201 asmlinkage long sys32_writev(int fd, struct iovec32 *vector, u32 count)
1203 struct file *file;
1204 int ret = -EBADF;
1206 lock_kernel();
1208 file = fget(fd);
1209 if(!file)
1210 goto bad_file;
1211 if (file->f_op && file->f_op->write && (file->f_mode & FMODE_WRITE))
1212 ret = do_readv_writev32(VERIFY_READ, file, vector, count);
1213 fput(file);
1215 bad_file:
1216 unlock_kernel();
1217 return ret;
1220 /* readdir & getdents */
1222 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1223 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1225 struct old_linux_dirent32 {
1226 u32 d_ino;
1227 u32 d_offset;
1228 unsigned short d_namlen;
1229 char d_name[1];
1232 struct readdir_callback32 {
1233 struct old_linux_dirent32 * dirent;
1234 int count;
1237 static int fillonedir(void * __buf, const char * name, int namlen,
1238 off_t offset, ino_t ino)
1240 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
1241 struct old_linux_dirent32 * dirent;
1243 if (buf->count)
1244 return -EINVAL;
1245 buf->count++;
1246 dirent = buf->dirent;
1247 put_user(ino, &dirent->d_ino);
1248 put_user(offset, &dirent->d_offset);
1249 put_user(namlen, &dirent->d_namlen);
1250 copy_to_user(dirent->d_name, name, namlen);
1251 put_user(0, dirent->d_name + namlen);
1252 return 0;
1255 asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent, unsigned int count)
1257 int error = -EBADF;
1258 struct file * file;
1259 struct inode * inode;
1260 struct readdir_callback32 buf;
1262 lock_kernel();
1263 file = fget(fd);
1264 if (!file)
1265 goto out;
1267 buf.count = 0;
1268 buf.dirent = dirent;
1270 error = -ENOTDIR;
1271 if (!file->f_op || !file->f_op->readdir)
1272 goto out_putf;
1274 inode = file->f_dentry->d_inode;
1275 down(&inode->i_sem);
1276 error = file->f_op->readdir(file, &buf, fillonedir);
1277 up(&inode->i_sem);
1278 if (error < 0)
1279 goto out_putf;
1280 error = buf.count;
1282 out_putf:
1283 fput(file);
1284 out:
1285 unlock_kernel();
1286 return error;
1289 struct linux_dirent32 {
1290 u32 d_ino;
1291 u32 d_off;
1292 unsigned short d_reclen;
1293 char d_name[1];
1296 struct getdents_callback32 {
1297 struct linux_dirent32 * current_dir;
1298 struct linux_dirent32 * previous;
1299 int count;
1300 int error;
1303 static int filldir(void * __buf, const char * name, int namlen, off_t offset, ino_t ino)
1305 struct linux_dirent32 * dirent;
1306 struct getdents_callback32 * buf = (struct getdents_callback32 *) __buf;
1307 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
1309 buf->error = -EINVAL; /* only used if we fail.. */
1310 if (reclen > buf->count)
1311 return -EINVAL;
1312 dirent = buf->previous;
1313 if (dirent)
1314 put_user(offset, &dirent->d_off);
1315 dirent = buf->current_dir;
1316 buf->previous = dirent;
1317 put_user(ino, &dirent->d_ino);
1318 put_user(reclen, &dirent->d_reclen);
1319 copy_to_user(dirent->d_name, name, namlen);
1320 put_user(0, dirent->d_name + namlen);
1321 ((char *) dirent) += reclen;
1322 buf->current_dir = dirent;
1323 buf->count -= reclen;
1324 return 0;
1327 asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
1329 struct file * file;
1330 struct inode * inode;
1331 struct linux_dirent32 * lastdirent;
1332 struct getdents_callback32 buf;
1333 int error = -EBADF;
1335 lock_kernel();
1336 file = fget(fd);
1337 if (!file)
1338 goto out;
1340 buf.current_dir = dirent;
1341 buf.previous = NULL;
1342 buf.count = count;
1343 buf.error = 0;
1345 error = -ENOTDIR;
1346 if (!file->f_op || !file->f_op->readdir)
1347 goto out_putf;
1349 inode = file->f_dentry->d_inode;
1350 down(&inode->i_sem);
1351 error = file->f_op->readdir(file, &buf, filldir);
1352 up(&inode->i_sem);
1353 if (error < 0)
1354 goto out_putf;
1355 lastdirent = buf.previous;
1356 error = buf.error;
1357 if(lastdirent) {
1358 put_user(file->f_pos, &lastdirent->d_off);
1359 error = count - buf.count;
1361 out_putf:
1362 fput(file);
1363 out:
1364 unlock_kernel();
1365 return error;
1368 /* end of readdir & getdents */
1371 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1372 * 64-bit unsigned longs.
1375 static inline int
1376 get_fd_set32(unsigned long n, unsigned long *fdset, u32 *ufdset)
1378 if (ufdset) {
1379 unsigned long odd;
1381 if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32)))
1382 return -EFAULT;
1384 odd = n & 1UL;
1385 n &= ~1UL;
1386 while (n) {
1387 unsigned long h, l;
1388 __get_user(l, ufdset);
1389 __get_user(h, ufdset+1);
1390 ufdset += 2;
1391 *fdset++ = h << 32 | l;
1392 n -= 2;
1394 if (odd)
1395 __get_user(*fdset, ufdset);
1396 } else {
1397 /* Tricky, must clear full unsigned long in the
1398 * kernel fdset at the end, this makes sure that
1399 * actually happens.
1401 memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32));
1403 return 0;
1406 static inline void
1407 set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset)
1409 unsigned long odd;
1411 if (!ufdset)
1412 return;
1414 odd = n & 1UL;
1415 n &= ~1UL;
1416 while (n) {
1417 unsigned long h, l;
1418 l = *fdset++;
1419 h = l >> 32;
1420 __put_user(l, ufdset);
1421 __put_user(h, ufdset+1);
1422 ufdset += 2;
1423 n -= 2;
1425 if (odd)
1426 __put_user(*fdset, ufdset);
1429 #define MAX_SELECT_SECONDS \
1430 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1432 asmlinkage int sys32_select(int n, u32 *inp, u32 *outp, u32 *exp, u32 tvp_x)
1434 fd_set_bits fds;
1435 struct timeval32 *tvp = (struct timeval32 *)AA(tvp_x);
1436 char *bits;
1437 unsigned long nn;
1438 long timeout;
1439 int ret, size;
1441 timeout = MAX_SCHEDULE_TIMEOUT;
1442 if (tvp) {
1443 time_t sec, usec;
1445 if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
1446 || (ret = __get_user(sec, &tvp->tv_sec))
1447 || (ret = __get_user(usec, &tvp->tv_usec)))
1448 goto out_nofds;
1450 ret = -EINVAL;
1451 if(sec < 0 || usec < 0)
1452 goto out_nofds;
1454 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1455 timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
1456 timeout += sec * (unsigned long) HZ;
1460 ret = -EINVAL;
1461 if (n < 0)
1462 goto out_nofds;
1463 if (n > current->files->max_fdset)
1464 n = current->files->max_fdset;
1467 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1468 * since we used fdset we need to allocate memory in units of
1469 * long-words.
1471 ret = -ENOMEM;
1472 size = FDS_BYTES(n);
1473 bits = kmalloc(6 * size, GFP_KERNEL);
1474 if (!bits)
1475 goto out_nofds;
1476 fds.in = (unsigned long *) bits;
1477 fds.out = (unsigned long *) (bits + size);
1478 fds.ex = (unsigned long *) (bits + 2*size);
1479 fds.res_in = (unsigned long *) (bits + 3*size);
1480 fds.res_out = (unsigned long *) (bits + 4*size);
1481 fds.res_ex = (unsigned long *) (bits + 5*size);
1483 nn = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32));
1484 if ((ret = get_fd_set32(nn, fds.in, inp)) ||
1485 (ret = get_fd_set32(nn, fds.out, outp)) ||
1486 (ret = get_fd_set32(nn, fds.ex, exp)))
1487 goto out;
1488 zero_fd_set(n, fds.res_in);
1489 zero_fd_set(n, fds.res_out);
1490 zero_fd_set(n, fds.res_ex);
1492 ret = do_select(n, &fds, &timeout);
1494 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1495 time_t sec = 0, usec = 0;
1496 if (timeout) {
1497 sec = timeout / HZ;
1498 usec = timeout % HZ;
1499 usec *= (1000000/HZ);
1501 put_user(sec, &tvp->tv_sec);
1502 put_user(usec, &tvp->tv_usec);
1505 if (ret < 0)
1506 goto out;
1507 if (!ret) {
1508 ret = -ERESTARTNOHAND;
1509 if (signal_pending(current))
1510 goto out;
1511 ret = 0;
1514 set_fd_set32(nn, inp, fds.res_in);
1515 set_fd_set32(nn, outp, fds.res_out);
1516 set_fd_set32(nn, exp, fds.res_ex);
1518 out:
1519 kfree(bits);
1520 out_nofds:
1521 return ret;
1524 static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
1526 unsigned long ino, blksize, blocks;
1527 kdev_t dev, rdev;
1528 umode_t mode;
1529 nlink_t nlink;
1530 uid_t uid;
1531 gid_t gid;
1532 off_t size;
1533 time_t atime, mtime, ctime;
1534 int err;
1536 /* Stream the loads of inode data into the load buffer,
1537 * then we push it all into the store buffer below. This
1538 * should give optimal cache performance.
1540 ino = inode->i_ino;
1541 dev = inode->i_dev;
1542 mode = inode->i_mode;
1543 nlink = inode->i_nlink;
1544 uid = inode->i_uid;
1545 gid = inode->i_gid;
1546 rdev = inode->i_rdev;
1547 size = inode->i_size;
1548 atime = inode->i_atime;
1549 mtime = inode->i_mtime;
1550 ctime = inode->i_ctime;
1551 blksize = inode->i_blksize;
1552 blocks = inode->i_blocks;
1554 err = put_user(kdev_t_to_nr(dev), &statbuf->st_dev);
1555 err |= put_user(ino, &statbuf->st_ino);
1556 err |= put_user(mode, &statbuf->st_mode);
1557 err |= put_user(nlink, &statbuf->st_nlink);
1558 err |= put_user(high2lowuid(uid), &statbuf->st_uid);
1559 err |= put_user(high2lowgid(gid), &statbuf->st_gid);
1560 err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
1561 err |= put_user(size, &statbuf->st_size);
1562 err |= put_user(atime, &statbuf->st_atime);
1563 err |= put_user(0, &statbuf->__unused1);
1564 err |= put_user(mtime, &statbuf->st_mtime);
1565 err |= put_user(0, &statbuf->__unused2);
1566 err |= put_user(ctime, &statbuf->st_ctime);
1567 err |= put_user(0, &statbuf->__unused3);
1568 if (blksize) {
1569 err |= put_user(blksize, &statbuf->st_blksize);
1570 err |= put_user(blocks, &statbuf->st_blocks);
1571 } else {
1572 unsigned int tmp_blocks;
1574 #define D_B 7
1575 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
1576 tmp_blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
1577 if (tmp_blocks > D_B) {
1578 unsigned int indirect;
1580 indirect = (tmp_blocks - D_B + I_B - 1) / I_B;
1581 tmp_blocks += indirect;
1582 if (indirect > 1) {
1583 indirect = (indirect - 1 + I_B - 1) / I_B;
1584 tmp_blocks += indirect;
1585 if (indirect > 1)
1586 tmp_blocks++;
1589 err |= put_user(BLOCK_SIZE, &statbuf->st_blksize);
1590 err |= put_user((BLOCK_SIZE / 512) * tmp_blocks, &statbuf->st_blocks);
1591 #undef D_B
1592 #undef I_B
1594 err |= put_user(0, &statbuf->__unused4[0]);
1595 err |= put_user(0, &statbuf->__unused4[1]);
1597 return err;
1600 asmlinkage int sys32_newstat(char * filename, struct stat32 *statbuf)
1602 struct dentry *dentry;
1603 int error;
1605 lock_kernel();
1606 dentry = namei(filename);
1608 error = PTR_ERR(dentry);
1609 if (!IS_ERR(dentry)) {
1610 struct inode *inode = dentry->d_inode;
1612 if (inode->i_op &&
1613 inode->i_op->revalidate)
1614 error = inode->i_op->revalidate(dentry);
1615 else
1616 error = 0;
1617 if (!error)
1618 error = cp_new_stat32(inode, statbuf);
1620 dput(dentry);
1622 unlock_kernel();
1623 return error;
1626 asmlinkage int sys32_newlstat(char * filename, struct stat32 *statbuf)
1628 struct dentry *dentry;
1629 int error;
1631 lock_kernel();
1632 dentry = lnamei(filename);
1634 error = PTR_ERR(dentry);
1635 if (!IS_ERR(dentry)) {
1636 struct inode *inode = dentry->d_inode;
1638 if (inode->i_op &&
1639 inode->i_op->revalidate)
1640 error = inode->i_op->revalidate(dentry);
1641 else
1642 error = 0;
1643 if (!error)
1644 error = cp_new_stat32(inode, statbuf);
1646 dput(dentry);
1648 unlock_kernel();
1649 return error;
1652 asmlinkage int sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
1654 struct file *f;
1655 int err = -EBADF;
1657 lock_kernel();
1658 f = fget(fd);
1659 if (f) {
1660 struct dentry *dentry = f->f_dentry;
1661 struct inode *inode = dentry->d_inode;
1663 if (inode->i_op &&
1664 inode->i_op->revalidate)
1665 err = inode->i_op->revalidate(dentry);
1666 else
1667 err = 0;
1668 if (!err)
1669 err = cp_new_stat32(inode, statbuf);
1671 fput(f);
1673 unlock_kernel();
1674 return err;
1677 extern asmlinkage int sys_sysfs(int option, unsigned long arg1, unsigned long arg2);
1679 asmlinkage int sys32_sysfs(int option, u32 arg1, u32 arg2)
1681 return sys_sysfs(option, arg1, arg2);
1684 struct ncp_mount_data32 {
1685 int version;
1686 unsigned int ncp_fd;
1687 __kernel_uid_t32 mounted_uid;
1688 __kernel_pid_t32 wdog_pid;
1689 unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
1690 unsigned int time_out;
1691 unsigned int retry_count;
1692 unsigned int flags;
1693 __kernel_uid_t32 uid;
1694 __kernel_gid_t32 gid;
1695 __kernel_mode_t32 file_mode;
1696 __kernel_mode_t32 dir_mode;
1699 static void *do_ncp_super_data_conv(void *raw_data)
1701 struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
1702 struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
1704 n->dir_mode = n32->dir_mode;
1705 n->file_mode = n32->file_mode;
1706 n->gid = low2highgid(n32->gid);
1707 n->uid = low2highuid(n32->uid);
1708 memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
1709 n->wdog_pid = n32->wdog_pid;
1710 n->mounted_uid = low2highuid(n32->mounted_uid);
1711 return raw_data;
1714 struct smb_mount_data32 {
1715 int version;
1716 __kernel_uid_t32 mounted_uid;
1717 __kernel_uid_t32 uid;
1718 __kernel_gid_t32 gid;
1719 __kernel_mode_t32 file_mode;
1720 __kernel_mode_t32 dir_mode;
1723 static void *do_smb_super_data_conv(void *raw_data)
1725 struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
1726 struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
1728 s->version = s32->version;
1729 s->mounted_uid = low2highuid(s32->mounted_uid);
1730 s->uid = low2highuid(s32->uid);
1731 s->gid = low2highgid(s32->gid);
1732 s->file_mode = s32->file_mode;
1733 s->dir_mode = s32->dir_mode;
1734 return raw_data;
1737 static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel)
1739 int i;
1740 unsigned long page;
1741 struct vm_area_struct *vma;
1743 *kernel = 0;
1744 if(!user)
1745 return 0;
1746 vma = find_vma(current->mm, (unsigned long)user);
1747 if(!vma || (unsigned long)user < vma->vm_start)
1748 return -EFAULT;
1749 if(!(vma->vm_flags & VM_READ))
1750 return -EFAULT;
1751 i = vma->vm_end - (unsigned long) user;
1752 if(PAGE_SIZE <= (unsigned long) i)
1753 i = PAGE_SIZE - 1;
1754 if(!(page = __get_free_page(GFP_KERNEL)))
1755 return -ENOMEM;
1756 if(copy_from_user((void *) page, user, i)) {
1757 free_page(page);
1758 return -EFAULT;
1760 *kernel = page;
1761 return 0;
1764 extern asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
1765 unsigned long new_flags, void *data);
1767 #define SMBFS_NAME "smbfs"
1768 #define NCPFS_NAME "ncpfs"
1770 asmlinkage int sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data)
1772 unsigned long type_page;
1773 int err, is_smb, is_ncp;
1775 if(!capable(CAP_SYS_ADMIN))
1776 return -EPERM;
1777 is_smb = is_ncp = 0;
1778 err = copy_mount_stuff_to_kernel((const void *)type, &type_page);
1779 if(err)
1780 return err;
1781 if(type_page) {
1782 is_smb = !strcmp((char *)type_page, SMBFS_NAME);
1783 is_ncp = !strcmp((char *)type_page, NCPFS_NAME);
1785 if(!is_smb && !is_ncp) {
1786 if(type_page)
1787 free_page(type_page);
1788 return sys_mount(dev_name, dir_name, type, new_flags, (void *)AA(data));
1789 } else {
1790 unsigned long dev_page, dir_page, data_page;
1791 mm_segment_t old_fs;
1793 err = copy_mount_stuff_to_kernel((const void *)dev_name, &dev_page);
1794 if(err)
1795 goto out;
1796 err = copy_mount_stuff_to_kernel((const void *)dir_name, &dir_page);
1797 if(err)
1798 goto dev_out;
1799 err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);
1800 if(err)
1801 goto dir_out;
1802 if(is_ncp)
1803 do_ncp_super_data_conv((void *)data_page);
1804 else if(is_smb)
1805 do_smb_super_data_conv((void *)data_page);
1806 else
1807 panic("The problem is here...");
1808 old_fs = get_fs();
1809 set_fs(KERNEL_DS);
1810 err = sys_mount((char *)dev_page, (char *)dir_page,
1811 (char *)type_page, new_flags,
1812 (void *)data_page);
1813 set_fs(old_fs);
1815 if(data_page)
1816 free_page(data_page);
1817 dir_out:
1818 if(dir_page)
1819 free_page(dir_page);
1820 dev_out:
1821 if(dev_page)
1822 free_page(dev_page);
1823 out:
1824 if(type_page)
1825 free_page(type_page);
1826 return err;
1830 struct rusage32 {
1831 struct timeval32 ru_utime;
1832 struct timeval32 ru_stime;
1833 s32 ru_maxrss;
1834 s32 ru_ixrss;
1835 s32 ru_idrss;
1836 s32 ru_isrss;
1837 s32 ru_minflt;
1838 s32 ru_majflt;
1839 s32 ru_nswap;
1840 s32 ru_inblock;
1841 s32 ru_oublock;
1842 s32 ru_msgsnd;
1843 s32 ru_msgrcv;
1844 s32 ru_nsignals;
1845 s32 ru_nvcsw;
1846 s32 ru_nivcsw;
1849 static int put_rusage (struct rusage32 *ru, struct rusage *r)
1851 int err;
1853 err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);
1854 err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);
1855 err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);
1856 err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);
1857 err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);
1858 err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);
1859 err |= __put_user (r->ru_idrss, &ru->ru_idrss);
1860 err |= __put_user (r->ru_isrss, &ru->ru_isrss);
1861 err |= __put_user (r->ru_minflt, &ru->ru_minflt);
1862 err |= __put_user (r->ru_majflt, &ru->ru_majflt);
1863 err |= __put_user (r->ru_nswap, &ru->ru_nswap);
1864 err |= __put_user (r->ru_inblock, &ru->ru_inblock);
1865 err |= __put_user (r->ru_oublock, &ru->ru_oublock);
1866 err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);
1867 err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);
1868 err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);
1869 err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);
1870 err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);
1871 return err;
1874 extern asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr,
1875 int options, struct rusage * ru);
1877 asmlinkage int sys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options, struct rusage32 *ru)
1879 if (!ru)
1880 return sys_wait4(pid, stat_addr, options, NULL);
1881 else {
1882 struct rusage r;
1883 int ret;
1884 unsigned int status;
1885 mm_segment_t old_fs = get_fs();
1887 set_fs (KERNEL_DS);
1888 ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);
1889 set_fs (old_fs);
1890 if (put_rusage (ru, &r)) return -EFAULT;
1891 if (stat_addr && put_user (status, stat_addr))
1892 return -EFAULT;
1893 return ret;
1897 struct sysinfo32 {
1898 s32 uptime;
1899 u32 loads[3];
1900 u32 totalram;
1901 u32 freeram;
1902 u32 sharedram;
1903 u32 bufferram;
1904 u32 totalswap;
1905 u32 freeswap;
1906 unsigned short procs;
1907 char _f[22];
1910 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
1912 asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
1914 struct sysinfo s;
1915 int ret, err;
1916 mm_segment_t old_fs = get_fs ();
1918 set_fs (KERNEL_DS);
1919 ret = sys_sysinfo(&s);
1920 set_fs (old_fs);
1921 err = put_user (s.uptime, &info->uptime);
1922 err |= __put_user (s.loads[0], &info->loads[0]);
1923 err |= __put_user (s.loads[1], &info->loads[1]);
1924 err |= __put_user (s.loads[2], &info->loads[2]);
1925 err |= __put_user (s.totalram, &info->totalram);
1926 err |= __put_user (s.freeram, &info->freeram);
1927 err |= __put_user (s.sharedram, &info->sharedram);
1928 err |= __put_user (s.bufferram, &info->bufferram);
1929 err |= __put_user (s.totalswap, &info->totalswap);
1930 err |= __put_user (s.freeswap, &info->freeswap);
1931 err |= __put_user (s.procs, &info->procs);
1932 if (err)
1933 return -EFAULT;
1934 return ret;
1937 struct timespec32 {
1938 s32 tv_sec;
1939 s32 tv_nsec;
1942 extern asmlinkage int sys_sched_rr_get_interval(pid_t pid, struct timespec *interval);
1944 asmlinkage int sys32_sched_rr_get_interval(__kernel_pid_t32 pid, struct timespec32 *interval)
1946 struct timespec t;
1947 int ret;
1948 mm_segment_t old_fs = get_fs ();
1950 set_fs (KERNEL_DS);
1951 ret = sys_sched_rr_get_interval(pid, &t);
1952 set_fs (old_fs);
1953 if (put_user (t.tv_sec, &interval->tv_sec) ||
1954 __put_user (t.tv_nsec, &interval->tv_nsec))
1955 return -EFAULT;
1956 return ret;
1959 extern asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp);
1961 asmlinkage int sys32_nanosleep(struct timespec32 *rqtp, struct timespec32 *rmtp)
1963 struct timespec t;
1964 int ret;
1965 mm_segment_t old_fs = get_fs ();
1967 if (get_user (t.tv_sec, &rqtp->tv_sec) ||
1968 __get_user (t.tv_nsec, &rqtp->tv_nsec))
1969 return -EFAULT;
1970 set_fs (KERNEL_DS);
1971 ret = sys_nanosleep(&t, rmtp ? &t : NULL);
1972 set_fs (old_fs);
1973 if (rmtp && ret == -EINTR) {
1974 if (__put_user (t.tv_sec, &rmtp->tv_sec) ||
1975 __put_user (t.tv_nsec, &rmtp->tv_nsec))
1976 return -EFAULT;
1978 return ret;
1981 extern asmlinkage int sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset);
1983 asmlinkage int sys32_sigprocmask(int how, old_sigset_t32 *set, old_sigset_t32 *oset)
1985 old_sigset_t s;
1986 int ret;
1987 mm_segment_t old_fs = get_fs();
1989 if (set && get_user (s, set)) return -EFAULT;
1990 set_fs (KERNEL_DS);
1991 ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);
1992 set_fs (old_fs);
1993 if (ret) return ret;
1994 if (oset && put_user (s, oset)) return -EFAULT;
1995 return 0;
1998 extern asmlinkage int sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize);
2000 asmlinkage int sys32_rt_sigprocmask(int how, sigset_t32 *set, sigset_t32 *oset, __kernel_size_t32 sigsetsize)
2002 sigset_t s;
2003 sigset_t32 s32;
2004 int ret;
2005 mm_segment_t old_fs = get_fs();
2007 if (set) {
2008 if (copy_from_user (&s32, set, sizeof(sigset_t32)))
2009 return -EFAULT;
2010 switch (_NSIG_WORDS) {
2011 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
2012 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
2013 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
2014 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
2017 set_fs (KERNEL_DS);
2018 ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize);
2019 set_fs (old_fs);
2020 if (ret) return ret;
2021 if (oset) {
2022 switch (_NSIG_WORDS) {
2023 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2024 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2025 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2026 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2028 if (copy_to_user (oset, &s32, sizeof(sigset_t32)))
2029 return -EFAULT;
2031 return 0;
2034 extern asmlinkage int sys_sigpending(old_sigset_t *set);
2036 asmlinkage int sys32_sigpending(old_sigset_t32 *set)
2038 old_sigset_t s;
2039 int ret;
2040 mm_segment_t old_fs = get_fs();
2042 set_fs (KERNEL_DS);
2043 ret = sys_sigpending(&s);
2044 set_fs (old_fs);
2045 if (put_user (s, set)) return -EFAULT;
2046 return ret;
2049 extern asmlinkage int sys_rt_sigpending(sigset_t *set, size_t sigsetsize);
2051 asmlinkage int sys32_rt_sigpending(sigset_t32 *set, __kernel_size_t32 sigsetsize)
2053 sigset_t s;
2054 sigset_t32 s32;
2055 int ret;
2056 mm_segment_t old_fs = get_fs();
2058 set_fs (KERNEL_DS);
2059 ret = sys_rt_sigpending(&s, sigsetsize);
2060 set_fs (old_fs);
2061 if (!ret) {
2062 switch (_NSIG_WORDS) {
2063 case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];
2064 case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];
2065 case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];
2066 case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];
2068 if (copy_to_user (set, &s32, sizeof(sigset_t32)))
2069 return -EFAULT;
2071 return ret;
2074 extern asmlinkage int
2075 sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
2076 const struct timespec *uts, size_t sigsetsize);
2078 asmlinkage int
2079 sys32_rt_sigtimedwait(sigset_t32 *uthese, siginfo_t32 *uinfo,
2080 struct timespec32 *uts, __kernel_size_t32 sigsetsize)
2082 sigset_t s;
2083 sigset_t32 s32;
2084 struct timespec t;
2085 int ret, err, i;
2086 mm_segment_t old_fs = get_fs();
2087 siginfo_t info;
2089 if (copy_from_user (&s32, uthese, sizeof(sigset_t32)))
2090 return -EFAULT;
2091 switch (_NSIG_WORDS) {
2092 case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);
2093 case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);
2094 case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);
2095 case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
2097 if (uts) {
2098 ret = get_user (t.tv_sec, &uts->tv_sec);
2099 ret |= __get_user (t.tv_nsec, &uts->tv_nsec);
2100 if (ret)
2101 return -EFAULT;
2103 set_fs (KERNEL_DS);
2104 ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
2105 set_fs (old_fs);
2106 if (ret >= 0 && uinfo) {
2107 err = put_user (info.si_signo, &uinfo->si_signo);
2108 err |= __put_user (info.si_errno, &uinfo->si_errno);
2109 err |= __put_user (info.si_code, &uinfo->si_code);
2110 if (info.si_code < 0)
2111 err |= __copy_to_user (uinfo->_sifields._pad, info._sifields._pad, SI_PAD_SIZE);
2112 else {
2113 i = info.si_signo;
2114 if (info.si_code == SI_USER)
2115 i = SIGRTMIN;
2116 switch (i) {
2117 case SIGPOLL:
2118 err |= __put_user (info.si_band, &uinfo->si_band);
2119 err |= __put_user (info.si_fd, &uinfo->si_fd);
2120 break;
2121 case SIGCHLD:
2122 err |= __put_user (info.si_pid, &uinfo->si_pid);
2123 err |= __put_user (info.si_uid, &uinfo->si_uid);
2124 err |= __put_user (info.si_status, &uinfo->si_status);
2125 err |= __put_user (info.si_utime, &uinfo->si_utime);
2126 err |= __put_user (info.si_stime, &uinfo->si_stime);
2127 break;
2128 case SIGSEGV:
2129 case SIGILL:
2130 case SIGFPE:
2131 case SIGBUS:
2132 case SIGEMT:
2133 err |= __put_user ((long)info.si_addr, &uinfo->si_addr);
2134 err |= __put_user (info.si_trapno, &uinfo->si_trapno);
2135 break;
2136 default:
2137 err |= __put_user (info.si_pid, &uinfo->si_pid);
2138 err |= __put_user (info.si_uid, &uinfo->si_uid);
2139 break;
2142 if (err)
2143 ret = -EFAULT;
2145 return ret;
2148 extern asmlinkage int
2149 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2151 asmlinkage int
2152 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2154 siginfo_t info;
2155 int ret;
2156 mm_segment_t old_fs = get_fs();
2158 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2159 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2160 return -EFAULT;
2161 set_fs (KERNEL_DS);
2162 ret = sys_rt_sigqueueinfo(pid, sig, &info);
2163 set_fs (old_fs);
2164 return ret;
2167 struct tms32 {
2168 __kernel_clock_t32 tms_utime;
2169 __kernel_clock_t32 tms_stime;
2170 __kernel_clock_t32 tms_cutime;
2171 __kernel_clock_t32 tms_cstime;
2174 extern asmlinkage long sys_times(struct tms * tbuf);
2176 asmlinkage long sys32_times(struct tms32 *tbuf)
2178 struct tms t;
2179 long ret;
2180 mm_segment_t old_fs = get_fs ();
2181 int err;
2183 set_fs (KERNEL_DS);
2184 ret = sys_times(tbuf ? &t : NULL);
2185 set_fs (old_fs);
2186 if (tbuf) {
2187 err = put_user (t.tms_utime, &tbuf->tms_utime);
2188 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2189 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2190 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2191 if (err)
2192 ret = -EFAULT;
2194 return ret;
2197 #define RLIM_INFINITY32 0x7fffffff
2198 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2200 struct rlimit32 {
2201 u32 rlim_cur;
2202 u32 rlim_max;
2205 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2207 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2209 struct rlimit r;
2210 int ret;
2211 mm_segment_t old_fs = get_fs ();
2213 set_fs (KERNEL_DS);
2214 ret = sys_getrlimit(resource, &r);
2215 set_fs (old_fs);
2216 if (!ret) {
2217 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2218 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2220 return ret;
2223 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2225 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2227 struct rlimit r;
2228 int ret;
2229 mm_segment_t old_fs = get_fs ();
2231 if (resource >= RLIM_NLIMITS) return -EINVAL;
2232 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2233 __get_user (r.rlim_max, &rlim->rlim_max))
2234 return -EFAULT;
2235 if (r.rlim_cur == RLIM_INFINITY32)
2236 r.rlim_cur = RLIM_INFINITY;
2237 if (r.rlim_max == RLIM_INFINITY32)
2238 r.rlim_max = RLIM_INFINITY;
2239 set_fs (KERNEL_DS);
2240 ret = sys_setrlimit(resource, &r);
2241 set_fs (old_fs);
2242 return ret;
2245 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2247 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2249 struct rusage r;
2250 int ret;
2251 mm_segment_t old_fs = get_fs();
2253 set_fs (KERNEL_DS);
2254 ret = sys_getrusage(who, &r);
2255 set_fs (old_fs);
2256 if (put_rusage (ru, &r)) return -EFAULT;
2257 return ret;
2260 /* XXX This really belongs in some header file... -DaveM */
2261 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2262 16 for IP, 16 for IPX,
2263 24 for IPv6,
2264 about 80 for AX.25 */
2266 /* XXX These as well... */
2267 extern __inline__ struct socket *socki_lookup(struct inode *inode)
2269 return &inode->u.socket_i;
2272 extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
2274 struct file *file;
2275 struct inode *inode;
2277 if (!(file = fget(fd)))
2279 *err = -EBADF;
2280 return NULL;
2283 inode = file->f_dentry->d_inode;
2284 if (!inode || !inode->i_sock || !socki_lookup(inode))
2286 *err = -ENOTSOCK;
2287 fput(file);
2288 return NULL;
2291 return socki_lookup(inode);
2294 extern __inline__ void sockfd_put(struct socket *sock)
2296 fput(sock->file);
2299 struct msghdr32 {
2300 u32 msg_name;
2301 int msg_namelen;
2302 u32 msg_iov;
2303 __kernel_size_t32 msg_iovlen;
2304 u32 msg_control;
2305 __kernel_size_t32 msg_controllen;
2306 unsigned msg_flags;
2309 struct cmsghdr32 {
2310 __kernel_size_t32 cmsg_len;
2311 int cmsg_level;
2312 int cmsg_type;
2315 /* Bleech... */
2316 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2317 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2319 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2321 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2322 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2323 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2325 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2326 (struct cmsghdr32 *)(ctl) : \
2327 (struct cmsghdr32 *)NULL)
2328 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2330 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2331 struct cmsghdr32 *__cmsg, int __cmsg_len)
2333 struct cmsghdr32 * __ptr;
2335 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2336 CMSG32_ALIGN(__cmsg_len));
2337 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2338 return NULL;
2340 return __ptr;
2343 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2344 struct cmsghdr32 *__cmsg,
2345 int __cmsg_len)
2347 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2348 __cmsg, __cmsg_len);
2351 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2352 struct iovec32 *uiov32,
2353 int niov)
2355 int tot_len = 0;
2357 while(niov > 0) {
2358 u32 len, buf;
2360 if(get_user(len, &uiov32->iov_len) ||
2361 get_user(buf, &uiov32->iov_base)) {
2362 tot_len = -EFAULT;
2363 break;
2365 tot_len += len;
2366 kiov->iov_base = (void *)A(buf);
2367 kiov->iov_len = (__kernel_size_t) len;
2368 uiov32++;
2369 kiov++;
2370 niov--;
2372 return tot_len;
2375 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2376 struct msghdr32 *umsg)
2378 u32 tmp1, tmp2, tmp3;
2379 int err;
2381 err = get_user(tmp1, &umsg->msg_name);
2382 err |= __get_user(tmp2, &umsg->msg_iov);
2383 err |= __get_user(tmp3, &umsg->msg_control);
2384 if (err)
2385 return -EFAULT;
2387 kmsg->msg_name = (void *)A(tmp1);
2388 kmsg->msg_iov = (struct iovec *)A(tmp2);
2389 kmsg->msg_control = (void *)A(tmp3);
2391 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2392 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2393 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2394 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2396 return err;
2399 /* I've named the args so it is easy to tell whose space the pointers are in. */
2400 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2401 char *kern_address, int mode)
2403 int tot_len;
2405 if(kern_msg->msg_namelen) {
2406 if(mode==VERIFY_READ) {
2407 int err = move_addr_to_kernel(kern_msg->msg_name,
2408 kern_msg->msg_namelen,
2409 kern_address);
2410 if(err < 0)
2411 return err;
2413 kern_msg->msg_name = kern_address;
2414 } else
2415 kern_msg->msg_name = NULL;
2417 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2418 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2419 GFP_KERNEL);
2420 if(!kern_iov)
2421 return -ENOMEM;
2424 tot_len = iov_from_user32_to_kern(kern_iov,
2425 (struct iovec32 *)kern_msg->msg_iov,
2426 kern_msg->msg_iovlen);
2427 if(tot_len >= 0)
2428 kern_msg->msg_iov = kern_iov;
2429 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2430 kfree(kern_iov);
2432 return tot_len;
2435 /* There is a lot of hair here because the alignment rules (and
2436 * thus placement) of cmsg headers and length are different for
2437 * 32-bit apps. -DaveM
2439 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2440 unsigned char *stackbuf, int stackbuf_size)
2442 struct cmsghdr32 *ucmsg;
2443 struct cmsghdr *kcmsg, *kcmsg_base;
2444 __kernel_size_t32 ucmlen;
2445 __kernel_size_t kcmlen, tmp;
2447 kcmlen = 0;
2448 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2449 ucmsg = CMSG32_FIRSTHDR(kmsg);
2450 while(ucmsg != NULL) {
2451 if(get_user(ucmlen, &ucmsg->cmsg_len))
2452 return -EFAULT;
2454 /* Catch bogons. */
2455 if(CMSG32_ALIGN(ucmlen) <
2456 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2457 return -EINVAL;
2458 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2459 + ucmlen) > kmsg->msg_controllen)
2460 return -EINVAL;
2462 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2463 CMSG_ALIGN(sizeof(struct cmsghdr)));
2464 kcmlen += tmp;
2465 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2467 if(kcmlen == 0)
2468 return -EINVAL;
2470 /* The kcmlen holds the 64-bit version of the control length.
2471 * It may not be modified as we do not stick it into the kmsg
2472 * until we have successfully copied over all of the data
2473 * from the user.
2475 if(kcmlen > stackbuf_size)
2476 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2477 if(kcmsg == NULL)
2478 return -ENOBUFS;
2480 /* Now copy them over neatly. */
2481 memset(kcmsg, 0, kcmlen);
2482 ucmsg = CMSG32_FIRSTHDR(kmsg);
2483 while(ucmsg != NULL) {
2484 __get_user(ucmlen, &ucmsg->cmsg_len);
2485 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2486 CMSG_ALIGN(sizeof(struct cmsghdr)));
2487 kcmsg->cmsg_len = tmp;
2488 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2489 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2491 /* Copy over the data. */
2492 if(copy_from_user(CMSG_DATA(kcmsg),
2493 CMSG32_DATA(ucmsg),
2494 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2495 goto out_free_efault;
2497 /* Advance. */
2498 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2499 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2502 /* Ok, looks like we made it. Hook it up and return success. */
2503 kmsg->msg_control = kcmsg_base;
2504 kmsg->msg_controllen = kcmlen;
2505 return 0;
2507 out_free_efault:
2508 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2509 kfree(kcmsg_base);
2510 return -EFAULT;
2513 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2514 int len, void *data)
2516 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2517 struct cmsghdr32 cmhdr;
2518 int cmlen = CMSG32_LEN(len);
2520 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2521 kmsg->msg_flags |= MSG_CTRUNC;
2522 return;
2525 if(kmsg->msg_controllen < cmlen) {
2526 kmsg->msg_flags |= MSG_CTRUNC;
2527 cmlen = kmsg->msg_controllen;
2529 cmhdr.cmsg_level = level;
2530 cmhdr.cmsg_type = type;
2531 cmhdr.cmsg_len = cmlen;
2533 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2534 return;
2535 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2536 return;
2537 cmlen = CMSG32_SPACE(len);
2538 kmsg->msg_control += cmlen;
2539 kmsg->msg_controllen -= cmlen;
2542 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2544 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2545 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2546 int fdnum = scm->fp->count;
2547 struct file **fp = scm->fp->fp;
2548 int *cmfptr;
2549 int err = 0, i;
2551 if (fdnum < fdmax)
2552 fdmax = fdnum;
2554 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2555 int new_fd;
2556 err = get_unused_fd();
2557 if (err < 0)
2558 break;
2559 new_fd = err;
2560 err = put_user(new_fd, cmfptr);
2561 if (err) {
2562 put_unused_fd(new_fd);
2563 break;
2565 /* Bump the usage count and install the file. */
2566 get_file(fp[i]);
2567 fd_install(new_fd, fp[i]);
2570 if (i > 0) {
2571 int cmlen = CMSG32_LEN(i * sizeof(int));
2572 if (!err)
2573 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2574 if (!err)
2575 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2576 if (!err)
2577 err = put_user(cmlen, &cm->cmsg_len);
2578 if (!err) {
2579 cmlen = CMSG32_SPACE(i * sizeof(int));
2580 kmsg->msg_control += cmlen;
2581 kmsg->msg_controllen -= cmlen;
2584 if (i < fdnum)
2585 kmsg->msg_flags |= MSG_CTRUNC;
2588 * All of the files that fit in the message have had their
2589 * usage counts incremented, so we just free the list.
2591 __scm_destroy(scm);
2594 /* In these cases we (currently) can just copy to data over verbatim
2595 * because all CMSGs created by the kernel have well defined types which
2596 * have the same layout in both the 32-bit and 64-bit API. One must add
2597 * some special cased conversions here if we start sending control messages
2598 * with incompatible types.
2600 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2601 * we do our work. The remaining cases are:
2603 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2604 * IP_TTL int 32-bit clean
2605 * IP_TOS __u8 32-bit clean
2606 * IP_RECVOPTS variable length 32-bit clean
2607 * IP_RETOPTS variable length 32-bit clean
2608 * (these last two are clean because the types are defined
2609 * by the IPv4 protocol)
2610 * IP_RECVERR struct sock_extended_err +
2611 * struct sockaddr_in 32-bit clean
2612 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2613 * struct sockaddr_in6 32-bit clean
2614 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2615 * IPV6_HOPLIMIT int 32-bit clean
2616 * IPV6_FLOWINFO u32 32-bit clean
2617 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2618 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2619 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2620 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2622 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2624 unsigned char *workbuf, *wp;
2625 unsigned long bufsz, space_avail;
2626 struct cmsghdr *ucmsg;
2628 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2629 space_avail = kmsg->msg_controllen + bufsz;
2630 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2631 if(workbuf == NULL)
2632 goto fail;
2634 /* To make this more sane we assume the kernel sends back properly
2635 * formatted control messages. Because of how the kernel will truncate
2636 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2638 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2639 while(((unsigned long)ucmsg) < ((unsigned long)kmsg->msg_control)) {
2640 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2641 int clen64, clen32;
2643 /* UCMSG is the 64-bit format CMSG entry in user-space.
2644 * KCMSG32 is within the kernel space temporary buffer
2645 * we use to convert into a 32-bit style CMSG.
2647 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2648 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2649 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2651 clen64 = kcmsg32->cmsg_len;
2652 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2653 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2654 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2655 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2656 kcmsg32->cmsg_len = clen32;
2658 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2659 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2662 /* Copy back fixed up data, and adjust pointers. */
2663 bufsz = (wp - workbuf);
2664 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2666 kmsg->msg_control = (struct cmsghdr *)
2667 (((char *)orig_cmsg_uptr) + bufsz);
2668 kmsg->msg_controllen = space_avail - bufsz;
2670 kfree(workbuf);
2671 return;
2673 fail:
2674 /* If we leave the 64-bit format CMSG chunks in there,
2675 * the application could get confused and crash. So to
2676 * ensure greater recovery, we report no CMSGs.
2678 kmsg->msg_controllen += bufsz;
2679 kmsg->msg_control = (void *) orig_cmsg_uptr;
2682 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2684 struct socket *sock;
2685 char address[MAX_SOCK_ADDR];
2686 struct iovec iov[UIO_FASTIOV];
2687 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2688 unsigned char *ctl_buf = ctl;
2689 struct msghdr kern_msg;
2690 int err, total_len;
2692 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2693 return -EFAULT;
2694 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2695 return -EINVAL;
2696 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2697 if (err < 0)
2698 goto out;
2699 total_len = err;
2701 if(kern_msg.msg_controllen) {
2702 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2703 if(err)
2704 goto out_freeiov;
2705 ctl_buf = kern_msg.msg_control;
2707 kern_msg.msg_flags = user_flags;
2709 lock_kernel();
2710 sock = sockfd_lookup(fd, &err);
2711 if (sock != NULL) {
2712 if (sock->file->f_flags & O_NONBLOCK)
2713 kern_msg.msg_flags |= MSG_DONTWAIT;
2714 err = sock_sendmsg(sock, &kern_msg, total_len);
2715 sockfd_put(sock);
2717 unlock_kernel();
2719 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2720 if(ctl_buf != ctl)
2721 kfree(ctl_buf);
2722 out_freeiov:
2723 if(kern_msg.msg_iov != iov)
2724 kfree(kern_msg.msg_iov);
2725 out:
2726 return err;
2729 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2731 struct iovec iovstack[UIO_FASTIOV];
2732 struct msghdr kern_msg;
2733 char addr[MAX_SOCK_ADDR];
2734 struct socket *sock;
2735 struct iovec *iov = iovstack;
2736 struct sockaddr *uaddr;
2737 int *uaddr_len;
2738 unsigned long cmsg_ptr;
2739 int err, total_len, len = 0;
2741 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2742 return -EFAULT;
2743 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2744 return -EINVAL;
2746 uaddr = kern_msg.msg_name;
2747 uaddr_len = &user_msg->msg_namelen;
2748 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2749 if (err < 0)
2750 goto out;
2751 total_len = err;
2753 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2754 kern_msg.msg_flags = 0;
2756 lock_kernel();
2757 sock = sockfd_lookup(fd, &err);
2758 if (sock != NULL) {
2759 struct scm_cookie scm;
2761 if (sock->file->f_flags & O_NONBLOCK)
2762 user_flags |= MSG_DONTWAIT;
2763 memset(&scm, 0, sizeof(scm));
2764 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2765 user_flags, &scm);
2766 if(err >= 0) {
2767 len = err;
2768 if(!kern_msg.msg_control) {
2769 if(sock->passcred || scm.fp)
2770 kern_msg.msg_flags |= MSG_CTRUNC;
2771 if(scm.fp)
2772 __scm_destroy(&scm);
2773 } else {
2774 /* If recvmsg processing itself placed some
2775 * control messages into user space, it's is
2776 * using 64-bit CMSG processing, so we need
2777 * to fix it up before we tack on more stuff.
2779 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2780 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2782 /* Wheee... */
2783 if(sock->passcred)
2784 put_cmsg32(&kern_msg,
2785 SOL_SOCKET, SCM_CREDENTIALS,
2786 sizeof(scm.creds), &scm.creds);
2787 if(scm.fp != NULL)
2788 scm_detach_fds32(&kern_msg, &scm);
2791 sockfd_put(sock);
2793 unlock_kernel();
2795 if(uaddr != NULL && err >= 0)
2796 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2797 if(cmsg_ptr != 0 && err >= 0) {
2798 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2799 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2800 err |= __put_user(uclen, &user_msg->msg_controllen);
2802 if(err >= 0)
2803 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2804 if(kern_msg.msg_iov != iov)
2805 kfree(kern_msg.msg_iov);
2806 out:
2807 if(err < 0)
2808 return err;
2809 return len;
2812 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2813 char *optval, int optlen);
2815 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2816 char *optval, int optlen)
2818 if (optname == SO_ATTACH_FILTER) {
2819 struct sock_fprog32 {
2820 __u16 len;
2821 __u32 filter;
2822 } *fprog32 = (struct sock_fprog32 *)optval;
2823 struct sock_fprog kfprog;
2824 struct sock_filter *kfilter;
2825 unsigned int fsize;
2826 mm_segment_t old_fs;
2827 __u32 uptr;
2828 int ret;
2830 if (get_user(kfprog.len, &fprog32->len) ||
2831 __get_user(uptr, &fprog32->filter))
2832 return -EFAULT;
2833 kfprog.filter = (struct sock_filter *)A(uptr);
2834 fsize = kfprog.len * sizeof(struct sock_filter);
2835 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2836 if (kfilter == NULL)
2837 return -ENOMEM;
2838 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2839 kfree(kfilter);
2840 return -EFAULT;
2842 kfprog.filter = kfilter;
2843 old_fs = get_fs();
2844 set_fs(KERNEL_DS);
2845 ret = sys_setsockopt(fd, level, optname,
2846 (char *)&kfprog, sizeof(kfprog));
2847 set_fs(old_fs);
2848 kfree(kfilter);
2849 return ret;
2851 return sys_setsockopt(fd, level, optname, optval, optlen);
2854 /* Argument list sizes for sys_socketcall */
2855 #define AL(x) ((x) * sizeof(u32))
2856 static unsigned char nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
2857 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
2858 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
2859 #undef AL
2861 extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
2862 extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
2863 extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen);
2864 extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
2865 extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
2866 extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
2867 extern asmlinkage int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
2868 unsigned flags, u32 addr, int addr_len);
2869 extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
2870 extern asmlinkage int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
2871 unsigned flags, u32 addr, u32 addr_len);
2872 extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
2873 u32 optval, u32 optlen);
2875 extern asmlinkage int sys_socket(int family, int type, int protocol);
2876 extern asmlinkage int sys_socketpair(int family, int type, int protocol,
2877 int usockvec[2]);
2878 extern asmlinkage int sys_shutdown(int fd, int how);
2879 extern asmlinkage int sys_listen(int fd, int backlog);
2881 asmlinkage int sys32_socketcall(int call, u32 *args)
2883 u32 a[6];
2884 u32 a0,a1;
2886 if (call<SYS_SOCKET||call>SYS_RECVMSG)
2887 return -EINVAL;
2888 if (copy_from_user(a, args, nargs[call]))
2889 return -EFAULT;
2890 a0=a[0];
2891 a1=a[1];
2893 switch(call)
2895 case SYS_SOCKET:
2896 return sys_socket(a0, a1, a[2]);
2897 case SYS_BIND:
2898 return sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
2899 case SYS_CONNECT:
2900 return sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
2901 case SYS_LISTEN:
2902 return sys_listen(a0, a1);
2903 case SYS_ACCEPT:
2904 return sys_accept(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
2905 case SYS_GETSOCKNAME:
2906 return sys_getsockname(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
2907 case SYS_GETPEERNAME:
2908 return sys_getpeername(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
2909 case SYS_SOCKETPAIR:
2910 return sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
2911 case SYS_SEND:
2912 return sys_send(a0, (void *)A(a1), a[2], a[3]);
2913 case SYS_SENDTO:
2914 return sys32_sendto(a0, a1, a[2], a[3], a[4], a[5]);
2915 case SYS_RECV:
2916 return sys_recv(a0, (void *)A(a1), a[2], a[3]);
2917 case SYS_RECVFROM:
2918 return sys32_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
2919 case SYS_SHUTDOWN:
2920 return sys_shutdown(a0,a1);
2921 case SYS_SETSOCKOPT:
2922 return sys32_setsockopt(a0, a1, a[2], (char *)A(a[3]), a[4]);
2923 case SYS_GETSOCKOPT:
2924 return sys32_getsockopt(a0, a1, a[2], a[3], a[4]);
2925 case SYS_SENDMSG:
2926 return sys32_sendmsg(a0, (struct msghdr32 *)A(a1), a[2]);
2927 case SYS_RECVMSG:
2928 return sys32_recvmsg(a0, (struct msghdr32 *)A(a1), a[2]);
2930 return -EINVAL;
2933 extern void check_pending(int signum);
2935 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2937 struct k_sigaction new_ka, old_ka;
2938 int ret;
2940 if(sig < 0) {
2941 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2942 sig = -sig;
2945 if (act) {
2946 old_sigset_t32 mask;
2948 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2949 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2950 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2951 ret |= __get_user(mask, &act->sa_mask);
2952 if (ret)
2953 return ret;
2954 new_ka.ka_restorer = NULL;
2955 siginitset(&new_ka.sa.sa_mask, mask);
2958 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2960 if (!ret && oact) {
2961 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2962 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2963 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2964 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2967 return ret;
2970 asmlinkage int
2971 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2972 void *restorer, __kernel_size_t32 sigsetsize)
2974 struct k_sigaction new_ka, old_ka;
2975 int ret;
2976 sigset_t32 set32;
2978 /* XXX: Don't preclude handling different sized sigset_t's. */
2979 if (sigsetsize != sizeof(sigset_t32))
2980 return -EINVAL;
2982 /* All tasks which use RT signals (effectively) use
2983 * new style signals.
2985 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2987 if (act) {
2988 new_ka.ka_restorer = restorer;
2989 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2990 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2991 switch (_NSIG_WORDS) {
2992 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2993 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2994 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2995 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2997 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2998 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2999 if (ret)
3000 return -EFAULT;
3003 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
3005 if (!ret && oact) {
3006 switch (_NSIG_WORDS) {
3007 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
3008 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
3009 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
3010 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
3012 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
3013 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
3014 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
3015 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
3018 return ret;
3023 * count32() counts the number of arguments/envelopes
3025 static int count32(u32 * argv)
3027 int i = 0;
3029 if (argv != NULL) {
3030 for (;;) {
3031 u32 p; int error;
3033 error = get_user(p,argv);
3034 if (error) return error;
3035 if (!p) break;
3036 argv++; i++;
3039 return i;
3043 * 'copy_string32()' copies argument/envelope strings from user
3044 * memory to free pages in kernel mem. These are in a format ready
3045 * to be put directly into the top of new user memory.
3047 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
3049 while (argc-- > 0) {
3050 u32 str;
3051 int len;
3052 unsigned long pos;
3054 if (get_user(str, argv + argc) ||
3055 !str ||
3056 !(len = strnlen_user((char *)A(str), bprm->p)))
3057 return -EFAULT;
3059 if (bprm->p < len)
3060 return -E2BIG;
3062 bprm->p -= len;
3064 pos = bprm->p;
3065 while (len) {
3066 char *kaddr;
3067 struct page *page;
3068 int offset, bytes_to_copy, new, err;
3070 offset = pos % PAGE_SIZE;
3071 page = bprm->page[pos / PAGE_SIZE];
3072 new = 0;
3073 if (!page) {
3074 page = alloc_page(GFP_USER);
3075 bprm->page[pos / PAGE_SIZE] = page;
3076 if (!page)
3077 return -ENOMEM;
3078 new = 1;
3080 kaddr = (char *)kmap(page);
3082 if (new && offset)
3083 memset(kaddr, 0, offset);
3084 bytes_to_copy = PAGE_SIZE - offset;
3085 if (bytes_to_copy > len) {
3086 bytes_to_copy = len;
3087 if (new)
3088 memset(kaddr+offset+len, 0,
3089 PAGE_SIZE-offset-len);
3092 err = copy_from_user(kaddr + offset, (char *)A(str),
3093 bytes_to_copy);
3094 flush_page_to_ram(page);
3095 kunmap((unsigned long)kaddr);
3097 if (err)
3098 return -EFAULT;
3100 pos += bytes_to_copy;
3101 str += bytes_to_copy;
3102 len -= bytes_to_copy;
3105 return 0;
3109 * sys32_execve() executes a new program.
3111 static inline int
3112 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
3114 struct linux_binprm bprm;
3115 struct dentry * dentry;
3116 int retval;
3117 int i;
3119 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3120 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3122 dentry = open_namei(filename, 0, 0);
3123 retval = PTR_ERR(dentry);
3124 if (IS_ERR(dentry))
3125 return retval;
3127 bprm.dentry = dentry;
3128 bprm.filename = filename;
3129 bprm.sh_bang = 0;
3130 bprm.loader = 0;
3131 bprm.exec = 0;
3132 if ((bprm.argc = count32(argv)) < 0) {
3133 dput(dentry);
3134 return bprm.argc;
3136 if ((bprm.envc = count32(envp)) < 0) {
3137 dput(dentry);
3138 return bprm.envc;
3141 retval = prepare_binprm(&bprm);
3142 if (retval < 0)
3143 goto out;
3145 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3146 if (retval < 0)
3147 goto out;
3149 bprm.exec = bprm.p;
3150 retval = copy_strings32(bprm.envc, envp, &bprm);
3151 if (retval < 0)
3152 goto out;
3154 retval = copy_strings32(bprm.argc, argv, &bprm);
3155 if (retval < 0)
3156 goto out;
3158 retval = search_binary_handler(&bprm, regs);
3159 if (retval >= 0)
3160 /* execve success */
3161 return retval;
3163 out:
3164 /* Something went wrong, return the inode and free the argument pages*/
3165 if (bprm.dentry)
3166 dput(bprm.dentry);
3168 for (i=0 ; i<MAX_ARG_PAGES ; i++)
3169 if (bprm.page[i])
3170 __free_page(bprm.page[i]);
3172 return retval;
3176 * sparc32_execve() executes a new program after the asm stub has set
3177 * things up for us. This should basically do what I want it to.
3179 asmlinkage int sparc32_execve(struct pt_regs *regs)
3181 int error, base = 0;
3182 char *filename;
3184 /* User register window flush is done by entry.S */
3186 /* Check for indirect call. */
3187 if((u32)regs->u_regs[UREG_G1] == 0)
3188 base = 1;
3190 lock_kernel();
3191 filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
3192 error = PTR_ERR(filename);
3193 if(IS_ERR(filename))
3194 goto out;
3195 error = do_execve32(filename,
3196 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3197 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3198 putname(filename);
3200 if(!error) {
3201 fprs_write(0);
3202 current->thread.xfsr[0] = 0;
3203 current->thread.fpsaved[0] = 0;
3204 regs->tstate &= ~TSTATE_PEF;
3206 out:
3207 unlock_kernel();
3208 return error;
3211 #ifdef CONFIG_MODULES
3213 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3215 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3217 return sys_create_module(name_user, (size_t)size);
3220 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3222 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3223 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3225 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3227 return sys_init_module(name_user, mod_user);
3230 extern asmlinkage int sys_delete_module(const char *name_user);
3232 asmlinkage int sys32_delete_module(const char *name_user)
3234 return sys_delete_module(name_user);
3237 struct module_info32 {
3238 u32 addr;
3239 u32 size;
3240 u32 flags;
3241 s32 usecount;
3244 /* Query various bits about modules. */
3246 static inline long
3247 get_mod_name(const char *user_name, char **buf)
3249 unsigned long page;
3250 long retval;
3252 if ((unsigned long)user_name >= TASK_SIZE
3253 && !segment_eq(get_fs (), KERNEL_DS))
3254 return -EFAULT;
3256 page = __get_free_page(GFP_KERNEL);
3257 if (!page)
3258 return -ENOMEM;
3260 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3261 if (retval > 0) {
3262 if (retval < PAGE_SIZE) {
3263 *buf = (char *)page;
3264 return retval;
3266 retval = -ENAMETOOLONG;
3267 } else if (!retval)
3268 retval = -EINVAL;
3270 free_page(page);
3271 return retval;
3274 static inline void
3275 put_mod_name(char *buf)
3277 free_page((unsigned long)buf);
3280 static __inline__ struct module *find_module(const char *name)
3282 struct module *mod;
3284 for (mod = module_list; mod ; mod = mod->next) {
3285 if (mod->flags & MOD_DELETED)
3286 continue;
3287 if (!strcmp(mod->name, name))
3288 break;
3291 return mod;
3294 static int
3295 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3297 struct module *mod;
3298 size_t nmod, space, len;
3300 nmod = space = 0;
3302 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3303 len = strlen(mod->name)+1;
3304 if (len > bufsize)
3305 goto calc_space_needed;
3306 if (copy_to_user(buf, mod->name, len))
3307 return -EFAULT;
3308 buf += len;
3309 bufsize -= len;
3310 space += len;
3313 if (put_user(nmod, ret))
3314 return -EFAULT;
3315 else
3316 return 0;
3318 calc_space_needed:
3319 space += len;
3320 while ((mod = mod->next)->next != NULL)
3321 space += strlen(mod->name)+1;
3323 if (put_user(space, ret))
3324 return -EFAULT;
3325 else
3326 return -ENOSPC;
3329 static int
3330 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3332 size_t i, space, len;
3334 if (mod->next == NULL)
3335 return -EINVAL;
3336 if (!MOD_CAN_QUERY(mod))
3337 return put_user(0, ret);
3339 space = 0;
3340 for (i = 0; i < mod->ndeps; ++i) {
3341 const char *dep_name = mod->deps[i].dep->name;
3343 len = strlen(dep_name)+1;
3344 if (len > bufsize)
3345 goto calc_space_needed;
3346 if (copy_to_user(buf, dep_name, len))
3347 return -EFAULT;
3348 buf += len;
3349 bufsize -= len;
3350 space += len;
3353 return put_user(i, ret);
3355 calc_space_needed:
3356 space += len;
3357 while (++i < mod->ndeps)
3358 space += strlen(mod->deps[i].dep->name)+1;
3360 if (put_user(space, ret))
3361 return -EFAULT;
3362 else
3363 return -ENOSPC;
3366 static int
3367 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3369 size_t nrefs, space, len;
3370 struct module_ref *ref;
3372 if (mod->next == NULL)
3373 return -EINVAL;
3374 if (!MOD_CAN_QUERY(mod))
3375 if (put_user(0, ret))
3376 return -EFAULT;
3377 else
3378 return 0;
3380 space = 0;
3381 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3382 const char *ref_name = ref->ref->name;
3384 len = strlen(ref_name)+1;
3385 if (len > bufsize)
3386 goto calc_space_needed;
3387 if (copy_to_user(buf, ref_name, len))
3388 return -EFAULT;
3389 buf += len;
3390 bufsize -= len;
3391 space += len;
3394 if (put_user(nrefs, ret))
3395 return -EFAULT;
3396 else
3397 return 0;
3399 calc_space_needed:
3400 space += len;
3401 while ((ref = ref->next_ref) != NULL)
3402 space += strlen(ref->ref->name)+1;
3404 if (put_user(space, ret))
3405 return -EFAULT;
3406 else
3407 return -ENOSPC;
3410 static inline int
3411 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3413 size_t i, space, len;
3414 struct module_symbol *s;
3415 char *strings;
3416 unsigned *vals;
3418 if (!MOD_CAN_QUERY(mod))
3419 if (put_user(0, ret))
3420 return -EFAULT;
3421 else
3422 return 0;
3424 space = mod->nsyms * 2*sizeof(u32);
3426 i = len = 0;
3427 s = mod->syms;
3429 if (space > bufsize)
3430 goto calc_space_needed;
3432 if (!access_ok(VERIFY_WRITE, buf, space))
3433 return -EFAULT;
3435 bufsize -= space;
3436 vals = (unsigned *)buf;
3437 strings = buf+space;
3439 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3440 len = strlen(s->name)+1;
3441 if (len > bufsize)
3442 goto calc_space_needed;
3444 if (copy_to_user(strings, s->name, len)
3445 || __put_user(s->value, vals+0)
3446 || __put_user(space, vals+1))
3447 return -EFAULT;
3449 strings += len;
3450 bufsize -= len;
3451 space += len;
3454 if (put_user(i, ret))
3455 return -EFAULT;
3456 else
3457 return 0;
3459 calc_space_needed:
3460 for (; i < mod->nsyms; ++i, ++s)
3461 space += strlen(s->name)+1;
3463 if (put_user(space, ret))
3464 return -EFAULT;
3465 else
3466 return -ENOSPC;
3469 static inline int
3470 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3472 int error = 0;
3474 if (mod->next == NULL)
3475 return -EINVAL;
3477 if (sizeof(struct module_info32) <= bufsize) {
3478 struct module_info32 info;
3479 info.addr = (unsigned long)mod;
3480 info.size = mod->size;
3481 info.flags = mod->flags;
3482 info.usecount =
3483 ((mod_member_present(mod, can_unload)
3484 && mod->can_unload)
3485 ? -1 : atomic_read(&mod->uc.usecount));
3487 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3488 return -EFAULT;
3489 } else
3490 error = -ENOSPC;
3492 if (put_user(sizeof(struct module_info32), ret))
3493 return -EFAULT;
3495 return error;
3498 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3500 struct module *mod;
3501 int err;
3503 lock_kernel();
3504 if (name_user == 0) {
3505 /* This finds "kernel_module" which is not exported. */
3506 for(mod = module_list; mod->next != NULL; mod = mod->next)
3508 } else {
3509 long namelen;
3510 char *name;
3512 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3513 err = namelen;
3514 goto out;
3516 err = -ENOENT;
3517 if (namelen == 0) {
3518 /* This finds "kernel_module" which is not exported. */
3519 for(mod = module_list; mod->next != NULL; mod = mod->next)
3521 } else if ((mod = find_module(name)) == NULL) {
3522 put_mod_name(name);
3523 goto out;
3525 put_mod_name(name);
3528 switch (which)
3530 case 0:
3531 err = 0;
3532 break;
3533 case QM_MODULES:
3534 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3535 break;
3536 case QM_DEPS:
3537 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3538 break;
3539 case QM_REFS:
3540 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3541 break;
3542 case QM_SYMBOLS:
3543 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3544 break;
3545 case QM_INFO:
3546 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3547 break;
3548 default:
3549 err = -EINVAL;
3550 break;
3552 out:
3553 unlock_kernel();
3554 return err;
3557 struct kernel_sym32 {
3558 u32 value;
3559 char name[60];
3562 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3564 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3566 int len, i;
3567 struct kernel_sym *tbl;
3568 mm_segment_t old_fs;
3570 len = sys_get_kernel_syms(NULL);
3571 if (!table) return len;
3572 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3573 if (!tbl) return -ENOMEM;
3574 old_fs = get_fs();
3575 set_fs (KERNEL_DS);
3576 sys_get_kernel_syms(tbl);
3577 set_fs (old_fs);
3578 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3579 if (put_user (tbl[i].value, &table->value) ||
3580 copy_to_user (table->name, tbl[i].name, 60))
3581 break;
3583 kfree (tbl);
3584 return i;
3587 #else /* CONFIG_MODULES */
3589 asmlinkage unsigned long
3590 sys32_create_module(const char *name_user, size_t size)
3592 return -ENOSYS;
3595 asmlinkage int
3596 sys32_init_module(const char *name_user, struct module *mod_user)
3598 return -ENOSYS;
3601 asmlinkage int
3602 sys32_delete_module(const char *name_user)
3604 return -ENOSYS;
3607 asmlinkage int
3608 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3609 size_t *ret)
3611 /* Let the program know about the new interface. Not that
3612 it'll do them much good. */
3613 if (which == 0)
3614 return 0;
3616 return -ENOSYS;
3619 asmlinkage int
3620 sys32_get_kernel_syms(struct kernel_sym *table)
3622 return -ENOSYS;
3625 #endif /* CONFIG_MODULES */
3627 /* Stuff for NFS server syscalls... */
3628 struct nfsctl_svc32 {
3629 u16 svc32_port;
3630 s32 svc32_nthreads;
3633 struct nfsctl_client32 {
3634 s8 cl32_ident[NFSCLNT_IDMAX+1];
3635 s32 cl32_naddr;
3636 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3637 s32 cl32_fhkeytype;
3638 s32 cl32_fhkeylen;
3639 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3642 struct nfsctl_export32 {
3643 s8 ex32_client[NFSCLNT_IDMAX+1];
3644 s8 ex32_path[NFS_MAXPATHLEN+1];
3645 __kernel_dev_t32 ex32_dev;
3646 __kernel_ino_t32 ex32_ino;
3647 s32 ex32_flags;
3648 __kernel_uid_t32 ex32_anon_uid;
3649 __kernel_gid_t32 ex32_anon_gid;
3652 struct nfsctl_uidmap32 {
3653 u32 ug32_ident; /* char * */
3654 __kernel_uid_t32 ug32_uidbase;
3655 s32 ug32_uidlen;
3656 u32 ug32_udimap; /* uid_t * */
3657 __kernel_uid_t32 ug32_gidbase;
3658 s32 ug32_gidlen;
3659 u32 ug32_gdimap; /* gid_t * */
3662 struct nfsctl_fhparm32 {
3663 struct sockaddr gf32_addr;
3664 __kernel_dev_t32 gf32_dev;
3665 __kernel_ino_t32 gf32_ino;
3666 s32 gf32_version;
3669 struct nfsctl_arg32 {
3670 s32 ca32_version; /* safeguard */
3671 union {
3672 struct nfsctl_svc32 u32_svc;
3673 struct nfsctl_client32 u32_client;
3674 struct nfsctl_export32 u32_export;
3675 struct nfsctl_uidmap32 u32_umap;
3676 struct nfsctl_fhparm32 u32_getfh;
3677 u32 u32_debug;
3678 } u;
3679 #define ca32_svc u.u32_svc
3680 #define ca32_client u.u32_client
3681 #define ca32_export u.u32_export
3682 #define ca32_umap u.u32_umap
3683 #define ca32_getfh u.u32_getfh
3684 #define ca32_authd u.u32_authd
3685 #define ca32_debug u.u32_debug
3688 union nfsctl_res32 {
3689 struct knfs_fh cr32_getfh;
3690 u32 cr32_debug;
3693 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3695 int err;
3697 err = __get_user(karg->ca_version, &arg32->ca32_version);
3698 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3699 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3700 return err;
3703 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3705 int err;
3707 err = __get_user(karg->ca_version, &arg32->ca32_version);
3708 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3709 &arg32->ca32_client.cl32_ident[0],
3710 NFSCLNT_IDMAX);
3711 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3712 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3713 &arg32->ca32_client.cl32_addrlist[0],
3714 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3715 err |= __get_user(karg->ca_client.cl_fhkeytype,
3716 &arg32->ca32_client.cl32_fhkeytype);
3717 err |= __get_user(karg->ca_client.cl_fhkeylen,
3718 &arg32->ca32_client.cl32_fhkeylen);
3719 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3720 &arg32->ca32_client.cl32_fhkey[0],
3721 NFSCLNT_KEYMAX);
3722 return err;
3725 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3727 int err;
3729 err = __get_user(karg->ca_version, &arg32->ca32_version);
3730 err |= copy_from_user(&karg->ca_export.ex_client[0],
3731 &arg32->ca32_export.ex32_client[0],
3732 NFSCLNT_IDMAX);
3733 err |= copy_from_user(&karg->ca_export.ex_path[0],
3734 &arg32->ca32_export.ex32_path[0],
3735 NFS_MAXPATHLEN);
3736 err |= __get_user(karg->ca_export.ex_dev,
3737 &arg32->ca32_export.ex32_dev);
3738 err |= __get_user(karg->ca_export.ex_ino,
3739 &arg32->ca32_export.ex32_ino);
3740 err |= __get_user(karg->ca_export.ex_flags,
3741 &arg32->ca32_export.ex32_flags);
3742 err |= __get_user(karg->ca_export.ex_anon_uid,
3743 &arg32->ca32_export.ex32_anon_uid);
3744 err |= __get_user(karg->ca_export.ex_anon_gid,
3745 &arg32->ca32_export.ex32_anon_gid);
3746 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3747 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3748 return err;
3751 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3753 u32 uaddr;
3754 int i;
3755 int err;
3757 memset(karg, 0, sizeof(*karg));
3758 if(__get_user(karg->ca_version, &arg32->ca32_version))
3759 return -EFAULT;
3760 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3761 if(!karg->ca_umap.ug_ident)
3762 return -ENOMEM;
3763 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3764 if(strncpy_from_user(karg->ca_umap.ug_ident,
3765 (char *)A(uaddr), PAGE_SIZE) <= 0)
3766 return -EFAULT;
3767 err |= __get_user(karg->ca_umap.ug_uidbase,
3768 &arg32->ca32_umap.ug32_uidbase);
3769 err |= __get_user(karg->ca_umap.ug_uidlen,
3770 &arg32->ca32_umap.ug32_uidlen);
3771 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3772 if (err)
3773 return -EFAULT;
3774 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3775 GFP_USER);
3776 if(!karg->ca_umap.ug_udimap)
3777 return -ENOMEM;
3778 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3779 err |= __get_user(karg->ca_umap.ug_udimap[i],
3780 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3781 err |= __get_user(karg->ca_umap.ug_gidbase,
3782 &arg32->ca32_umap.ug32_gidbase);
3783 err |= __get_user(karg->ca_umap.ug_uidlen,
3784 &arg32->ca32_umap.ug32_gidlen);
3785 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3786 if (err)
3787 return -EFAULT;
3788 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3789 GFP_USER);
3790 if(!karg->ca_umap.ug_gdimap)
3791 return -ENOMEM;
3792 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3793 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3794 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3796 return err;
3799 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3801 int err;
3803 err = __get_user(karg->ca_version, &arg32->ca32_version);
3804 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3805 &arg32->ca32_getfh.gf32_addr,
3806 (sizeof(struct sockaddr)));
3807 err |= __get_user(karg->ca_getfh.gf_dev,
3808 &arg32->ca32_getfh.gf32_dev);
3809 err |= __get_user(karg->ca_getfh.gf_ino,
3810 &arg32->ca32_getfh.gf32_ino);
3811 err |= __get_user(karg->ca_getfh.gf_version,
3812 &arg32->ca32_getfh.gf32_version);
3813 return err;
3816 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3818 int err;
3820 err = copy_to_user(&res32->cr32_getfh,
3821 &kres->cr_getfh,
3822 sizeof(res32->cr32_getfh));
3823 err |= __put_user(kres->cr_debug, &res32->cr32_debug);
3824 return err;
3827 extern asmlinkage int sys_nfsservctl(int cmd, void *arg, void *resp);
3829 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3831 struct nfsctl_arg *karg = NULL;
3832 union nfsctl_res *kres = NULL;
3833 mm_segment_t oldfs;
3834 int err;
3836 karg = kmalloc(sizeof(*karg), GFP_USER);
3837 if(!karg)
3838 return -ENOMEM;
3839 if(res32) {
3840 kres = kmalloc(sizeof(*kres), GFP_USER);
3841 if(!kres) {
3842 kfree(karg);
3843 return -ENOMEM;
3846 switch(cmd) {
3847 case NFSCTL_SVC:
3848 err = nfs_svc32_trans(karg, arg32);
3849 break;
3850 case NFSCTL_ADDCLIENT:
3851 err = nfs_clnt32_trans(karg, arg32);
3852 break;
3853 case NFSCTL_DELCLIENT:
3854 err = nfs_clnt32_trans(karg, arg32);
3855 break;
3856 case NFSCTL_EXPORT:
3857 err = nfs_exp32_trans(karg, arg32);
3858 break;
3859 /* This one is unimplemented, be we're ready for it. */
3860 case NFSCTL_UGIDUPDATE:
3861 err = nfs_uud32_trans(karg, arg32);
3862 break;
3863 case NFSCTL_GETFH:
3864 err = nfs_getfh32_trans(karg, arg32);
3865 break;
3866 default:
3867 err = -EINVAL;
3868 break;
3870 if(err)
3871 goto done;
3872 oldfs = get_fs();
3873 set_fs(KERNEL_DS);
3874 err = sys_nfsservctl(cmd, karg, kres);
3875 set_fs(oldfs);
3877 if(!err && cmd == NFSCTL_GETFH)
3878 err = nfs_getfh32_res_trans(kres, res32);
3880 done:
3881 if(karg) {
3882 if(cmd == NFSCTL_UGIDUPDATE) {
3883 if(karg->ca_umap.ug_ident)
3884 kfree(karg->ca_umap.ug_ident);
3885 if(karg->ca_umap.ug_udimap)
3886 kfree(karg->ca_umap.ug_udimap);
3887 if(karg->ca_umap.ug_gdimap)
3888 kfree(karg->ca_umap.ug_gdimap);
3890 kfree(karg);
3892 if(kres)
3893 kfree(kres);
3894 return err;
3897 /* Translations due to time_t size differences. Which affects all
3898 sorts of things, like timeval and itimerval. */
3900 extern struct timezone sys_tz;
3901 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3903 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3905 if (tv) {
3906 struct timeval ktv;
3907 do_gettimeofday(&ktv);
3908 if (put_tv32(tv, &ktv))
3909 return -EFAULT;
3911 if (tz) {
3912 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3913 return -EFAULT;
3915 return 0;
3918 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3920 struct timeval ktv;
3921 struct timezone ktz;
3923 if (tv) {
3924 if (get_tv32(&ktv, tv))
3925 return -EFAULT;
3927 if (tz) {
3928 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3929 return -EFAULT;
3932 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3935 extern int do_getitimer(int which, struct itimerval *value);
3937 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3939 struct itimerval kit;
3940 int error;
3942 error = do_getitimer(which, &kit);
3943 if (!error && put_it32(it, &kit))
3944 error = -EFAULT;
3946 return error;
3949 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3951 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3953 struct itimerval kin, kout;
3954 int error;
3956 if (in) {
3957 if (get_it32(&kin, in))
3958 return -EFAULT;
3959 } else
3960 memset(&kin, 0, sizeof(kin));
3962 error = do_setitimer(which, &kin, out ? &kout : NULL);
3963 if (error || !out)
3964 return error;
3965 if (put_it32(out, &kout))
3966 return -EFAULT;
3968 return 0;
3972 asmlinkage int sys_utimes(char *, struct timeval *);
3974 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3976 char *kfilename;
3977 struct timeval ktvs[2];
3978 mm_segment_t old_fs;
3979 int ret;
3981 kfilename = getname32(filename);
3982 ret = PTR_ERR(kfilename);
3983 if (!IS_ERR(kfilename)) {
3984 if (tvs) {
3985 if (get_tv32(&ktvs[0], tvs) ||
3986 get_tv32(&ktvs[1], 1+tvs))
3987 return -EFAULT;
3990 old_fs = get_fs();
3991 set_fs(KERNEL_DS);
3992 ret = sys_utimes(kfilename, &ktvs[0]);
3993 set_fs(old_fs);
3995 putname(kfilename);
3997 return ret;
4000 /* These are here just in case some old sparc32 binary calls it. */
4001 asmlinkage int sys32_pause(void)
4003 current->state = TASK_INTERRUPTIBLE;
4004 schedule();
4005 return -ERESTARTNOHAND;
4008 /* PCI config space poking. */
4009 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
4010 unsigned long dfn,
4011 unsigned long off,
4012 unsigned long len,
4013 unsigned char *buf);
4015 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
4016 unsigned long dfn,
4017 unsigned long off,
4018 unsigned long len,
4019 unsigned char *buf);
4021 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
4023 return sys_pciconfig_read((unsigned long) bus,
4024 (unsigned long) dfn,
4025 (unsigned long) off,
4026 (unsigned long) len,
4027 (unsigned char *)AA(ubuf));
4030 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
4032 return sys_pciconfig_write((unsigned long) bus,
4033 (unsigned long) dfn,
4034 (unsigned long) off,
4035 (unsigned long) len,
4036 (unsigned char *)AA(ubuf));
4039 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
4040 unsigned long arg4, unsigned long arg5);
4042 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
4044 return sys_prctl(option,
4045 (unsigned long) arg2,
4046 (unsigned long) arg3,
4047 (unsigned long) arg4,
4048 (unsigned long) arg5);
4052 extern asmlinkage int sys_newuname(struct new_utsname * name);
4054 asmlinkage int sys32_newuname(struct new_utsname * name)
4056 int ret = sys_newuname(name);
4058 if (current->personality == PER_LINUX32 && !ret) {
4059 ret = copy_to_user(name->machine, "sparc\0\0", 8);
4061 return ret;
4064 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4065 size_t count, loff_t pos);
4067 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4068 size_t count, loff_t pos);
4070 typedef __kernel_ssize_t32 ssize_t32;
4072 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
4073 __kernel_size_t32 count, u32 poshi, u32 poslo)
4075 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4078 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
4079 __kernel_size_t32 count, u32 poshi, u32 poslo)
4081 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4085 extern asmlinkage long sys_personality(unsigned long);
4087 asmlinkage int sys32_personality(unsigned long personality)
4089 int ret;
4090 lock_kernel();
4091 if (current->personality == PER_LINUX32 && personality == PER_LINUX)
4092 personality = PER_LINUX32;
4093 ret = sys_personality(personality);
4094 unlock_kernel();
4095 if (ret == PER_LINUX32)
4096 ret = PER_LINUX;
4097 return ret;
4100 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4102 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4104 mm_segment_t old_fs = get_fs();
4105 int ret;
4106 off_t of;
4108 if (offset && get_user(of, offset))
4109 return -EFAULT;
4111 set_fs(KERNEL_DS);
4112 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4113 set_fs(old_fs);
4115 if (!ret && offset && put_user(of, offset))
4116 return -EFAULT;
4118 return ret;
4121 /* Handle adjtimex compatability. */
4123 struct timex32 {
4124 u32 modes;
4125 s32 offset, freq, maxerror, esterror;
4126 s32 status, constant, precision, tolerance;
4127 struct timeval32 time;
4128 s32 tick;
4129 s32 ppsfreq, jitter, shift, stabil;
4130 s32 jitcnt, calcnt, errcnt, stbcnt;
4131 s32 :32; s32 :32; s32 :32; s32 :32;
4132 s32 :32; s32 :32; s32 :32; s32 :32;
4133 s32 :32; s32 :32; s32 :32; s32 :32;
4136 extern int do_adjtimex(struct timex *);
4138 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4140 struct timex txc;
4141 int ret;
4143 memset(&txc, 0, sizeof(struct timex));
4145 if(get_user(txc.modes, &utp->modes) ||
4146 __get_user(txc.offset, &utp->offset) ||
4147 __get_user(txc.freq, &utp->freq) ||
4148 __get_user(txc.maxerror, &utp->maxerror) ||
4149 __get_user(txc.esterror, &utp->esterror) ||
4150 __get_user(txc.status, &utp->status) ||
4151 __get_user(txc.constant, &utp->constant) ||
4152 __get_user(txc.precision, &utp->precision) ||
4153 __get_user(txc.tolerance, &utp->tolerance) ||
4154 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4155 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4156 __get_user(txc.tick, &utp->tick) ||
4157 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4158 __get_user(txc.jitter, &utp->jitter) ||
4159 __get_user(txc.shift, &utp->shift) ||
4160 __get_user(txc.stabil, &utp->stabil) ||
4161 __get_user(txc.jitcnt, &utp->jitcnt) ||
4162 __get_user(txc.calcnt, &utp->calcnt) ||
4163 __get_user(txc.errcnt, &utp->errcnt) ||
4164 __get_user(txc.stbcnt, &utp->stbcnt))
4165 return -EFAULT;
4167 ret = do_adjtimex(&txc);
4169 if(put_user(txc.modes, &utp->modes) ||
4170 __put_user(txc.offset, &utp->offset) ||
4171 __put_user(txc.freq, &utp->freq) ||
4172 __put_user(txc.maxerror, &utp->maxerror) ||
4173 __put_user(txc.esterror, &utp->esterror) ||
4174 __put_user(txc.status, &utp->status) ||
4175 __put_user(txc.constant, &utp->constant) ||
4176 __put_user(txc.precision, &utp->precision) ||
4177 __put_user(txc.tolerance, &utp->tolerance) ||
4178 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4179 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4180 __put_user(txc.tick, &utp->tick) ||
4181 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4182 __put_user(txc.jitter, &utp->jitter) ||
4183 __put_user(txc.shift, &utp->shift) ||
4184 __put_user(txc.stabil, &utp->stabil) ||
4185 __put_user(txc.jitcnt, &utp->jitcnt) ||
4186 __put_user(txc.calcnt, &utp->calcnt) ||
4187 __put_user(txc.errcnt, &utp->errcnt) ||
4188 __put_user(txc.stbcnt, &utp->stbcnt))
4189 ret = -EFAULT;
4191 return ret;
4194 /* This is just a version for 32-bit applications which does
4195 * not force O_LARGEFILE on.
4198 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4200 char * tmp;
4201 int fd, error;
4203 tmp = getname(filename);
4204 fd = PTR_ERR(tmp);
4205 if (!IS_ERR(tmp)) {
4206 fd = get_unused_fd();
4207 if (fd >= 0) {
4208 struct file * f;
4209 lock_kernel();
4210 f = filp_open(tmp, flags, mode);
4211 unlock_kernel();
4212 error = PTR_ERR(f);
4213 if (IS_ERR(f))
4214 goto out_error;
4215 fd_install(fd, f);
4217 out:
4218 putname(tmp);
4220 return fd;
4222 out_error:
4223 put_unused_fd(fd);
4224 fd = error;
4225 goto out;