Import 2.3.41pre2
[davej-history.git] / arch / sparc64 / kernel / sys_sparc32.c
blob61b9a33977b31519fc37c96c3bc20a15ef792d44
1 /* $Id: sys_sparc32.c,v 1.131 2000/01/21 11:38:54 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;
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 extern int copy_siginfo_to_user32(siginfo_t32 *, siginfo_t *);
2108 if (copy_siginfo_to_user32(uinfo, &info))
2109 ret = -EFAULT;
2111 return ret;
2114 extern asmlinkage int
2115 sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
2117 asmlinkage int
2118 sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
2120 siginfo_t info;
2121 int ret;
2122 mm_segment_t old_fs = get_fs();
2124 if (copy_from_user (&info, uinfo, 3*sizeof(int)) ||
2125 copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
2126 return -EFAULT;
2127 set_fs (KERNEL_DS);
2128 ret = sys_rt_sigqueueinfo(pid, sig, &info);
2129 set_fs (old_fs);
2130 return ret;
2133 struct tms32 {
2134 __kernel_clock_t32 tms_utime;
2135 __kernel_clock_t32 tms_stime;
2136 __kernel_clock_t32 tms_cutime;
2137 __kernel_clock_t32 tms_cstime;
2140 extern asmlinkage long sys_times(struct tms * tbuf);
2142 asmlinkage long sys32_times(struct tms32 *tbuf)
2144 struct tms t;
2145 long ret;
2146 mm_segment_t old_fs = get_fs ();
2147 int err;
2149 set_fs (KERNEL_DS);
2150 ret = sys_times(tbuf ? &t : NULL);
2151 set_fs (old_fs);
2152 if (tbuf) {
2153 err = put_user (t.tms_utime, &tbuf->tms_utime);
2154 err |= __put_user (t.tms_stime, &tbuf->tms_stime);
2155 err |= __put_user (t.tms_cutime, &tbuf->tms_cutime);
2156 err |= __put_user (t.tms_cstime, &tbuf->tms_cstime);
2157 if (err)
2158 ret = -EFAULT;
2160 return ret;
2163 #define RLIM_INFINITY32 0x7fffffff
2164 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2166 struct rlimit32 {
2167 u32 rlim_cur;
2168 u32 rlim_max;
2171 extern asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim);
2173 asmlinkage int sys32_getrlimit(unsigned int resource, struct rlimit32 *rlim)
2175 struct rlimit r;
2176 int ret;
2177 mm_segment_t old_fs = get_fs ();
2179 set_fs (KERNEL_DS);
2180 ret = sys_getrlimit(resource, &r);
2181 set_fs (old_fs);
2182 if (!ret) {
2183 ret = put_user (RESOURCE32(r.rlim_cur), &rlim->rlim_cur);
2184 ret |= __put_user (RESOURCE32(r.rlim_max), &rlim->rlim_max);
2186 return ret;
2189 extern asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim);
2191 asmlinkage int sys32_setrlimit(unsigned int resource, struct rlimit32 *rlim)
2193 struct rlimit r;
2194 int ret;
2195 mm_segment_t old_fs = get_fs ();
2197 if (resource >= RLIM_NLIMITS) return -EINVAL;
2198 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
2199 __get_user (r.rlim_max, &rlim->rlim_max))
2200 return -EFAULT;
2201 if (r.rlim_cur == RLIM_INFINITY32)
2202 r.rlim_cur = RLIM_INFINITY;
2203 if (r.rlim_max == RLIM_INFINITY32)
2204 r.rlim_max = RLIM_INFINITY;
2205 set_fs (KERNEL_DS);
2206 ret = sys_setrlimit(resource, &r);
2207 set_fs (old_fs);
2208 return ret;
2211 extern asmlinkage int sys_getrusage(int who, struct rusage *ru);
2213 asmlinkage int sys32_getrusage(int who, struct rusage32 *ru)
2215 struct rusage r;
2216 int ret;
2217 mm_segment_t old_fs = get_fs();
2219 set_fs (KERNEL_DS);
2220 ret = sys_getrusage(who, &r);
2221 set_fs (old_fs);
2222 if (put_rusage (ru, &r)) return -EFAULT;
2223 return ret;
2226 /* XXX This really belongs in some header file... -DaveM */
2227 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2228 16 for IP, 16 for IPX,
2229 24 for IPv6,
2230 about 80 for AX.25 */
2232 /* XXX These as well... */
2233 extern __inline__ struct socket *socki_lookup(struct inode *inode)
2235 return &inode->u.socket_i;
2238 extern __inline__ struct socket *sockfd_lookup(int fd, int *err)
2240 struct file *file;
2241 struct inode *inode;
2243 if (!(file = fget(fd)))
2245 *err = -EBADF;
2246 return NULL;
2249 inode = file->f_dentry->d_inode;
2250 if (!inode || !inode->i_sock || !socki_lookup(inode))
2252 *err = -ENOTSOCK;
2253 fput(file);
2254 return NULL;
2257 return socki_lookup(inode);
2260 extern __inline__ void sockfd_put(struct socket *sock)
2262 fput(sock->file);
2265 struct msghdr32 {
2266 u32 msg_name;
2267 int msg_namelen;
2268 u32 msg_iov;
2269 __kernel_size_t32 msg_iovlen;
2270 u32 msg_control;
2271 __kernel_size_t32 msg_controllen;
2272 unsigned msg_flags;
2275 struct cmsghdr32 {
2276 __kernel_size_t32 cmsg_len;
2277 int cmsg_level;
2278 int cmsg_type;
2281 /* Bleech... */
2282 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2283 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2285 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2287 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2288 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2289 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2291 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2292 (struct cmsghdr32 *)(ctl) : \
2293 (struct cmsghdr32 *)NULL)
2294 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2296 __inline__ struct cmsghdr32 *__cmsg32_nxthdr(void *__ctl, __kernel_size_t __size,
2297 struct cmsghdr32 *__cmsg, int __cmsg_len)
2299 struct cmsghdr32 * __ptr;
2301 __ptr = (struct cmsghdr32 *)(((unsigned char *) __cmsg) +
2302 CMSG32_ALIGN(__cmsg_len));
2303 if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
2304 return NULL;
2306 return __ptr;
2309 __inline__ struct cmsghdr32 *cmsg32_nxthdr (struct msghdr *__msg,
2310 struct cmsghdr32 *__cmsg,
2311 int __cmsg_len)
2313 return __cmsg32_nxthdr(__msg->msg_control, __msg->msg_controllen,
2314 __cmsg, __cmsg_len);
2317 static inline int iov_from_user32_to_kern(struct iovec *kiov,
2318 struct iovec32 *uiov32,
2319 int niov)
2321 int tot_len = 0;
2323 while(niov > 0) {
2324 u32 len, buf;
2326 if(get_user(len, &uiov32->iov_len) ||
2327 get_user(buf, &uiov32->iov_base)) {
2328 tot_len = -EFAULT;
2329 break;
2331 tot_len += len;
2332 kiov->iov_base = (void *)A(buf);
2333 kiov->iov_len = (__kernel_size_t) len;
2334 uiov32++;
2335 kiov++;
2336 niov--;
2338 return tot_len;
2341 static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
2342 struct msghdr32 *umsg)
2344 u32 tmp1, tmp2, tmp3;
2345 int err;
2347 err = get_user(tmp1, &umsg->msg_name);
2348 err |= __get_user(tmp2, &umsg->msg_iov);
2349 err |= __get_user(tmp3, &umsg->msg_control);
2350 if (err)
2351 return -EFAULT;
2353 kmsg->msg_name = (void *)A(tmp1);
2354 kmsg->msg_iov = (struct iovec *)A(tmp2);
2355 kmsg->msg_control = (void *)A(tmp3);
2357 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
2358 err |= get_user(kmsg->msg_iovlen, &umsg->msg_iovlen);
2359 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
2360 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
2362 return err;
2365 /* I've named the args so it is easy to tell whose space the pointers are in. */
2366 static int verify_iovec32(struct msghdr *kern_msg, struct iovec *kern_iov,
2367 char *kern_address, int mode)
2369 int tot_len;
2371 if(kern_msg->msg_namelen) {
2372 if(mode==VERIFY_READ) {
2373 int err = move_addr_to_kernel(kern_msg->msg_name,
2374 kern_msg->msg_namelen,
2375 kern_address);
2376 if(err < 0)
2377 return err;
2379 kern_msg->msg_name = kern_address;
2380 } else
2381 kern_msg->msg_name = NULL;
2383 if(kern_msg->msg_iovlen > UIO_FASTIOV) {
2384 kern_iov = kmalloc(kern_msg->msg_iovlen * sizeof(struct iovec),
2385 GFP_KERNEL);
2386 if(!kern_iov)
2387 return -ENOMEM;
2390 tot_len = iov_from_user32_to_kern(kern_iov,
2391 (struct iovec32 *)kern_msg->msg_iov,
2392 kern_msg->msg_iovlen);
2393 if(tot_len >= 0)
2394 kern_msg->msg_iov = kern_iov;
2395 else if(kern_msg->msg_iovlen > UIO_FASTIOV)
2396 kfree(kern_iov);
2398 return tot_len;
2401 /* There is a lot of hair here because the alignment rules (and
2402 * thus placement) of cmsg headers and length are different for
2403 * 32-bit apps. -DaveM
2405 static int cmsghdr_from_user32_to_kern(struct msghdr *kmsg,
2406 unsigned char *stackbuf, int stackbuf_size)
2408 struct cmsghdr32 *ucmsg;
2409 struct cmsghdr *kcmsg, *kcmsg_base;
2410 __kernel_size_t32 ucmlen;
2411 __kernel_size_t kcmlen, tmp;
2413 kcmlen = 0;
2414 kcmsg_base = kcmsg = (struct cmsghdr *)stackbuf;
2415 ucmsg = CMSG32_FIRSTHDR(kmsg);
2416 while(ucmsg != NULL) {
2417 if(get_user(ucmlen, &ucmsg->cmsg_len))
2418 return -EFAULT;
2420 /* Catch bogons. */
2421 if(CMSG32_ALIGN(ucmlen) <
2422 CMSG32_ALIGN(sizeof(struct cmsghdr32)))
2423 return -EINVAL;
2424 if((unsigned long)(((char *)ucmsg - (char *)kmsg->msg_control)
2425 + ucmlen) > kmsg->msg_controllen)
2426 return -EINVAL;
2428 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2429 CMSG_ALIGN(sizeof(struct cmsghdr)));
2430 kcmlen += tmp;
2431 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2433 if(kcmlen == 0)
2434 return -EINVAL;
2436 /* The kcmlen holds the 64-bit version of the control length.
2437 * It may not be modified as we do not stick it into the kmsg
2438 * until we have successfully copied over all of the data
2439 * from the user.
2441 if(kcmlen > stackbuf_size)
2442 kcmsg_base = kcmsg = kmalloc(kcmlen, GFP_KERNEL);
2443 if(kcmsg == NULL)
2444 return -ENOBUFS;
2446 /* Now copy them over neatly. */
2447 memset(kcmsg, 0, kcmlen);
2448 ucmsg = CMSG32_FIRSTHDR(kmsg);
2449 while(ucmsg != NULL) {
2450 __get_user(ucmlen, &ucmsg->cmsg_len);
2451 tmp = ((ucmlen - CMSG32_ALIGN(sizeof(*ucmsg))) +
2452 CMSG_ALIGN(sizeof(struct cmsghdr)));
2453 kcmsg->cmsg_len = tmp;
2454 __get_user(kcmsg->cmsg_level, &ucmsg->cmsg_level);
2455 __get_user(kcmsg->cmsg_type, &ucmsg->cmsg_type);
2457 /* Copy over the data. */
2458 if(copy_from_user(CMSG_DATA(kcmsg),
2459 CMSG32_DATA(ucmsg),
2460 (ucmlen - CMSG32_ALIGN(sizeof(*ucmsg)))))
2461 goto out_free_efault;
2463 /* Advance. */
2464 kcmsg = (struct cmsghdr *)((char *)kcmsg + CMSG_ALIGN(tmp));
2465 ucmsg = CMSG32_NXTHDR(kmsg, ucmsg, ucmlen);
2468 /* Ok, looks like we made it. Hook it up and return success. */
2469 kmsg->msg_control = kcmsg_base;
2470 kmsg->msg_controllen = kcmlen;
2471 return 0;
2473 out_free_efault:
2474 if(kcmsg_base != (struct cmsghdr *)stackbuf)
2475 kfree(kcmsg_base);
2476 return -EFAULT;
2479 static void put_cmsg32(struct msghdr *kmsg, int level, int type,
2480 int len, void *data)
2482 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2483 struct cmsghdr32 cmhdr;
2484 int cmlen = CMSG32_LEN(len);
2486 if(cm == NULL || kmsg->msg_controllen < sizeof(*cm)) {
2487 kmsg->msg_flags |= MSG_CTRUNC;
2488 return;
2491 if(kmsg->msg_controllen < cmlen) {
2492 kmsg->msg_flags |= MSG_CTRUNC;
2493 cmlen = kmsg->msg_controllen;
2495 cmhdr.cmsg_level = level;
2496 cmhdr.cmsg_type = type;
2497 cmhdr.cmsg_len = cmlen;
2499 if(copy_to_user(cm, &cmhdr, sizeof cmhdr))
2500 return;
2501 if(copy_to_user(CMSG32_DATA(cm), data, cmlen - sizeof(struct cmsghdr32)))
2502 return;
2503 cmlen = CMSG32_SPACE(len);
2504 kmsg->msg_control += cmlen;
2505 kmsg->msg_controllen -= cmlen;
2508 static void scm_detach_fds32(struct msghdr *kmsg, struct scm_cookie *scm)
2510 struct cmsghdr32 *cm = (struct cmsghdr32 *) kmsg->msg_control;
2511 int fdmax = (kmsg->msg_controllen - sizeof(struct cmsghdr32)) / sizeof(int);
2512 int fdnum = scm->fp->count;
2513 struct file **fp = scm->fp->fp;
2514 int *cmfptr;
2515 int err = 0, i;
2517 if (fdnum < fdmax)
2518 fdmax = fdnum;
2520 for (i = 0, cmfptr = (int *) CMSG32_DATA(cm); i < fdmax; i++, cmfptr++) {
2521 int new_fd;
2522 err = get_unused_fd();
2523 if (err < 0)
2524 break;
2525 new_fd = err;
2526 err = put_user(new_fd, cmfptr);
2527 if (err) {
2528 put_unused_fd(new_fd);
2529 break;
2531 /* Bump the usage count and install the file. */
2532 get_file(fp[i]);
2533 fd_install(new_fd, fp[i]);
2536 if (i > 0) {
2537 int cmlen = CMSG32_LEN(i * sizeof(int));
2538 if (!err)
2539 err = put_user(SOL_SOCKET, &cm->cmsg_level);
2540 if (!err)
2541 err = put_user(SCM_RIGHTS, &cm->cmsg_type);
2542 if (!err)
2543 err = put_user(cmlen, &cm->cmsg_len);
2544 if (!err) {
2545 cmlen = CMSG32_SPACE(i * sizeof(int));
2546 kmsg->msg_control += cmlen;
2547 kmsg->msg_controllen -= cmlen;
2550 if (i < fdnum)
2551 kmsg->msg_flags |= MSG_CTRUNC;
2554 * All of the files that fit in the message have had their
2555 * usage counts incremented, so we just free the list.
2557 __scm_destroy(scm);
2560 /* In these cases we (currently) can just copy to data over verbatim
2561 * because all CMSGs created by the kernel have well defined types which
2562 * have the same layout in both the 32-bit and 64-bit API. One must add
2563 * some special cased conversions here if we start sending control messages
2564 * with incompatible types.
2566 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2567 * we do our work. The remaining cases are:
2569 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2570 * IP_TTL int 32-bit clean
2571 * IP_TOS __u8 32-bit clean
2572 * IP_RECVOPTS variable length 32-bit clean
2573 * IP_RETOPTS variable length 32-bit clean
2574 * (these last two are clean because the types are defined
2575 * by the IPv4 protocol)
2576 * IP_RECVERR struct sock_extended_err +
2577 * struct sockaddr_in 32-bit clean
2578 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2579 * struct sockaddr_in6 32-bit clean
2580 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2581 * IPV6_HOPLIMIT int 32-bit clean
2582 * IPV6_FLOWINFO u32 32-bit clean
2583 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2584 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2585 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2586 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2588 static void cmsg32_recvmsg_fixup(struct msghdr *kmsg, unsigned long orig_cmsg_uptr)
2590 unsigned char *workbuf, *wp;
2591 unsigned long bufsz, space_avail;
2592 struct cmsghdr *ucmsg;
2594 bufsz = ((unsigned long)kmsg->msg_control) - orig_cmsg_uptr;
2595 space_avail = kmsg->msg_controllen + bufsz;
2596 wp = workbuf = kmalloc(bufsz, GFP_KERNEL);
2597 if(workbuf == NULL)
2598 goto fail;
2600 /* To make this more sane we assume the kernel sends back properly
2601 * formatted control messages. Because of how the kernel will truncate
2602 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2604 ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
2605 while(((unsigned long)ucmsg) < ((unsigned long)kmsg->msg_control)) {
2606 struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
2607 int clen64, clen32;
2609 /* UCMSG is the 64-bit format CMSG entry in user-space.
2610 * KCMSG32 is within the kernel space temporary buffer
2611 * we use to convert into a 32-bit style CMSG.
2613 __get_user(kcmsg32->cmsg_len, &ucmsg->cmsg_len);
2614 __get_user(kcmsg32->cmsg_level, &ucmsg->cmsg_level);
2615 __get_user(kcmsg32->cmsg_type, &ucmsg->cmsg_type);
2617 clen64 = kcmsg32->cmsg_len;
2618 copy_from_user(CMSG32_DATA(kcmsg32), CMSG_DATA(ucmsg),
2619 clen64 - CMSG_ALIGN(sizeof(*ucmsg)));
2620 clen32 = ((clen64 - CMSG_ALIGN(sizeof(*ucmsg))) +
2621 CMSG32_ALIGN(sizeof(struct cmsghdr32)));
2622 kcmsg32->cmsg_len = clen32;
2624 ucmsg = (struct cmsghdr *) (((char *)ucmsg) + CMSG_ALIGN(clen64));
2625 wp = (((char *)kcmsg32) + CMSG32_ALIGN(clen32));
2628 /* Copy back fixed up data, and adjust pointers. */
2629 bufsz = (wp - workbuf);
2630 copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);
2632 kmsg->msg_control = (struct cmsghdr *)
2633 (((char *)orig_cmsg_uptr) + bufsz);
2634 kmsg->msg_controllen = space_avail - bufsz;
2636 kfree(workbuf);
2637 return;
2639 fail:
2640 /* If we leave the 64-bit format CMSG chunks in there,
2641 * the application could get confused and crash. So to
2642 * ensure greater recovery, we report no CMSGs.
2644 kmsg->msg_controllen += bufsz;
2645 kmsg->msg_control = (void *) orig_cmsg_uptr;
2648 asmlinkage int sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags)
2650 struct socket *sock;
2651 char address[MAX_SOCK_ADDR];
2652 struct iovec iov[UIO_FASTIOV];
2653 unsigned char ctl[sizeof(struct cmsghdr) + 20];
2654 unsigned char *ctl_buf = ctl;
2655 struct msghdr kern_msg;
2656 int err, total_len;
2658 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2659 return -EFAULT;
2660 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2661 return -EINVAL;
2662 err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);
2663 if (err < 0)
2664 goto out;
2665 total_len = err;
2667 if(kern_msg.msg_controllen) {
2668 err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));
2669 if(err)
2670 goto out_freeiov;
2671 ctl_buf = kern_msg.msg_control;
2673 kern_msg.msg_flags = user_flags;
2675 lock_kernel();
2676 sock = sockfd_lookup(fd, &err);
2677 if (sock != NULL) {
2678 if (sock->file->f_flags & O_NONBLOCK)
2679 kern_msg.msg_flags |= MSG_DONTWAIT;
2680 err = sock_sendmsg(sock, &kern_msg, total_len);
2681 sockfd_put(sock);
2683 unlock_kernel();
2685 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2686 if(ctl_buf != ctl)
2687 kfree(ctl_buf);
2688 out_freeiov:
2689 if(kern_msg.msg_iov != iov)
2690 kfree(kern_msg.msg_iov);
2691 out:
2692 return err;
2695 asmlinkage int sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags)
2697 struct iovec iovstack[UIO_FASTIOV];
2698 struct msghdr kern_msg;
2699 char addr[MAX_SOCK_ADDR];
2700 struct socket *sock;
2701 struct iovec *iov = iovstack;
2702 struct sockaddr *uaddr;
2703 int *uaddr_len;
2704 unsigned long cmsg_ptr;
2705 int err, total_len, len = 0;
2707 if(msghdr_from_user32_to_kern(&kern_msg, user_msg))
2708 return -EFAULT;
2709 if(kern_msg.msg_iovlen > UIO_MAXIOV)
2710 return -EINVAL;
2712 uaddr = kern_msg.msg_name;
2713 uaddr_len = &user_msg->msg_namelen;
2714 err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);
2715 if (err < 0)
2716 goto out;
2717 total_len = err;
2719 cmsg_ptr = (unsigned long) kern_msg.msg_control;
2720 kern_msg.msg_flags = 0;
2722 lock_kernel();
2723 sock = sockfd_lookup(fd, &err);
2724 if (sock != NULL) {
2725 struct scm_cookie scm;
2727 if (sock->file->f_flags & O_NONBLOCK)
2728 user_flags |= MSG_DONTWAIT;
2729 memset(&scm, 0, sizeof(scm));
2730 err = sock->ops->recvmsg(sock, &kern_msg, total_len,
2731 user_flags, &scm);
2732 if(err >= 0) {
2733 len = err;
2734 if(!kern_msg.msg_control) {
2735 if(sock->passcred || scm.fp)
2736 kern_msg.msg_flags |= MSG_CTRUNC;
2737 if(scm.fp)
2738 __scm_destroy(&scm);
2739 } else {
2740 /* If recvmsg processing itself placed some
2741 * control messages into user space, it's is
2742 * using 64-bit CMSG processing, so we need
2743 * to fix it up before we tack on more stuff.
2745 if((unsigned long) kern_msg.msg_control != cmsg_ptr)
2746 cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);
2748 /* Wheee... */
2749 if(sock->passcred)
2750 put_cmsg32(&kern_msg,
2751 SOL_SOCKET, SCM_CREDENTIALS,
2752 sizeof(scm.creds), &scm.creds);
2753 if(scm.fp != NULL)
2754 scm_detach_fds32(&kern_msg, &scm);
2757 sockfd_put(sock);
2759 unlock_kernel();
2761 if(uaddr != NULL && err >= 0)
2762 err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);
2763 if(cmsg_ptr != 0 && err >= 0) {
2764 unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);
2765 __kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);
2766 err |= __put_user(uclen, &user_msg->msg_controllen);
2768 if(err >= 0)
2769 err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);
2770 if(kern_msg.msg_iov != iov)
2771 kfree(kern_msg.msg_iov);
2772 out:
2773 if(err < 0)
2774 return err;
2775 return len;
2778 extern asmlinkage int sys_setsockopt(int fd, int level, int optname,
2779 char *optval, int optlen);
2781 asmlinkage int sys32_setsockopt(int fd, int level, int optname,
2782 char *optval, int optlen)
2784 if (optname == SO_ATTACH_FILTER) {
2785 struct sock_fprog32 {
2786 __u16 len;
2787 __u32 filter;
2788 } *fprog32 = (struct sock_fprog32 *)optval;
2789 struct sock_fprog kfprog;
2790 struct sock_filter *kfilter;
2791 unsigned int fsize;
2792 mm_segment_t old_fs;
2793 __u32 uptr;
2794 int ret;
2796 if (get_user(kfprog.len, &fprog32->len) ||
2797 __get_user(uptr, &fprog32->filter))
2798 return -EFAULT;
2799 kfprog.filter = (struct sock_filter *)A(uptr);
2800 fsize = kfprog.len * sizeof(struct sock_filter);
2801 kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
2802 if (kfilter == NULL)
2803 return -ENOMEM;
2804 if (copy_from_user(kfilter, kfprog.filter, fsize)) {
2805 kfree(kfilter);
2806 return -EFAULT;
2808 kfprog.filter = kfilter;
2809 old_fs = get_fs();
2810 set_fs(KERNEL_DS);
2811 ret = sys_setsockopt(fd, level, optname,
2812 (char *)&kfprog, sizeof(kfprog));
2813 set_fs(old_fs);
2814 kfree(kfilter);
2815 return ret;
2817 return sys_setsockopt(fd, level, optname, optval, optlen);
2820 /* Argument list sizes for sys_socketcall */
2821 #define AL(x) ((x) * sizeof(u32))
2822 static unsigned char nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),
2823 AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),
2824 AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};
2825 #undef AL
2827 extern asmlinkage int sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);
2828 extern asmlinkage int sys_connect(int fd, struct sockaddr *uservaddr, int addrlen);
2829 extern asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen);
2830 extern asmlinkage int sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
2831 extern asmlinkage int sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockaddr_len);
2832 extern asmlinkage int sys_send(int fd, void *buff, size_t len, unsigned flags);
2833 extern asmlinkage int sys32_sendto(int fd, u32 buff, __kernel_size_t32 len,
2834 unsigned flags, u32 addr, int addr_len);
2835 extern asmlinkage int sys_recv(int fd, void *ubuf, size_t size, unsigned flags);
2836 extern asmlinkage int sys32_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,
2837 unsigned flags, u32 addr, u32 addr_len);
2838 extern asmlinkage int sys32_getsockopt(int fd, int level, int optname,
2839 u32 optval, u32 optlen);
2841 extern asmlinkage int sys_socket(int family, int type, int protocol);
2842 extern asmlinkage int sys_socketpair(int family, int type, int protocol,
2843 int usockvec[2]);
2844 extern asmlinkage int sys_shutdown(int fd, int how);
2845 extern asmlinkage int sys_listen(int fd, int backlog);
2847 asmlinkage int sys32_socketcall(int call, u32 *args)
2849 u32 a[6];
2850 u32 a0,a1;
2852 if (call<SYS_SOCKET||call>SYS_RECVMSG)
2853 return -EINVAL;
2854 if (copy_from_user(a, args, nargs[call]))
2855 return -EFAULT;
2856 a0=a[0];
2857 a1=a[1];
2859 switch(call)
2861 case SYS_SOCKET:
2862 return sys_socket(a0, a1, a[2]);
2863 case SYS_BIND:
2864 return sys_bind(a0, (struct sockaddr *)A(a1), a[2]);
2865 case SYS_CONNECT:
2866 return sys_connect(a0, (struct sockaddr *)A(a1), a[2]);
2867 case SYS_LISTEN:
2868 return sys_listen(a0, a1);
2869 case SYS_ACCEPT:
2870 return sys_accept(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
2871 case SYS_GETSOCKNAME:
2872 return sys_getsockname(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
2873 case SYS_GETPEERNAME:
2874 return sys_getpeername(a0, (struct sockaddr *)A(a1), (int *)A(a[2]));
2875 case SYS_SOCKETPAIR:
2876 return sys_socketpair(a0, a1, a[2], (int *)A(a[3]));
2877 case SYS_SEND:
2878 return sys_send(a0, (void *)A(a1), a[2], a[3]);
2879 case SYS_SENDTO:
2880 return sys32_sendto(a0, a1, a[2], a[3], a[4], a[5]);
2881 case SYS_RECV:
2882 return sys_recv(a0, (void *)A(a1), a[2], a[3]);
2883 case SYS_RECVFROM:
2884 return sys32_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);
2885 case SYS_SHUTDOWN:
2886 return sys_shutdown(a0,a1);
2887 case SYS_SETSOCKOPT:
2888 return sys32_setsockopt(a0, a1, a[2], (char *)A(a[3]), a[4]);
2889 case SYS_GETSOCKOPT:
2890 return sys32_getsockopt(a0, a1, a[2], a[3], a[4]);
2891 case SYS_SENDMSG:
2892 return sys32_sendmsg(a0, (struct msghdr32 *)A(a1), a[2]);
2893 case SYS_RECVMSG:
2894 return sys32_recvmsg(a0, (struct msghdr32 *)A(a1), a[2]);
2896 return -EINVAL;
2899 extern void check_pending(int signum);
2901 asmlinkage int sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
2903 struct k_sigaction new_ka, old_ka;
2904 int ret;
2906 if(sig < 0) {
2907 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2908 sig = -sig;
2911 if (act) {
2912 old_sigset_t32 mask;
2914 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2915 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2916 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2917 ret |= __get_user(mask, &act->sa_mask);
2918 if (ret)
2919 return ret;
2920 new_ka.ka_restorer = NULL;
2921 siginitset(&new_ka.sa.sa_mask, mask);
2924 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2926 if (!ret && oact) {
2927 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2928 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2929 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2930 ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
2933 return ret;
2936 asmlinkage int
2937 sys32_rt_sigaction(int sig, struct sigaction32 *act, struct sigaction32 *oact,
2938 void *restorer, __kernel_size_t32 sigsetsize)
2940 struct k_sigaction new_ka, old_ka;
2941 int ret;
2942 sigset_t32 set32;
2944 /* XXX: Don't preclude handling different sized sigset_t's. */
2945 if (sigsetsize != sizeof(sigset_t32))
2946 return -EINVAL;
2948 /* All tasks which use RT signals (effectively) use
2949 * new style signals.
2951 current->thread.flags |= SPARC_FLAG_NEWSIGNALS;
2953 if (act) {
2954 new_ka.ka_restorer = restorer;
2955 ret = get_user((long)new_ka.sa.sa_handler, &act->sa_handler);
2956 ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(sigset_t32));
2957 switch (_NSIG_WORDS) {
2958 case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);
2959 case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);
2960 case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);
2961 case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);
2963 ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
2964 ret |= __get_user((long)new_ka.sa.sa_restorer, &act->sa_restorer);
2965 if (ret)
2966 return -EFAULT;
2969 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
2971 if (!ret && oact) {
2972 switch (_NSIG_WORDS) {
2973 case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];
2974 case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];
2975 case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];
2976 case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];
2978 ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler);
2979 ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(sigset_t32));
2980 ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
2981 ret |= __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer);
2984 return ret;
2989 * count32() counts the number of arguments/envelopes
2991 static int count32(u32 * argv)
2993 int i = 0;
2995 if (argv != NULL) {
2996 for (;;) {
2997 u32 p; int error;
2999 error = get_user(p,argv);
3000 if (error) return error;
3001 if (!p) break;
3002 argv++; i++;
3005 return i;
3009 * 'copy_string32()' copies argument/envelope strings from user
3010 * memory to free pages in kernel mem. These are in a format ready
3011 * to be put directly into the top of new user memory.
3013 static int copy_strings32(int argc, u32 * argv, struct linux_binprm *bprm)
3015 while (argc-- > 0) {
3016 u32 str;
3017 int len;
3018 unsigned long pos;
3020 if (get_user(str, argv + argc) ||
3021 !str ||
3022 !(len = strnlen_user((char *)A(str), bprm->p)))
3023 return -EFAULT;
3025 if (bprm->p < len)
3026 return -E2BIG;
3028 bprm->p -= len;
3030 pos = bprm->p;
3031 while (len) {
3032 char *kaddr;
3033 struct page *page;
3034 int offset, bytes_to_copy, new, err;
3036 offset = pos % PAGE_SIZE;
3037 page = bprm->page[pos / PAGE_SIZE];
3038 new = 0;
3039 if (!page) {
3040 page = alloc_page(GFP_USER);
3041 bprm->page[pos / PAGE_SIZE] = page;
3042 if (!page)
3043 return -ENOMEM;
3044 new = 1;
3046 kaddr = (char *)kmap(page);
3048 if (new && offset)
3049 memset(kaddr, 0, offset);
3050 bytes_to_copy = PAGE_SIZE - offset;
3051 if (bytes_to_copy > len) {
3052 bytes_to_copy = len;
3053 if (new)
3054 memset(kaddr+offset+len, 0,
3055 PAGE_SIZE-offset-len);
3058 err = copy_from_user(kaddr + offset, (char *)A(str),
3059 bytes_to_copy);
3060 flush_page_to_ram(page);
3061 kunmap((unsigned long)kaddr);
3063 if (err)
3064 return -EFAULT;
3066 pos += bytes_to_copy;
3067 str += bytes_to_copy;
3068 len -= bytes_to_copy;
3071 return 0;
3075 * sys32_execve() executes a new program.
3077 static inline int
3078 do_execve32(char * filename, u32 * argv, u32 * envp, struct pt_regs * regs)
3080 struct linux_binprm bprm;
3081 struct dentry * dentry;
3082 int retval;
3083 int i;
3085 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
3086 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
3088 dentry = open_namei(filename, 0, 0);
3089 retval = PTR_ERR(dentry);
3090 if (IS_ERR(dentry))
3091 return retval;
3093 bprm.dentry = dentry;
3094 bprm.filename = filename;
3095 bprm.sh_bang = 0;
3096 bprm.loader = 0;
3097 bprm.exec = 0;
3098 if ((bprm.argc = count32(argv)) < 0) {
3099 dput(dentry);
3100 return bprm.argc;
3102 if ((bprm.envc = count32(envp)) < 0) {
3103 dput(dentry);
3104 return bprm.envc;
3107 retval = prepare_binprm(&bprm);
3108 if (retval < 0)
3109 goto out;
3111 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
3112 if (retval < 0)
3113 goto out;
3115 bprm.exec = bprm.p;
3116 retval = copy_strings32(bprm.envc, envp, &bprm);
3117 if (retval < 0)
3118 goto out;
3120 retval = copy_strings32(bprm.argc, argv, &bprm);
3121 if (retval < 0)
3122 goto out;
3124 retval = search_binary_handler(&bprm, regs);
3125 if (retval >= 0)
3126 /* execve success */
3127 return retval;
3129 out:
3130 /* Something went wrong, return the inode and free the argument pages*/
3131 if (bprm.dentry)
3132 dput(bprm.dentry);
3134 for (i=0 ; i<MAX_ARG_PAGES ; i++)
3135 if (bprm.page[i])
3136 __free_page(bprm.page[i]);
3138 return retval;
3142 * sparc32_execve() executes a new program after the asm stub has set
3143 * things up for us. This should basically do what I want it to.
3145 asmlinkage int sparc32_execve(struct pt_regs *regs)
3147 int error, base = 0;
3148 char *filename;
3150 /* User register window flush is done by entry.S */
3152 /* Check for indirect call. */
3153 if((u32)regs->u_regs[UREG_G1] == 0)
3154 base = 1;
3156 lock_kernel();
3157 filename = getname32((char *)AA(regs->u_regs[base + UREG_I0]));
3158 error = PTR_ERR(filename);
3159 if(IS_ERR(filename))
3160 goto out;
3161 error = do_execve32(filename,
3162 (u32 *)AA((u32)regs->u_regs[base + UREG_I1]),
3163 (u32 *)AA((u32)regs->u_regs[base + UREG_I2]), regs);
3164 putname(filename);
3166 if(!error) {
3167 fprs_write(0);
3168 current->thread.xfsr[0] = 0;
3169 current->thread.fpsaved[0] = 0;
3170 regs->tstate &= ~TSTATE_PEF;
3172 out:
3173 unlock_kernel();
3174 return error;
3177 #ifdef CONFIG_MODULES
3179 extern asmlinkage unsigned long sys_create_module(const char *name_user, size_t size);
3181 asmlinkage unsigned long sys32_create_module(const char *name_user, __kernel_size_t32 size)
3183 return sys_create_module(name_user, (size_t)size);
3186 extern asmlinkage int sys_init_module(const char *name_user, struct module *mod_user);
3188 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3189 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3191 asmlinkage int sys32_init_module(const char *name_user, struct module *mod_user)
3193 return sys_init_module(name_user, mod_user);
3196 extern asmlinkage int sys_delete_module(const char *name_user);
3198 asmlinkage int sys32_delete_module(const char *name_user)
3200 return sys_delete_module(name_user);
3203 struct module_info32 {
3204 u32 addr;
3205 u32 size;
3206 u32 flags;
3207 s32 usecount;
3210 /* Query various bits about modules. */
3212 static inline long
3213 get_mod_name(const char *user_name, char **buf)
3215 unsigned long page;
3216 long retval;
3218 if ((unsigned long)user_name >= TASK_SIZE
3219 && !segment_eq(get_fs (), KERNEL_DS))
3220 return -EFAULT;
3222 page = __get_free_page(GFP_KERNEL);
3223 if (!page)
3224 return -ENOMEM;
3226 retval = strncpy_from_user((char *)page, user_name, PAGE_SIZE);
3227 if (retval > 0) {
3228 if (retval < PAGE_SIZE) {
3229 *buf = (char *)page;
3230 return retval;
3232 retval = -ENAMETOOLONG;
3233 } else if (!retval)
3234 retval = -EINVAL;
3236 free_page(page);
3237 return retval;
3240 static inline void
3241 put_mod_name(char *buf)
3243 free_page((unsigned long)buf);
3246 static __inline__ struct module *find_module(const char *name)
3248 struct module *mod;
3250 for (mod = module_list; mod ; mod = mod->next) {
3251 if (mod->flags & MOD_DELETED)
3252 continue;
3253 if (!strcmp(mod->name, name))
3254 break;
3257 return mod;
3260 static int
3261 qm_modules(char *buf, size_t bufsize, __kernel_size_t32 *ret)
3263 struct module *mod;
3264 size_t nmod, space, len;
3266 nmod = space = 0;
3268 for (mod = module_list; mod->next != NULL; mod = mod->next, ++nmod) {
3269 len = strlen(mod->name)+1;
3270 if (len > bufsize)
3271 goto calc_space_needed;
3272 if (copy_to_user(buf, mod->name, len))
3273 return -EFAULT;
3274 buf += len;
3275 bufsize -= len;
3276 space += len;
3279 if (put_user(nmod, ret))
3280 return -EFAULT;
3281 else
3282 return 0;
3284 calc_space_needed:
3285 space += len;
3286 while ((mod = mod->next)->next != NULL)
3287 space += strlen(mod->name)+1;
3289 if (put_user(space, ret))
3290 return -EFAULT;
3291 else
3292 return -ENOSPC;
3295 static int
3296 qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3298 size_t i, space, len;
3300 if (mod->next == NULL)
3301 return -EINVAL;
3302 if (!MOD_CAN_QUERY(mod))
3303 return put_user(0, ret);
3305 space = 0;
3306 for (i = 0; i < mod->ndeps; ++i) {
3307 const char *dep_name = mod->deps[i].dep->name;
3309 len = strlen(dep_name)+1;
3310 if (len > bufsize)
3311 goto calc_space_needed;
3312 if (copy_to_user(buf, dep_name, len))
3313 return -EFAULT;
3314 buf += len;
3315 bufsize -= len;
3316 space += len;
3319 return put_user(i, ret);
3321 calc_space_needed:
3322 space += len;
3323 while (++i < mod->ndeps)
3324 space += strlen(mod->deps[i].dep->name)+1;
3326 if (put_user(space, ret))
3327 return -EFAULT;
3328 else
3329 return -ENOSPC;
3332 static int
3333 qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3335 size_t nrefs, space, len;
3336 struct module_ref *ref;
3338 if (mod->next == NULL)
3339 return -EINVAL;
3340 if (!MOD_CAN_QUERY(mod))
3341 if (put_user(0, ret))
3342 return -EFAULT;
3343 else
3344 return 0;
3346 space = 0;
3347 for (nrefs = 0, ref = mod->refs; ref ; ++nrefs, ref = ref->next_ref) {
3348 const char *ref_name = ref->ref->name;
3350 len = strlen(ref_name)+1;
3351 if (len > bufsize)
3352 goto calc_space_needed;
3353 if (copy_to_user(buf, ref_name, len))
3354 return -EFAULT;
3355 buf += len;
3356 bufsize -= len;
3357 space += len;
3360 if (put_user(nrefs, ret))
3361 return -EFAULT;
3362 else
3363 return 0;
3365 calc_space_needed:
3366 space += len;
3367 while ((ref = ref->next_ref) != NULL)
3368 space += strlen(ref->ref->name)+1;
3370 if (put_user(space, ret))
3371 return -EFAULT;
3372 else
3373 return -ENOSPC;
3376 static inline int
3377 qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3379 size_t i, space, len;
3380 struct module_symbol *s;
3381 char *strings;
3382 unsigned *vals;
3384 if (!MOD_CAN_QUERY(mod))
3385 if (put_user(0, ret))
3386 return -EFAULT;
3387 else
3388 return 0;
3390 space = mod->nsyms * 2*sizeof(u32);
3392 i = len = 0;
3393 s = mod->syms;
3395 if (space > bufsize)
3396 goto calc_space_needed;
3398 if (!access_ok(VERIFY_WRITE, buf, space))
3399 return -EFAULT;
3401 bufsize -= space;
3402 vals = (unsigned *)buf;
3403 strings = buf+space;
3405 for (; i < mod->nsyms ; ++i, ++s, vals += 2) {
3406 len = strlen(s->name)+1;
3407 if (len > bufsize)
3408 goto calc_space_needed;
3410 if (copy_to_user(strings, s->name, len)
3411 || __put_user(s->value, vals+0)
3412 || __put_user(space, vals+1))
3413 return -EFAULT;
3415 strings += len;
3416 bufsize -= len;
3417 space += len;
3420 if (put_user(i, ret))
3421 return -EFAULT;
3422 else
3423 return 0;
3425 calc_space_needed:
3426 for (; i < mod->nsyms; ++i, ++s)
3427 space += strlen(s->name)+1;
3429 if (put_user(space, ret))
3430 return -EFAULT;
3431 else
3432 return -ENOSPC;
3435 static inline int
3436 qm_info(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
3438 int error = 0;
3440 if (mod->next == NULL)
3441 return -EINVAL;
3443 if (sizeof(struct module_info32) <= bufsize) {
3444 struct module_info32 info;
3445 info.addr = (unsigned long)mod;
3446 info.size = mod->size;
3447 info.flags = mod->flags;
3448 info.usecount =
3449 ((mod_member_present(mod, can_unload)
3450 && mod->can_unload)
3451 ? -1 : atomic_read(&mod->uc.usecount));
3453 if (copy_to_user(buf, &info, sizeof(struct module_info32)))
3454 return -EFAULT;
3455 } else
3456 error = -ENOSPC;
3458 if (put_user(sizeof(struct module_info32), ret))
3459 return -EFAULT;
3461 return error;
3464 asmlinkage int sys32_query_module(char *name_user, int which, char *buf, __kernel_size_t32 bufsize, u32 ret)
3466 struct module *mod;
3467 int err;
3469 lock_kernel();
3470 if (name_user == 0) {
3471 /* This finds "kernel_module" which is not exported. */
3472 for(mod = module_list; mod->next != NULL; mod = mod->next)
3474 } else {
3475 long namelen;
3476 char *name;
3478 if ((namelen = get_mod_name(name_user, &name)) < 0) {
3479 err = namelen;
3480 goto out;
3482 err = -ENOENT;
3483 if (namelen == 0) {
3484 /* This finds "kernel_module" which is not exported. */
3485 for(mod = module_list; mod->next != NULL; mod = mod->next)
3487 } else if ((mod = find_module(name)) == NULL) {
3488 put_mod_name(name);
3489 goto out;
3491 put_mod_name(name);
3494 switch (which)
3496 case 0:
3497 err = 0;
3498 break;
3499 case QM_MODULES:
3500 err = qm_modules(buf, bufsize, (__kernel_size_t32 *)AA(ret));
3501 break;
3502 case QM_DEPS:
3503 err = qm_deps(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3504 break;
3505 case QM_REFS:
3506 err = qm_refs(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3507 break;
3508 case QM_SYMBOLS:
3509 err = qm_symbols(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3510 break;
3511 case QM_INFO:
3512 err = qm_info(mod, buf, bufsize, (__kernel_size_t32 *)AA(ret));
3513 break;
3514 default:
3515 err = -EINVAL;
3516 break;
3518 out:
3519 unlock_kernel();
3520 return err;
3523 struct kernel_sym32 {
3524 u32 value;
3525 char name[60];
3528 extern asmlinkage int sys_get_kernel_syms(struct kernel_sym *table);
3530 asmlinkage int sys32_get_kernel_syms(struct kernel_sym32 *table)
3532 int len, i;
3533 struct kernel_sym *tbl;
3534 mm_segment_t old_fs;
3536 len = sys_get_kernel_syms(NULL);
3537 if (!table) return len;
3538 tbl = kmalloc (len * sizeof (struct kernel_sym), GFP_KERNEL);
3539 if (!tbl) return -ENOMEM;
3540 old_fs = get_fs();
3541 set_fs (KERNEL_DS);
3542 sys_get_kernel_syms(tbl);
3543 set_fs (old_fs);
3544 for (i = 0; i < len; i++, table += sizeof (struct kernel_sym32)) {
3545 if (put_user (tbl[i].value, &table->value) ||
3546 copy_to_user (table->name, tbl[i].name, 60))
3547 break;
3549 kfree (tbl);
3550 return i;
3553 #else /* CONFIG_MODULES */
3555 asmlinkage unsigned long
3556 sys32_create_module(const char *name_user, size_t size)
3558 return -ENOSYS;
3561 asmlinkage int
3562 sys32_init_module(const char *name_user, struct module *mod_user)
3564 return -ENOSYS;
3567 asmlinkage int
3568 sys32_delete_module(const char *name_user)
3570 return -ENOSYS;
3573 asmlinkage int
3574 sys32_query_module(const char *name_user, int which, char *buf, size_t bufsize,
3575 size_t *ret)
3577 /* Let the program know about the new interface. Not that
3578 it'll do them much good. */
3579 if (which == 0)
3580 return 0;
3582 return -ENOSYS;
3585 asmlinkage int
3586 sys32_get_kernel_syms(struct kernel_sym *table)
3588 return -ENOSYS;
3591 #endif /* CONFIG_MODULES */
3593 /* Stuff for NFS server syscalls... */
3594 struct nfsctl_svc32 {
3595 u16 svc32_port;
3596 s32 svc32_nthreads;
3599 struct nfsctl_client32 {
3600 s8 cl32_ident[NFSCLNT_IDMAX+1];
3601 s32 cl32_naddr;
3602 struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
3603 s32 cl32_fhkeytype;
3604 s32 cl32_fhkeylen;
3605 u8 cl32_fhkey[NFSCLNT_KEYMAX];
3608 struct nfsctl_export32 {
3609 s8 ex32_client[NFSCLNT_IDMAX+1];
3610 s8 ex32_path[NFS_MAXPATHLEN+1];
3611 __kernel_dev_t32 ex32_dev;
3612 __kernel_ino_t32 ex32_ino;
3613 s32 ex32_flags;
3614 __kernel_uid_t32 ex32_anon_uid;
3615 __kernel_gid_t32 ex32_anon_gid;
3618 struct nfsctl_uidmap32 {
3619 u32 ug32_ident; /* char * */
3620 __kernel_uid_t32 ug32_uidbase;
3621 s32 ug32_uidlen;
3622 u32 ug32_udimap; /* uid_t * */
3623 __kernel_uid_t32 ug32_gidbase;
3624 s32 ug32_gidlen;
3625 u32 ug32_gdimap; /* gid_t * */
3628 struct nfsctl_fhparm32 {
3629 struct sockaddr gf32_addr;
3630 __kernel_dev_t32 gf32_dev;
3631 __kernel_ino_t32 gf32_ino;
3632 s32 gf32_version;
3635 struct nfsctl_arg32 {
3636 s32 ca32_version; /* safeguard */
3637 union {
3638 struct nfsctl_svc32 u32_svc;
3639 struct nfsctl_client32 u32_client;
3640 struct nfsctl_export32 u32_export;
3641 struct nfsctl_uidmap32 u32_umap;
3642 struct nfsctl_fhparm32 u32_getfh;
3643 u32 u32_debug;
3644 } u;
3645 #define ca32_svc u.u32_svc
3646 #define ca32_client u.u32_client
3647 #define ca32_export u.u32_export
3648 #define ca32_umap u.u32_umap
3649 #define ca32_getfh u.u32_getfh
3650 #define ca32_authd u.u32_authd
3651 #define ca32_debug u.u32_debug
3654 union nfsctl_res32 {
3655 struct knfs_fh cr32_getfh;
3656 u32 cr32_debug;
3659 static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3661 int err;
3663 err = __get_user(karg->ca_version, &arg32->ca32_version);
3664 err |= __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port);
3665 err |= __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads);
3666 return err;
3669 static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3671 int err;
3673 err = __get_user(karg->ca_version, &arg32->ca32_version);
3674 err |= copy_from_user(&karg->ca_client.cl_ident[0],
3675 &arg32->ca32_client.cl32_ident[0],
3676 NFSCLNT_IDMAX);
3677 err |= __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr);
3678 err |= copy_from_user(&karg->ca_client.cl_addrlist[0],
3679 &arg32->ca32_client.cl32_addrlist[0],
3680 (sizeof(struct in_addr) * NFSCLNT_ADDRMAX));
3681 err |= __get_user(karg->ca_client.cl_fhkeytype,
3682 &arg32->ca32_client.cl32_fhkeytype);
3683 err |= __get_user(karg->ca_client.cl_fhkeylen,
3684 &arg32->ca32_client.cl32_fhkeylen);
3685 err |= copy_from_user(&karg->ca_client.cl_fhkey[0],
3686 &arg32->ca32_client.cl32_fhkey[0],
3687 NFSCLNT_KEYMAX);
3688 return err;
3691 static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3693 int err;
3695 err = __get_user(karg->ca_version, &arg32->ca32_version);
3696 err |= copy_from_user(&karg->ca_export.ex_client[0],
3697 &arg32->ca32_export.ex32_client[0],
3698 NFSCLNT_IDMAX);
3699 err |= copy_from_user(&karg->ca_export.ex_path[0],
3700 &arg32->ca32_export.ex32_path[0],
3701 NFS_MAXPATHLEN);
3702 err |= __get_user(karg->ca_export.ex_dev,
3703 &arg32->ca32_export.ex32_dev);
3704 err |= __get_user(karg->ca_export.ex_ino,
3705 &arg32->ca32_export.ex32_ino);
3706 err |= __get_user(karg->ca_export.ex_flags,
3707 &arg32->ca32_export.ex32_flags);
3708 err |= __get_user(karg->ca_export.ex_anon_uid,
3709 &arg32->ca32_export.ex32_anon_uid);
3710 err |= __get_user(karg->ca_export.ex_anon_gid,
3711 &arg32->ca32_export.ex32_anon_gid);
3712 karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
3713 karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
3714 return err;
3717 static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3719 u32 uaddr;
3720 int i;
3721 int err;
3723 memset(karg, 0, sizeof(*karg));
3724 if(__get_user(karg->ca_version, &arg32->ca32_version))
3725 return -EFAULT;
3726 karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
3727 if(!karg->ca_umap.ug_ident)
3728 return -ENOMEM;
3729 err = __get_user(uaddr, &arg32->ca32_umap.ug32_ident);
3730 if(strncpy_from_user(karg->ca_umap.ug_ident,
3731 (char *)A(uaddr), PAGE_SIZE) <= 0)
3732 return -EFAULT;
3733 err |= __get_user(karg->ca_umap.ug_uidbase,
3734 &arg32->ca32_umap.ug32_uidbase);
3735 err |= __get_user(karg->ca_umap.ug_uidlen,
3736 &arg32->ca32_umap.ug32_uidlen);
3737 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_udimap);
3738 if (err)
3739 return -EFAULT;
3740 karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
3741 GFP_USER);
3742 if(!karg->ca_umap.ug_udimap)
3743 return -ENOMEM;
3744 for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
3745 err |= __get_user(karg->ca_umap.ug_udimap[i],
3746 &(((__kernel_uid_t32 *)A(uaddr))[i]));
3747 err |= __get_user(karg->ca_umap.ug_gidbase,
3748 &arg32->ca32_umap.ug32_gidbase);
3749 err |= __get_user(karg->ca_umap.ug_uidlen,
3750 &arg32->ca32_umap.ug32_gidlen);
3751 err |= __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap);
3752 if (err)
3753 return -EFAULT;
3754 karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
3755 GFP_USER);
3756 if(!karg->ca_umap.ug_gdimap)
3757 return -ENOMEM;
3758 for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
3759 err |= __get_user(karg->ca_umap.ug_gdimap[i],
3760 &(((__kernel_gid_t32 *)A(uaddr))[i]));
3762 return err;
3765 static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
3767 int err;
3769 err = __get_user(karg->ca_version, &arg32->ca32_version);
3770 err |= copy_from_user(&karg->ca_getfh.gf_addr,
3771 &arg32->ca32_getfh.gf32_addr,
3772 (sizeof(struct sockaddr)));
3773 err |= __get_user(karg->ca_getfh.gf_dev,
3774 &arg32->ca32_getfh.gf32_dev);
3775 err |= __get_user(karg->ca_getfh.gf_ino,
3776 &arg32->ca32_getfh.gf32_ino);
3777 err |= __get_user(karg->ca_getfh.gf_version,
3778 &arg32->ca32_getfh.gf32_version);
3779 return err;
3782 static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
3784 int err;
3786 err = copy_to_user(&res32->cr32_getfh,
3787 &kres->cr_getfh,
3788 sizeof(res32->cr32_getfh));
3789 err |= __put_user(kres->cr_debug, &res32->cr32_debug);
3790 return err;
3793 extern asmlinkage int sys_nfsservctl(int cmd, void *arg, void *resp);
3795 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
3797 struct nfsctl_arg *karg = NULL;
3798 union nfsctl_res *kres = NULL;
3799 mm_segment_t oldfs;
3800 int err;
3802 karg = kmalloc(sizeof(*karg), GFP_USER);
3803 if(!karg)
3804 return -ENOMEM;
3805 if(res32) {
3806 kres = kmalloc(sizeof(*kres), GFP_USER);
3807 if(!kres) {
3808 kfree(karg);
3809 return -ENOMEM;
3812 switch(cmd) {
3813 case NFSCTL_SVC:
3814 err = nfs_svc32_trans(karg, arg32);
3815 break;
3816 case NFSCTL_ADDCLIENT:
3817 err = nfs_clnt32_trans(karg, arg32);
3818 break;
3819 case NFSCTL_DELCLIENT:
3820 err = nfs_clnt32_trans(karg, arg32);
3821 break;
3822 case NFSCTL_EXPORT:
3823 err = nfs_exp32_trans(karg, arg32);
3824 break;
3825 /* This one is unimplemented, be we're ready for it. */
3826 case NFSCTL_UGIDUPDATE:
3827 err = nfs_uud32_trans(karg, arg32);
3828 break;
3829 case NFSCTL_GETFH:
3830 err = nfs_getfh32_trans(karg, arg32);
3831 break;
3832 default:
3833 err = -EINVAL;
3834 break;
3836 if(err)
3837 goto done;
3838 oldfs = get_fs();
3839 set_fs(KERNEL_DS);
3840 err = sys_nfsservctl(cmd, karg, kres);
3841 set_fs(oldfs);
3843 if(!err && cmd == NFSCTL_GETFH)
3844 err = nfs_getfh32_res_trans(kres, res32);
3846 done:
3847 if(karg) {
3848 if(cmd == NFSCTL_UGIDUPDATE) {
3849 if(karg->ca_umap.ug_ident)
3850 kfree(karg->ca_umap.ug_ident);
3851 if(karg->ca_umap.ug_udimap)
3852 kfree(karg->ca_umap.ug_udimap);
3853 if(karg->ca_umap.ug_gdimap)
3854 kfree(karg->ca_umap.ug_gdimap);
3856 kfree(karg);
3858 if(kres)
3859 kfree(kres);
3860 return err;
3863 /* Translations due to time_t size differences. Which affects all
3864 sorts of things, like timeval and itimerval. */
3866 extern struct timezone sys_tz;
3867 extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
3869 asmlinkage int sys32_gettimeofday(struct timeval32 *tv, struct timezone *tz)
3871 if (tv) {
3872 struct timeval ktv;
3873 do_gettimeofday(&ktv);
3874 if (put_tv32(tv, &ktv))
3875 return -EFAULT;
3877 if (tz) {
3878 if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
3879 return -EFAULT;
3881 return 0;
3884 asmlinkage int sys32_settimeofday(struct timeval32 *tv, struct timezone *tz)
3886 struct timeval ktv;
3887 struct timezone ktz;
3889 if (tv) {
3890 if (get_tv32(&ktv, tv))
3891 return -EFAULT;
3893 if (tz) {
3894 if (copy_from_user(&ktz, tz, sizeof(ktz)))
3895 return -EFAULT;
3898 return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
3901 extern int do_getitimer(int which, struct itimerval *value);
3903 asmlinkage int sys32_getitimer(int which, struct itimerval32 *it)
3905 struct itimerval kit;
3906 int error;
3908 error = do_getitimer(which, &kit);
3909 if (!error && put_it32(it, &kit))
3910 error = -EFAULT;
3912 return error;
3915 extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
3917 asmlinkage int sys32_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
3919 struct itimerval kin, kout;
3920 int error;
3922 if (in) {
3923 if (get_it32(&kin, in))
3924 return -EFAULT;
3925 } else
3926 memset(&kin, 0, sizeof(kin));
3928 error = do_setitimer(which, &kin, out ? &kout : NULL);
3929 if (error || !out)
3930 return error;
3931 if (put_it32(out, &kout))
3932 return -EFAULT;
3934 return 0;
3938 asmlinkage int sys_utimes(char *, struct timeval *);
3940 asmlinkage int sys32_utimes(char *filename, struct timeval32 *tvs)
3942 char *kfilename;
3943 struct timeval ktvs[2];
3944 mm_segment_t old_fs;
3945 int ret;
3947 kfilename = getname32(filename);
3948 ret = PTR_ERR(kfilename);
3949 if (!IS_ERR(kfilename)) {
3950 if (tvs) {
3951 if (get_tv32(&ktvs[0], tvs) ||
3952 get_tv32(&ktvs[1], 1+tvs))
3953 return -EFAULT;
3956 old_fs = get_fs();
3957 set_fs(KERNEL_DS);
3958 ret = sys_utimes(kfilename, &ktvs[0]);
3959 set_fs(old_fs);
3961 putname(kfilename);
3963 return ret;
3966 /* These are here just in case some old sparc32 binary calls it. */
3967 asmlinkage int sys32_pause(void)
3969 current->state = TASK_INTERRUPTIBLE;
3970 schedule();
3971 return -ERESTARTNOHAND;
3974 /* PCI config space poking. */
3975 extern asmlinkage int sys_pciconfig_read(unsigned long bus,
3976 unsigned long dfn,
3977 unsigned long off,
3978 unsigned long len,
3979 unsigned char *buf);
3981 extern asmlinkage int sys_pciconfig_write(unsigned long bus,
3982 unsigned long dfn,
3983 unsigned long off,
3984 unsigned long len,
3985 unsigned char *buf);
3987 asmlinkage int sys32_pciconfig_read(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3989 return sys_pciconfig_read((unsigned long) bus,
3990 (unsigned long) dfn,
3991 (unsigned long) off,
3992 (unsigned long) len,
3993 (unsigned char *)AA(ubuf));
3996 asmlinkage int sys32_pciconfig_write(u32 bus, u32 dfn, u32 off, u32 len, u32 ubuf)
3998 return sys_pciconfig_write((unsigned long) bus,
3999 (unsigned long) dfn,
4000 (unsigned long) off,
4001 (unsigned long) len,
4002 (unsigned char *)AA(ubuf));
4005 extern asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
4006 unsigned long arg4, unsigned long arg5);
4008 asmlinkage int sys32_prctl(int option, u32 arg2, u32 arg3, u32 arg4, u32 arg5)
4010 return sys_prctl(option,
4011 (unsigned long) arg2,
4012 (unsigned long) arg3,
4013 (unsigned long) arg4,
4014 (unsigned long) arg5);
4018 extern asmlinkage int sys_newuname(struct new_utsname * name);
4020 asmlinkage int sys32_newuname(struct new_utsname * name)
4022 int ret = sys_newuname(name);
4024 if (current->personality == PER_LINUX32 && !ret) {
4025 ret = copy_to_user(name->machine, "sparc\0\0", 8);
4027 return ret;
4030 extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,
4031 size_t count, loff_t pos);
4033 extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,
4034 size_t count, loff_t pos);
4036 typedef __kernel_ssize_t32 ssize_t32;
4038 asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
4039 __kernel_size_t32 count, u32 poshi, u32 poslo)
4041 return sys_pread(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4044 asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
4045 __kernel_size_t32 count, u32 poshi, u32 poslo)
4047 return sys_pwrite(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
4051 extern asmlinkage long sys_personality(unsigned long);
4053 asmlinkage int sys32_personality(unsigned long personality)
4055 int ret;
4056 lock_kernel();
4057 if (current->personality == PER_LINUX32 && personality == PER_LINUX)
4058 personality = PER_LINUX32;
4059 ret = sys_personality(personality);
4060 unlock_kernel();
4061 if (ret == PER_LINUX32)
4062 ret = PER_LINUX;
4063 return ret;
4066 extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
4068 asmlinkage int sys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 count)
4070 mm_segment_t old_fs = get_fs();
4071 int ret;
4072 off_t of;
4074 if (offset && get_user(of, offset))
4075 return -EFAULT;
4077 set_fs(KERNEL_DS);
4078 ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count);
4079 set_fs(old_fs);
4081 if (!ret && offset && put_user(of, offset))
4082 return -EFAULT;
4084 return ret;
4087 /* Handle adjtimex compatability. */
4089 struct timex32 {
4090 u32 modes;
4091 s32 offset, freq, maxerror, esterror;
4092 s32 status, constant, precision, tolerance;
4093 struct timeval32 time;
4094 s32 tick;
4095 s32 ppsfreq, jitter, shift, stabil;
4096 s32 jitcnt, calcnt, errcnt, stbcnt;
4097 s32 :32; s32 :32; s32 :32; s32 :32;
4098 s32 :32; s32 :32; s32 :32; s32 :32;
4099 s32 :32; s32 :32; s32 :32; s32 :32;
4102 extern int do_adjtimex(struct timex *);
4104 asmlinkage int sys32_adjtimex(struct timex32 *utp)
4106 struct timex txc;
4107 int ret;
4109 memset(&txc, 0, sizeof(struct timex));
4111 if(get_user(txc.modes, &utp->modes) ||
4112 __get_user(txc.offset, &utp->offset) ||
4113 __get_user(txc.freq, &utp->freq) ||
4114 __get_user(txc.maxerror, &utp->maxerror) ||
4115 __get_user(txc.esterror, &utp->esterror) ||
4116 __get_user(txc.status, &utp->status) ||
4117 __get_user(txc.constant, &utp->constant) ||
4118 __get_user(txc.precision, &utp->precision) ||
4119 __get_user(txc.tolerance, &utp->tolerance) ||
4120 __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4121 __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4122 __get_user(txc.tick, &utp->tick) ||
4123 __get_user(txc.ppsfreq, &utp->ppsfreq) ||
4124 __get_user(txc.jitter, &utp->jitter) ||
4125 __get_user(txc.shift, &utp->shift) ||
4126 __get_user(txc.stabil, &utp->stabil) ||
4127 __get_user(txc.jitcnt, &utp->jitcnt) ||
4128 __get_user(txc.calcnt, &utp->calcnt) ||
4129 __get_user(txc.errcnt, &utp->errcnt) ||
4130 __get_user(txc.stbcnt, &utp->stbcnt))
4131 return -EFAULT;
4133 ret = do_adjtimex(&txc);
4135 if(put_user(txc.modes, &utp->modes) ||
4136 __put_user(txc.offset, &utp->offset) ||
4137 __put_user(txc.freq, &utp->freq) ||
4138 __put_user(txc.maxerror, &utp->maxerror) ||
4139 __put_user(txc.esterror, &utp->esterror) ||
4140 __put_user(txc.status, &utp->status) ||
4141 __put_user(txc.constant, &utp->constant) ||
4142 __put_user(txc.precision, &utp->precision) ||
4143 __put_user(txc.tolerance, &utp->tolerance) ||
4144 __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
4145 __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
4146 __put_user(txc.tick, &utp->tick) ||
4147 __put_user(txc.ppsfreq, &utp->ppsfreq) ||
4148 __put_user(txc.jitter, &utp->jitter) ||
4149 __put_user(txc.shift, &utp->shift) ||
4150 __put_user(txc.stabil, &utp->stabil) ||
4151 __put_user(txc.jitcnt, &utp->jitcnt) ||
4152 __put_user(txc.calcnt, &utp->calcnt) ||
4153 __put_user(txc.errcnt, &utp->errcnt) ||
4154 __put_user(txc.stbcnt, &utp->stbcnt))
4155 ret = -EFAULT;
4157 return ret;
4160 /* This is just a version for 32-bit applications which does
4161 * not force O_LARGEFILE on.
4164 asmlinkage long sparc32_open(const char * filename, int flags, int mode)
4166 char * tmp;
4167 int fd, error;
4169 tmp = getname(filename);
4170 fd = PTR_ERR(tmp);
4171 if (!IS_ERR(tmp)) {
4172 fd = get_unused_fd();
4173 if (fd >= 0) {
4174 struct file * f;
4175 lock_kernel();
4176 f = filp_open(tmp, flags, mode);
4177 unlock_kernel();
4178 error = PTR_ERR(f);
4179 if (IS_ERR(f))
4180 goto out_error;
4181 fd_install(fd, f);
4183 out:
4184 putname(tmp);
4186 return fd;
4188 out_error:
4189 put_unused_fd(fd);
4190 fd = error;
4191 goto out;