1 /* $Id: sys_sparc32.c,v 1.184 2002/02/09 19:49:31 davem Exp $
2 * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
7 * These routines maintain argument size conversion between 32bit and 64bit
11 #include <linux/config.h>
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
16 #include <linux/file.h>
17 #include <linux/signal.h>
18 #include <linux/resource.h>
19 #include <linux/times.h>
20 #include <linux/utsname.h>
21 #include <linux/timex.h>
22 #include <linux/smp.h>
23 #include <linux/smp_lock.h>
24 #include <linux/sem.h>
25 #include <linux/msg.h>
26 #include <linux/shm.h>
27 #include <linux/slab.h>
28 #include <linux/uio.h>
29 #include <linux/nfs_fs.h>
30 #include <linux/smb_fs.h>
31 #include <linux/smb_mount.h>
32 #include <linux/ncp_fs.h>
33 #include <linux/quota.h>
34 #include <linux/module.h>
35 #include <linux/sunrpc/svc.h>
36 #include <linux/nfsd/nfsd.h>
37 #include <linux/nfsd/cache.h>
38 #include <linux/nfsd/xdr.h>
39 #include <linux/nfsd/syscall.h>
40 #include <linux/poll.h>
41 #include <linux/personality.h>
42 #include <linux/stat.h>
43 #include <linux/filter.h>
44 #include <linux/highmem.h>
45 #include <linux/highuid.h>
46 #include <linux/mman.h>
47 #include <linux/ipv6.h>
49 #include <linux/icmpv6.h>
50 #include <linux/sysctl.h>
51 #include <linux/binfmts.h>
52 #include <linux/dnotify.h>
53 #include <linux/security.h>
54 #include <linux/compat.h>
55 #include <linux/vfs.h>
56 #include <linux/netfilter_ipv4/ip_tables.h>
58 #include <asm/types.h>
60 #include <asm/uaccess.h>
61 #include <asm/fpumacro.h>
62 #include <asm/semaphore.h>
63 #include <asm/mmu_context.h>
67 /* Use this to get at 32-bit user passed pointers. */
68 /* Things to consider: the low-level assembly stub does
69 srl x, 0, x for first four arguments, so if you have
70 pointer to something in the first four arguments, just
71 declare it as a pointer, not u32. On the other side,
72 arguments from 5th onwards should be declared as u32
73 for pointers, and need AA() around each usage.
74 A() macro should be used for places where you e.g.
75 have some internal variable u32 and just want to get
76 rid of a compiler warning. AA() has to be used in
77 places where you want to convert a function argument
78 to 32bit pointer or when you e.g. access pt_regs
79 structure and want to consider 32bit registers only.
82 #define A(__x) ((unsigned long)(__x))
84 ({ unsigned long __ret; \
85 __asm__ ("srl %0, 0, %0" \
91 extern asmlinkage
long sys_chown(const char *, uid_t
,gid_t
);
92 extern asmlinkage
long sys_lchown(const char *, uid_t
,gid_t
);
93 extern asmlinkage
long sys_fchown(unsigned int, uid_t
,gid_t
);
94 extern asmlinkage
long sys_setregid(gid_t
, gid_t
);
95 extern asmlinkage
long sys_setgid(gid_t
);
96 extern asmlinkage
long sys_setreuid(uid_t
, uid_t
);
97 extern asmlinkage
long sys_setuid(uid_t
);
98 extern asmlinkage
long sys_setresuid(uid_t
, uid_t
, uid_t
);
99 extern asmlinkage
long sys_setresgid(gid_t
, gid_t
, gid_t
);
100 extern asmlinkage
long sys_setfsuid(uid_t
);
101 extern asmlinkage
long sys_setfsgid(gid_t
);
103 /* For this source file, we want overflow handling. */
111 #undef NEW_TO_OLD_UID
112 #undef NEW_TO_OLD_GID
113 #undef SET_OLDSTAT_UID
114 #undef SET_OLDSTAT_GID
118 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
119 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
120 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
121 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
122 #define SET_UID16(var, uid) var = high2lowuid(uid)
123 #define SET_GID16(var, gid) var = high2lowgid(gid)
124 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
125 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
126 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
127 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
128 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
129 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
131 asmlinkage
long sys32_chown16(const char * filename
, u16 user
, u16 group
)
133 return sys_chown(filename
, low2highuid(user
), low2highgid(group
));
136 asmlinkage
long sys32_lchown16(const char * filename
, u16 user
, u16 group
)
138 return sys_lchown(filename
, low2highuid(user
), low2highgid(group
));
141 asmlinkage
long sys32_fchown16(unsigned int fd
, u16 user
, u16 group
)
143 return sys_fchown(fd
, low2highuid(user
), low2highgid(group
));
146 asmlinkage
long sys32_setregid16(u16 rgid
, u16 egid
)
148 return sys_setregid(low2highgid(rgid
), low2highgid(egid
));
151 asmlinkage
long sys32_setgid16(u16 gid
)
153 return sys_setgid((gid_t
)gid
);
156 asmlinkage
long sys32_setreuid16(u16 ruid
, u16 euid
)
158 return sys_setreuid(low2highuid(ruid
), low2highuid(euid
));
161 asmlinkage
long sys32_setuid16(u16 uid
)
163 return sys_setuid((uid_t
)uid
);
166 asmlinkage
long sys32_setresuid16(u16 ruid
, u16 euid
, u16 suid
)
168 return sys_setresuid(low2highuid(ruid
), low2highuid(euid
),
172 asmlinkage
long sys32_getresuid16(u16
*ruid
, u16
*euid
, u16
*suid
)
176 if (!(retval
= put_user(high2lowuid(current
->uid
), ruid
)) &&
177 !(retval
= put_user(high2lowuid(current
->euid
), euid
)))
178 retval
= put_user(high2lowuid(current
->suid
), suid
);
183 asmlinkage
long sys32_setresgid16(u16 rgid
, u16 egid
, u16 sgid
)
185 return sys_setresgid(low2highgid(rgid
), low2highgid(egid
),
189 asmlinkage
long sys32_getresgid16(u16
*rgid
, u16
*egid
, u16
*sgid
)
193 if (!(retval
= put_user(high2lowgid(current
->gid
), rgid
)) &&
194 !(retval
= put_user(high2lowgid(current
->egid
), egid
)))
195 retval
= put_user(high2lowgid(current
->sgid
), sgid
);
200 asmlinkage
long sys32_setfsuid16(u16 uid
)
202 return sys_setfsuid((uid_t
)uid
);
205 asmlinkage
long sys32_setfsgid16(u16 gid
)
207 return sys_setfsgid((gid_t
)gid
);
210 asmlinkage
long sys32_getgroups16(int gidsetsize
, u16
*grouplist
)
217 i
= current
->ngroups
;
222 groups
[j
] = current
->groups
[j
];
223 if (copy_to_user(grouplist
, groups
, sizeof(u16
)*i
))
229 asmlinkage
long sys32_setgroups16(int gidsetsize
, u16
*grouplist
)
234 if (!capable(CAP_SETGID
))
236 if ((unsigned) gidsetsize
> NGROUPS
)
238 if (copy_from_user(groups
, grouplist
, gidsetsize
* sizeof(u16
)))
240 for (i
= 0 ; i
< gidsetsize
; i
++)
241 current
->groups
[i
] = (gid_t
)groups
[i
];
242 current
->ngroups
= gidsetsize
;
246 asmlinkage
long sys32_getuid16(void)
248 return high2lowuid(current
->uid
);
251 asmlinkage
long sys32_geteuid16(void)
253 return high2lowuid(current
->euid
);
256 asmlinkage
long sys32_getgid16(void)
258 return high2lowgid(current
->gid
);
261 asmlinkage
long sys32_getegid16(void)
263 return high2lowgid(current
->egid
);
266 /* 32-bit timeval and related flotsam. */
268 static long get_tv32(struct timeval
*o
, struct compat_timeval
*i
)
270 return (!access_ok(VERIFY_READ
, tv32
, sizeof(*tv32
)) ||
271 (__get_user(o
->tv_sec
, &i
->tv_sec
) |
272 __get_user(o
->tv_usec
, &i
->tv_usec
)));
275 static inline long put_tv32(struct compat_timeval
*o
, struct timeval
*i
)
277 return (!access_ok(VERIFY_WRITE
, o
, sizeof(*o
)) ||
278 (__put_user(i
->tv_sec
, &o
->tv_sec
) |
279 __put_user(i
->tv_usec
, &o
->tv_usec
)));
282 extern asmlinkage
int sys_ioperm(unsigned long from
, unsigned long num
, int on
);
284 asmlinkage
int sys32_ioperm(u32 from
, u32 num
, int on
)
286 return sys_ioperm((unsigned long)from
, (unsigned long)num
, on
);
289 struct msgbuf32
{ s32 mtype
; char mtext
[1]; };
303 struct ipc_perm32 sem_perm
; /* permissions .. see ipc.h */
304 compat_time_t sem_otime
; /* last semop time */
305 compat_time_t sem_ctime
; /* last change time */
306 u32 sem_base
; /* ptr to first semaphore in array */
307 u32 sem_pending
; /* pending operations to be processed */
308 u32 sem_pending_last
; /* last pending operation */
309 u32 undo
; /* undo requests on this array */
310 unsigned short sem_nsems
; /* no. of semaphores in array */
313 struct semid64_ds32
{
314 struct ipc64_perm sem_perm
; /* this structure is the same on sparc32 and sparc64 */
316 compat_time_t sem_otime
;
318 compat_time_t sem_ctime
;
326 struct ipc_perm32 msg_perm
;
329 compat_time_t msg_stime
;
330 compat_time_t msg_rtime
;
331 compat_time_t msg_ctime
;
334 unsigned short msg_cbytes
;
335 unsigned short msg_qnum
;
336 unsigned short msg_qbytes
;
337 compat_ipc_pid_t msg_lspid
;
338 compat_ipc_pid_t msg_lrpid
;
341 struct msqid64_ds32
{
342 struct ipc64_perm msg_perm
;
344 compat_time_t msg_stime
;
346 compat_time_t msg_rtime
;
348 compat_time_t msg_ctime
;
349 unsigned int msg_cbytes
;
350 unsigned int msg_qnum
;
351 unsigned int msg_qbytes
;
352 compat_pid_t msg_lspid
;
353 compat_pid_t msg_lrpid
;
354 unsigned int __unused1
;
355 unsigned int __unused2
;
360 struct ipc_perm32 shm_perm
;
362 compat_time_t shm_atime
;
363 compat_time_t shm_dtime
;
364 compat_time_t shm_ctime
;
365 compat_ipc_pid_t shm_cpid
;
366 compat_ipc_pid_t shm_lpid
;
367 unsigned short shm_nattch
;
370 struct shmid64_ds32
{
371 struct ipc64_perm shm_perm
;
373 compat_time_t shm_atime
;
375 compat_time_t shm_dtime
;
377 compat_time_t shm_ctime
;
378 compat_size_t shm_segsz
;
379 compat_pid_t shm_cpid
;
380 compat_pid_t shm_lpid
;
381 unsigned int shm_nattch
;
382 unsigned int __unused1
;
383 unsigned int __unused2
;
388 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
390 * This is really horribly ugly.
392 #define IPCOP_MASK(__x) (1UL << (__x))
393 static int do_sys32_semctl(int first
, int second
, int third
, void *uptr
)
402 if (get_user (pad
, (u32
*)uptr
))
405 fourth
.val
= (int)pad
;
407 fourth
.__pad
= (void *)A(pad
);
408 if (IPCOP_MASK (third
) &
409 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SEM_INFO
) | IPCOP_MASK (GETVAL
) |
410 IPCOP_MASK (GETPID
) | IPCOP_MASK (GETNCNT
) | IPCOP_MASK (GETZCNT
) |
411 IPCOP_MASK (GETALL
) | IPCOP_MASK (SETALL
) | IPCOP_MASK (IPC_RMID
))) {
412 err
= sys_semctl (first
, second
, third
, fourth
);
413 } else if (third
& IPC_64
) {
415 struct semid64_ds32
*usp
= (struct semid64_ds32
*)A(pad
);
417 int need_back_translation
;
419 if (third
== (IPC_SET
|IPC_64
)) {
420 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
421 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
422 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
427 need_back_translation
=
428 (IPCOP_MASK (third
) &
429 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
430 if (need_back_translation
)
434 err
= sys_semctl (first
, second
, third
, fourth
);
436 if (need_back_translation
) {
437 int err2
= copy_to_user (&usp
->sem_perm
, &s
.sem_perm
, sizeof(struct ipc64_perm
) + 2*sizeof(time_t));
438 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
439 if (err2
) err
= -EFAULT
;
443 struct semid_ds32
*usp
= (struct semid_ds32
*)A(pad
);
445 int need_back_translation
;
447 if (third
== IPC_SET
) {
448 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
449 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
450 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
455 need_back_translation
=
456 (IPCOP_MASK (third
) &
457 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
458 if (need_back_translation
)
462 err
= sys_semctl (first
, second
, third
, fourth
);
464 if (need_back_translation
) {
465 int err2
= put_user (s
.sem_perm
.key
, &usp
->sem_perm
.key
);
466 err2
|= __put_user (high2lowuid(s
.sem_perm
.uid
), &usp
->sem_perm
.uid
);
467 err2
|= __put_user (high2lowgid(s
.sem_perm
.gid
), &usp
->sem_perm
.gid
);
468 err2
|= __put_user (high2lowuid(s
.sem_perm
.cuid
), &usp
->sem_perm
.cuid
);
469 err2
|= __put_user (high2lowgid(s
.sem_perm
.cgid
), &usp
->sem_perm
.cgid
);
470 err2
|= __put_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
471 err2
|= __put_user (s
.sem_perm
.seq
, &usp
->sem_perm
.seq
);
472 err2
|= __put_user (s
.sem_otime
, &usp
->sem_otime
);
473 err2
|= __put_user (s
.sem_ctime
, &usp
->sem_ctime
);
474 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
475 if (err2
) err
= -EFAULT
;
482 static int do_sys32_msgsnd (int first
, int second
, int third
, void *uptr
)
484 struct msgbuf
*p
= kmalloc (second
+ sizeof (struct msgbuf
) + 4, GFP_USER
);
485 struct msgbuf32
*up
= (struct msgbuf32
*)uptr
;
492 if (get_user (p
->mtype
, &up
->mtype
) ||
493 __copy_from_user (p
->mtext
, &up
->mtext
, second
))
497 err
= sys_msgsnd (first
, p
, second
, third
);
504 static int do_sys32_msgrcv (int first
, int second
, int msgtyp
, int third
,
505 int version
, void *uptr
)
513 struct ipc_kludge
*uipck
= (struct ipc_kludge
*)uptr
;
514 struct ipc_kludge ipck
;
520 if (copy_from_user (&ipck
, uipck
, sizeof (struct ipc_kludge
)))
522 uptr
= (void *)A(ipck
.msgp
);
523 msgtyp
= ipck
.msgtyp
;
526 p
= kmalloc (second
+ sizeof (struct msgbuf
) + 4, GFP_USER
);
531 err
= sys_msgrcv (first
, p
, second
+ 4, msgtyp
, third
);
535 up
= (struct msgbuf32
*)uptr
;
536 if (put_user (p
->mtype
, &up
->mtype
) ||
537 __copy_to_user (&up
->mtext
, p
->mtext
, err
))
545 static int do_sys32_msgctl (int first
, int second
, void *uptr
)
549 if (IPCOP_MASK (second
) &
550 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (MSG_INFO
) |
551 IPCOP_MASK (IPC_RMID
))) {
552 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)uptr
);
553 } else if (second
& IPC_64
) {
555 struct msqid64_ds32
*up
= (struct msqid64_ds32
*)uptr
;
558 if (second
== (IPC_SET
|IPC_64
)) {
559 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
560 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
561 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
562 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
568 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)&m
);
570 if (IPCOP_MASK (second
) &
571 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
572 int err2
= copy_to_user(&up
->msg_perm
, &m
.msg_perm
, sizeof(struct ipc64_perm
) + 3*sizeof(time_t));
573 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
574 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
575 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
576 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
577 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
583 struct msqid_ds32
*up
= (struct msqid_ds32
*)uptr
;
586 if (second
== IPC_SET
) {
587 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
588 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
589 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
590 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
596 err
= sys_msgctl (first
, second
, &m
);
598 if (IPCOP_MASK (second
) &
599 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
600 int err2
= put_user (m
.msg_perm
.key
, &up
->msg_perm
.key
);
601 err2
|= __put_user (high2lowuid(m
.msg_perm
.uid
), &up
->msg_perm
.uid
);
602 err2
|= __put_user (high2lowgid(m
.msg_perm
.gid
), &up
->msg_perm
.gid
);
603 err2
|= __put_user (high2lowuid(m
.msg_perm
.cuid
), &up
->msg_perm
.cuid
);
604 err2
|= __put_user (high2lowgid(m
.msg_perm
.cgid
), &up
->msg_perm
.cgid
);
605 err2
|= __put_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
606 err2
|= __put_user (m
.msg_perm
.seq
, &up
->msg_perm
.seq
);
607 err2
|= __put_user (m
.msg_stime
, &up
->msg_stime
);
608 err2
|= __put_user (m
.msg_rtime
, &up
->msg_rtime
);
609 err2
|= __put_user (m
.msg_ctime
, &up
->msg_ctime
);
610 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
611 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
612 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
613 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
614 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
624 static int do_sys32_shmat (int first
, int second
, int third
, int version
, void *uptr
)
627 u32
*uaddr
= (u32
*)A((u32
)third
);
632 err
= sys_shmat (first
, uptr
, second
, &raddr
);
635 err
= put_user (raddr
, uaddr
);
640 static int do_sys32_shmctl (int first
, int second
, void *uptr
)
644 if (IPCOP_MASK (second
) &
645 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SHM_LOCK
) | IPCOP_MASK (SHM_UNLOCK
) |
646 IPCOP_MASK (IPC_RMID
))) {
647 if (second
== (IPC_INFO
|IPC_64
))
648 second
= IPC_INFO
; /* So that we don't have to translate it */
649 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)uptr
);
650 } else if ((second
& IPC_64
) && second
!= (SHM_INFO
|IPC_64
)) {
652 struct shmid64_ds32
*up
= (struct shmid64_ds32
*)uptr
;
655 if (second
== (IPC_SET
|IPC_64
)) {
656 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
657 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
658 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
664 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)&s
);
669 /* Mask it even in this case so it becomes a CSE. */
670 if (IPCOP_MASK (second
) &
671 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
672 int err2
= copy_to_user (&up
->shm_perm
, &s
.shm_perm
, sizeof(struct ipc64_perm
) + 3*sizeof(time_t));
673 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
674 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
675 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
676 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
682 struct shmid_ds32
*up
= (struct shmid_ds32
*)uptr
;
686 if (second
== IPC_SET
) {
687 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
688 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
689 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
695 err
= sys_shmctl (first
, second
, &s
);
700 /* Mask it even in this case so it becomes a CSE. */
701 if (second
== SHM_INFO
) {
704 u32 shm_tot
, shm_rss
, shm_swp
;
705 u32 swap_attempts
, swap_successes
;
706 } *uip
= (struct shm_info32
*)uptr
;
707 struct shm_info
*kp
= (struct shm_info
*)&s
;
708 int err2
= put_user (kp
->used_ids
, &uip
->used_ids
);
709 err2
|= __put_user (kp
->shm_tot
, &uip
->shm_tot
);
710 err2
|= __put_user (kp
->shm_rss
, &uip
->shm_rss
);
711 err2
|= __put_user (kp
->shm_swp
, &uip
->shm_swp
);
712 err2
|= __put_user (kp
->swap_attempts
, &uip
->swap_attempts
);
713 err2
|= __put_user (kp
->swap_successes
, &uip
->swap_successes
);
716 } else if (IPCOP_MASK (second
) &
717 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
718 int err2
= put_user (s
.shm_perm
.key
, &up
->shm_perm
.key
);
719 err2
|= __put_user (high2lowuid(s
.shm_perm
.uid
), &up
->shm_perm
.uid
);
720 err2
|= __put_user (high2lowuid(s
.shm_perm
.gid
), &up
->shm_perm
.gid
);
721 err2
|= __put_user (high2lowuid(s
.shm_perm
.cuid
), &up
->shm_perm
.cuid
);
722 err2
|= __put_user (high2lowuid(s
.shm_perm
.cgid
), &up
->shm_perm
.cgid
);
723 err2
|= __put_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
724 err2
|= __put_user (s
.shm_perm
.seq
, &up
->shm_perm
.seq
);
725 err2
|= __put_user (s
.shm_atime
, &up
->shm_atime
);
726 err2
|= __put_user (s
.shm_dtime
, &up
->shm_dtime
);
727 err2
|= __put_user (s
.shm_ctime
, &up
->shm_ctime
);
728 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
729 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
730 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
731 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
740 asmlinkage
int sys32_ipc (u32 call
, int first
, int second
, int third
, u32 ptr
, u32 fifth
)
744 version
= call
>> 16; /* hack for backward compatibility */
750 /* struct sembuf is the same on 32 and 64bit :)) */
751 err
= sys_semop (first
, (struct sembuf
*)AA(ptr
), second
);
754 err
= sys_semget (first
, second
, third
);
757 err
= do_sys32_semctl (first
, second
, third
, (void *)AA(ptr
));
766 err
= do_sys32_msgsnd (first
, second
, third
, (void *)AA(ptr
));
769 err
= do_sys32_msgrcv (first
, second
, fifth
, third
,
770 version
, (void *)AA(ptr
));
773 err
= sys_msgget ((key_t
) first
, second
);
776 err
= do_sys32_msgctl (first
, second
, (void *)AA(ptr
));
785 err
= do_sys32_shmat (first
, second
, third
,
786 version
, (void *)AA(ptr
));
789 err
= sys_shmdt ((char *)AA(ptr
));
792 err
= sys_shmget (first
, second
, third
);
795 err
= do_sys32_shmctl (first
, second
, (void *)AA(ptr
));
808 extern asmlinkage
long sys_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
);
810 asmlinkage
long sys32_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
821 if (get_compat_flock(&f
, (struct compat_flock
*)arg
))
823 old_fs
= get_fs(); set_fs (KERNEL_DS
);
824 ret
= sys_fcntl(fd
, cmd
, (unsigned long)&f
);
827 if (put_compat_flock(&f
, (struct compat_flock
*)arg
))
832 return sys_fcntl(fd
, cmd
, (unsigned long)arg
);
836 asmlinkage
long sys32_fcntl64(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
838 if (cmd
>= F_GETLK64
&& cmd
<= F_SETLKW64
)
839 return sys_fcntl(fd
, cmd
+ F_GETLK
- F_GETLK64
, arg
);
840 return sys32_fcntl(fd
, cmd
, arg
);
843 extern asmlinkage
long sys_truncate(const char * path
, unsigned long length
);
844 extern asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
);
846 asmlinkage
int sys32_truncate64(const char * path
, unsigned long high
, unsigned long low
)
851 return sys_truncate(path
, (high
<< 32) | low
);
854 asmlinkage
int sys32_ftruncate64(unsigned int fd
, unsigned long high
, unsigned long low
)
859 return sys_ftruncate(fd
, (high
<< 32) | low
);
862 struct iovec32
{ u32 iov_base
; compat_size_t iov_len
; };
864 typedef ssize_t (*io_fn_t
)(struct file
*, char *, size_t, loff_t
*);
865 typedef ssize_t (*iov_fn_t
)(struct file
*, const struct iovec
*, unsigned long, loff_t
*);
867 static long do_readv_writev32(int type
, struct file
*file
,
868 const struct iovec32
*vector
, u32 count
)
870 compat_ssize_t tot_len
;
871 struct iovec iovstack
[UIO_FASTIOV
];
872 struct iovec
*iov
=iovstack
, *ivp
;
879 * SuS says "The readv() function *may* fail if the iovcnt argument
880 * was less than or equal to 0, or greater than {IOV_MAX}. Linux has
881 * traditionally returned zero for zero segments, so...
887 /* First get the "struct iovec" from user memory and
888 * verify all the pointers
891 if (count
> UIO_MAXIOV
)
895 if (count
> UIO_FASTIOV
) {
897 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
902 if (verify_area(VERIFY_READ
, vector
, sizeof(struct iovec32
)*count
))
906 * Single unix specification:
907 * We should -EINVAL if an element length is not >= 0 and fitting an
908 * ssize_t. The total length is fitting an ssize_t
910 * Be careful here because iov_len is a size_t not an ssize_t
917 compat_ssize_t tmp
= tot_len
;
921 if (__get_user(len
, &vector
->iov_len
) ||
922 __get_user(buf
, &vector
->iov_base
)) {
926 if (len
< 0) /* size_t not fitting an ssize_t32 .. */
929 if (tot_len
< tmp
) /* maths overflow on the compat_ssize_t */
931 ivp
->iov_base
= (void *)A(buf
);
932 ivp
->iov_len
= (__kernel_size_t
) len
;
942 inode
= file
->f_dentry
->d_inode
;
943 /* VERIFY_WRITE actually means a read, as we write to user space */
944 retval
= locks_verify_area((type
== READ
945 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
946 inode
, file
, file
->f_pos
, tot_len
);
951 fn
= file
->f_op
->read
;
952 fnv
= file
->f_op
->readv
;
954 fn
= (io_fn_t
)file
->f_op
->write
;
955 fnv
= file
->f_op
->writev
;
958 retval
= fnv(file
, iov
, count
, &file
->f_pos
);
962 /* Do it by hand, with file-ops */
968 base
= ivp
->iov_base
;
973 nr
= fn(file
, base
, len
, &file
->f_pos
);
987 if ((retval
+ (type
== READ
)) > 0)
988 dnotify_parent(file
->f_dentry
,
989 (type
== READ
) ? DN_ACCESS
: DN_MODIFY
);
994 asmlinkage
long sys32_readv(int fd
, struct iovec32
*vector
, u32 count
)
1004 if (!(file
->f_mode
& FMODE_READ
))
1007 if (!file
->f_op
|| (!file
->f_op
->readv
&& !file
->f_op
->read
))
1010 ret
= do_readv_writev32(READ
, file
, vector
, count
);
1017 asmlinkage
long sys32_writev(int fd
, struct iovec32
*vector
, u32 count
)
1027 if (!(file
->f_mode
& FMODE_WRITE
))
1030 if (!file
->f_op
|| (!file
->f_op
->writev
&& !file
->f_op
->write
))
1033 ret
= do_readv_writev32(WRITE
, file
, vector
, count
);
1040 /* readdir & getdents */
1042 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1043 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1045 struct old_linux_dirent32
{
1048 unsigned short d_namlen
;
1052 struct readdir_callback32
{
1053 struct old_linux_dirent32
* dirent
;
1057 static int fillonedir(void * __buf
, const char * name
, int namlen
,
1058 loff_t offset
, ino_t ino
, unsigned int d_type
)
1060 struct readdir_callback32
* buf
= (struct readdir_callback32
*) __buf
;
1061 struct old_linux_dirent32
* dirent
;
1066 dirent
= buf
->dirent
;
1067 put_user(ino
, &dirent
->d_ino
);
1068 put_user(offset
, &dirent
->d_offset
);
1069 put_user(namlen
, &dirent
->d_namlen
);
1070 copy_to_user(dirent
->d_name
, name
, namlen
);
1071 put_user(0, dirent
->d_name
+ namlen
);
1075 asmlinkage
int old32_readdir(unsigned int fd
, struct old_linux_dirent32
*dirent
, unsigned int count
)
1079 struct readdir_callback32 buf
;
1086 buf
.dirent
= dirent
;
1088 error
= vfs_readdir(file
, fillonedir
, &buf
);
1099 struct linux_dirent32
{
1102 unsigned short d_reclen
;
1106 struct getdents_callback32
{
1107 struct linux_dirent32
* current_dir
;
1108 struct linux_dirent32
* previous
;
1113 static int filldir(void * __buf
, const char * name
, int namlen
, loff_t offset
, ino_t ino
,
1114 unsigned int d_type
)
1116 struct linux_dirent32
* dirent
;
1117 struct getdents_callback32
* buf
= (struct getdents_callback32
*) __buf
;
1118 int reclen
= ROUND_UP(NAME_OFFSET(dirent
) + namlen
+ 1);
1120 buf
->error
= -EINVAL
; /* only used if we fail.. */
1121 if (reclen
> buf
->count
)
1123 dirent
= buf
->previous
;
1125 put_user(offset
, &dirent
->d_off
);
1126 dirent
= buf
->current_dir
;
1127 buf
->previous
= dirent
;
1128 put_user(ino
, &dirent
->d_ino
);
1129 put_user(reclen
, &dirent
->d_reclen
);
1130 copy_to_user(dirent
->d_name
, name
, namlen
);
1131 put_user(0, dirent
->d_name
+ namlen
);
1132 ((char *) dirent
) += reclen
;
1133 buf
->current_dir
= dirent
;
1134 buf
->count
-= reclen
;
1138 asmlinkage
int sys32_getdents(unsigned int fd
, struct linux_dirent32
*dirent
, unsigned int count
)
1141 struct linux_dirent32
* lastdirent
;
1142 struct getdents_callback32 buf
;
1149 buf
.current_dir
= dirent
;
1150 buf
.previous
= NULL
;
1154 error
= vfs_readdir(file
, filldir
, &buf
);
1157 lastdirent
= buf
.previous
;
1160 put_user(file
->f_pos
, &lastdirent
->d_off
);
1161 error
= count
- buf
.count
;
1169 /* end of readdir & getdents */
1172 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1173 * 64-bit unsigned longs.
1176 static int get_fd_set32(unsigned long n
, unsigned long *fdset
, u32
*ufdset
)
1181 if (verify_area(VERIFY_WRITE
, ufdset
, n
*sizeof(u32
)))
1188 __get_user(l
, ufdset
);
1189 __get_user(h
, ufdset
+1);
1191 *fdset
++ = h
<< 32 | l
;
1195 __get_user(*fdset
, ufdset
);
1197 /* Tricky, must clear full unsigned long in the
1198 * kernel fdset at the end, this makes sure that
1201 memset(fdset
, 0, ((n
+ 1) & ~1)*sizeof(u32
));
1206 static void set_fd_set32(unsigned long n
, u32
*ufdset
, unsigned long *fdset
)
1219 __put_user(l
, ufdset
);
1220 __put_user(h
, ufdset
+1);
1225 __put_user(*fdset
, ufdset
);
1228 #define MAX_SELECT_SECONDS \
1229 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1231 asmlinkage
int sys32_select(int n
, u32
*inp
, u32
*outp
, u32
*exp
, u32 tvp_x
)
1234 struct compat_timeval
*tvp
= (struct compat_timeval
*)AA(tvp_x
);
1240 timeout
= MAX_SCHEDULE_TIMEOUT
;
1244 if ((ret
= verify_area(VERIFY_READ
, tvp
, sizeof(*tvp
)))
1245 || (ret
= __get_user(sec
, &tvp
->tv_sec
))
1246 || (ret
= __get_user(usec
, &tvp
->tv_usec
)))
1250 if(sec
< 0 || usec
< 0)
1253 if ((unsigned long) sec
< MAX_SELECT_SECONDS
) {
1254 timeout
= (usec
+ 1000000/HZ
- 1) / (1000000/HZ
);
1255 timeout
+= sec
* (unsigned long) HZ
;
1262 if (n
> current
->files
->max_fdset
)
1263 n
= current
->files
->max_fdset
;
1266 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1267 * since we used fdset we need to allocate memory in units of
1271 size
= FDS_BYTES(n
);
1272 bits
= kmalloc(6 * size
, GFP_KERNEL
);
1275 fds
.in
= (unsigned long *) bits
;
1276 fds
.out
= (unsigned long *) (bits
+ size
);
1277 fds
.ex
= (unsigned long *) (bits
+ 2*size
);
1278 fds
.res_in
= (unsigned long *) (bits
+ 3*size
);
1279 fds
.res_out
= (unsigned long *) (bits
+ 4*size
);
1280 fds
.res_ex
= (unsigned long *) (bits
+ 5*size
);
1282 nn
= (n
+ 8*sizeof(u32
) - 1) / (8*sizeof(u32
));
1283 if ((ret
= get_fd_set32(nn
, fds
.in
, inp
)) ||
1284 (ret
= get_fd_set32(nn
, fds
.out
, outp
)) ||
1285 (ret
= get_fd_set32(nn
, fds
.ex
, exp
)))
1287 zero_fd_set(n
, fds
.res_in
);
1288 zero_fd_set(n
, fds
.res_out
);
1289 zero_fd_set(n
, fds
.res_ex
);
1291 ret
= do_select(n
, &fds
, &timeout
);
1293 if (tvp
&& !(current
->personality
& STICKY_TIMEOUTS
)) {
1294 time_t sec
= 0, usec
= 0;
1297 usec
= timeout
% HZ
;
1298 usec
*= (1000000/HZ
);
1300 put_user(sec
, &tvp
->tv_sec
);
1301 put_user(usec
, &tvp
->tv_usec
);
1307 ret
= -ERESTARTNOHAND
;
1308 if (signal_pending(current
))
1313 set_fd_set32(nn
, inp
, fds
.res_in
);
1314 set_fd_set32(nn
, outp
, fds
.res_out
);
1315 set_fd_set32(nn
, exp
, fds
.res_ex
);
1323 int cp_compat_stat(struct kstat
*stat
, struct compat_stat
*statbuf
)
1327 if (stat
->size
> MAX_NON_LFS
)
1330 err
= put_user(stat
->dev
, &statbuf
->st_dev
);
1331 err
|= put_user(stat
->ino
, &statbuf
->st_ino
);
1332 err
|= put_user(stat
->mode
, &statbuf
->st_mode
);
1333 err
|= put_user(stat
->nlink
, &statbuf
->st_nlink
);
1334 err
|= put_user(high2lowuid(stat
->uid
), &statbuf
->st_uid
);
1335 err
|= put_user(high2lowgid(stat
->gid
), &statbuf
->st_gid
);
1336 err
|= put_user(stat
->rdev
, &statbuf
->st_rdev
);
1337 err
|= put_user(stat
->size
, &statbuf
->st_size
);
1338 err
|= put_user(stat
->atime
.tv_sec
, &statbuf
->st_atime
);
1339 err
|= put_user(0, &statbuf
->__unused1
);
1340 err
|= put_user(stat
->mtime
.tv_sec
, &statbuf
->st_mtime
);
1341 err
|= put_user(0, &statbuf
->__unused2
);
1342 err
|= put_user(stat
->ctime
.tv_sec
, &statbuf
->st_ctime
);
1343 err
|= put_user(0, &statbuf
->__unused3
);
1344 err
|= put_user(stat
->blksize
, &statbuf
->st_blksize
);
1345 err
|= put_user(stat
->blocks
, &statbuf
->st_blocks
);
1346 err
|= put_user(0, &statbuf
->__unused4
[0]);
1347 err
|= put_user(0, &statbuf
->__unused4
[1]);
1352 extern asmlinkage
int sys_sysfs(int option
, unsigned long arg1
, unsigned long arg2
);
1354 asmlinkage
int sys32_sysfs(int option
, u32 arg1
, u32 arg2
)
1356 return sys_sysfs(option
, arg1
, arg2
);
1359 struct ncp_mount_data32_v3
{
1361 unsigned int ncp_fd
;
1362 compat_uid_t mounted_uid
;
1363 compat_pid_t wdog_pid
;
1364 unsigned char mounted_vol
[NCP_VOLNAME_LEN
+ 1];
1365 unsigned int time_out
;
1366 unsigned int retry_count
;
1370 compat_mode_t file_mode
;
1371 compat_mode_t dir_mode
;
1374 struct ncp_mount_data32_v4
{
1376 /* all members below are "long" in ABI ... i.e. 32bit on sparc32, while 64bits on sparc64 */
1378 unsigned int mounted_uid
;
1381 unsigned int ncp_fd
;
1382 unsigned int time_out
;
1383 unsigned int retry_count
;
1387 unsigned int file_mode
;
1388 unsigned int dir_mode
;
1391 static void *do_ncp_super_data_conv(void *raw_data
)
1393 switch (*(int*)raw_data
) {
1394 case NCP_MOUNT_VERSION
:
1396 struct ncp_mount_data news
, *n
= &news
;
1397 struct ncp_mount_data32_v3
*n32
= (struct ncp_mount_data32_v3
*)raw_data
;
1399 n
->version
= n32
->version
;
1400 n
->ncp_fd
= n32
->ncp_fd
;
1401 n
->mounted_uid
= low2highuid(n32
->mounted_uid
);
1402 n
->wdog_pid
= n32
->wdog_pid
;
1403 memmove (n
->mounted_vol
, n32
->mounted_vol
, sizeof (n32
->mounted_vol
));
1404 n
->time_out
= n32
->time_out
;
1405 n
->retry_count
= n32
->retry_count
;
1406 n
->flags
= n32
->flags
;
1407 n
->uid
= low2highuid(n32
->uid
);
1408 n
->gid
= low2highgid(n32
->gid
);
1409 n
->file_mode
= n32
->file_mode
;
1410 n
->dir_mode
= n32
->dir_mode
;
1411 memcpy(raw_data
, n
, sizeof(*n
));
1414 case NCP_MOUNT_VERSION_V4
:
1416 struct ncp_mount_data_v4 news
, *n
= &news
;
1417 struct ncp_mount_data32_v4
*n32
= (struct ncp_mount_data32_v4
*)raw_data
;
1419 n
->version
= n32
->version
;
1420 n
->flags
= n32
->flags
;
1421 n
->mounted_uid
= n32
->mounted_uid
;
1422 n
->wdog_pid
= n32
->wdog_pid
;
1423 n
->ncp_fd
= n32
->ncp_fd
;
1424 n
->time_out
= n32
->time_out
;
1425 n
->retry_count
= n32
->retry_count
;
1428 n
->file_mode
= n32
->file_mode
;
1429 n
->dir_mode
= n32
->dir_mode
;
1430 memcpy(raw_data
, n
, sizeof(*n
));
1434 /* do not touch unknown structures */
1440 struct smb_mount_data32
{
1442 compat_uid_t mounted_uid
;
1445 compat_mode_t file_mode
;
1446 compat_mode_t dir_mode
;
1449 static void *do_smb_super_data_conv(void *raw_data
)
1451 struct smb_mount_data news
, *s
= &news
;
1452 struct smb_mount_data32
*s32
= (struct smb_mount_data32
*)raw_data
;
1454 if (s32
->version
!= SMB_MOUNT_OLDVERSION
)
1456 s
->version
= s32
->version
;
1457 s
->mounted_uid
= low2highuid(s32
->mounted_uid
);
1458 s
->uid
= low2highuid(s32
->uid
);
1459 s
->gid
= low2highgid(s32
->gid
);
1460 s
->file_mode
= s32
->file_mode
;
1461 s
->dir_mode
= s32
->dir_mode
;
1462 memcpy(raw_data
, s
, sizeof(struct smb_mount_data
));
1467 static int copy_mount_stuff_to_kernel(const void *user
, unsigned long *kernel
)
1471 struct vm_area_struct
*vma
;
1476 vma
= find_vma(current
->mm
, (unsigned long)user
);
1477 if(!vma
|| (unsigned long)user
< vma
->vm_start
)
1479 if(!(vma
->vm_flags
& VM_READ
))
1481 i
= vma
->vm_end
- (unsigned long) user
;
1482 if(PAGE_SIZE
<= (unsigned long) i
)
1484 if(!(page
= __get_free_page(GFP_KERNEL
)))
1486 if(copy_from_user((void *) page
, user
, i
)) {
1494 #define SMBFS_NAME "smbfs"
1495 #define NCPFS_NAME "ncpfs"
1497 asmlinkage
int sys32_mount(char *dev_name
, char *dir_name
, char *type
, unsigned long new_flags
, u32 data
)
1499 unsigned long type_page
= 0;
1500 unsigned long data_page
= 0;
1501 unsigned long dev_page
= 0;
1502 unsigned long dir_page
= 0;
1503 int err
, is_smb
, is_ncp
;
1505 is_smb
= is_ncp
= 0;
1507 err
= copy_mount_stuff_to_kernel((const void *)type
, &type_page
);
1516 is_smb
= !strcmp((char *)type_page
, SMBFS_NAME
);
1517 is_ncp
= !strcmp((char *)type_page
, NCPFS_NAME
);
1519 err
= copy_mount_stuff_to_kernel((const void *)AA(data
), &data_page
);
1523 err
= copy_mount_stuff_to_kernel(dev_name
, &dev_page
);
1527 err
= copy_mount_stuff_to_kernel(dir_name
, &dir_page
);
1531 if (!is_smb
&& !is_ncp
) {
1533 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1534 (char*)type_page
, new_flags
, (char*)data_page
);
1538 do_ncp_super_data_conv((void *)data_page
);
1540 do_smb_super_data_conv((void *)data_page
);
1543 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1544 (char*)type_page
, new_flags
, (char*)data_page
);
1547 free_page(dir_page
);
1550 free_page(dev_page
);
1553 free_page(data_page
);
1556 free_page(type_page
);
1563 struct compat_timeval ru_utime
;
1564 struct compat_timeval ru_stime
;
1581 static int put_rusage (struct rusage32
*ru
, struct rusage
*r
)
1585 err
= put_user (r
->ru_utime
.tv_sec
, &ru
->ru_utime
.tv_sec
);
1586 err
|= __put_user (r
->ru_utime
.tv_usec
, &ru
->ru_utime
.tv_usec
);
1587 err
|= __put_user (r
->ru_stime
.tv_sec
, &ru
->ru_stime
.tv_sec
);
1588 err
|= __put_user (r
->ru_stime
.tv_usec
, &ru
->ru_stime
.tv_usec
);
1589 err
|= __put_user (r
->ru_maxrss
, &ru
->ru_maxrss
);
1590 err
|= __put_user (r
->ru_ixrss
, &ru
->ru_ixrss
);
1591 err
|= __put_user (r
->ru_idrss
, &ru
->ru_idrss
);
1592 err
|= __put_user (r
->ru_isrss
, &ru
->ru_isrss
);
1593 err
|= __put_user (r
->ru_minflt
, &ru
->ru_minflt
);
1594 err
|= __put_user (r
->ru_majflt
, &ru
->ru_majflt
);
1595 err
|= __put_user (r
->ru_nswap
, &ru
->ru_nswap
);
1596 err
|= __put_user (r
->ru_inblock
, &ru
->ru_inblock
);
1597 err
|= __put_user (r
->ru_oublock
, &ru
->ru_oublock
);
1598 err
|= __put_user (r
->ru_msgsnd
, &ru
->ru_msgsnd
);
1599 err
|= __put_user (r
->ru_msgrcv
, &ru
->ru_msgrcv
);
1600 err
|= __put_user (r
->ru_nsignals
, &ru
->ru_nsignals
);
1601 err
|= __put_user (r
->ru_nvcsw
, &ru
->ru_nvcsw
);
1602 err
|= __put_user (r
->ru_nivcsw
, &ru
->ru_nivcsw
);
1606 asmlinkage
int sys32_wait4(compat_pid_t pid
, unsigned int *stat_addr
, int options
, struct rusage32
*ru
)
1609 return sys_wait4(pid
, stat_addr
, options
, NULL
);
1613 unsigned int status
;
1614 mm_segment_t old_fs
= get_fs();
1617 ret
= sys_wait4(pid
, stat_addr
? &status
: NULL
, options
, &r
);
1619 if (put_rusage (ru
, &r
)) return -EFAULT
;
1620 if (stat_addr
&& put_user (status
, stat_addr
))
1635 unsigned short procs
;
1639 extern asmlinkage
int sys_sysinfo(struct sysinfo
*info
);
1641 asmlinkage
int sys32_sysinfo(struct sysinfo32
*info
)
1645 mm_segment_t old_fs
= get_fs ();
1648 ret
= sys_sysinfo(&s
);
1650 err
= put_user (s
.uptime
, &info
->uptime
);
1651 err
|= __put_user (s
.loads
[0], &info
->loads
[0]);
1652 err
|= __put_user (s
.loads
[1], &info
->loads
[1]);
1653 err
|= __put_user (s
.loads
[2], &info
->loads
[2]);
1654 err
|= __put_user (s
.totalram
, &info
->totalram
);
1655 err
|= __put_user (s
.freeram
, &info
->freeram
);
1656 err
|= __put_user (s
.sharedram
, &info
->sharedram
);
1657 err
|= __put_user (s
.bufferram
, &info
->bufferram
);
1658 err
|= __put_user (s
.totalswap
, &info
->totalswap
);
1659 err
|= __put_user (s
.freeswap
, &info
->freeswap
);
1660 err
|= __put_user (s
.procs
, &info
->procs
);
1666 extern asmlinkage
int sys_sched_rr_get_interval(pid_t pid
, struct timespec
*interval
);
1668 asmlinkage
int sys32_sched_rr_get_interval(compat_pid_t pid
, struct compat_timespec
*interval
)
1672 mm_segment_t old_fs
= get_fs ();
1675 ret
= sys_sched_rr_get_interval(pid
, &t
);
1677 if (put_compat_timespec(&t
, interval
))
1682 extern asmlinkage
int sys_sigprocmask(int how
, old_sigset_t
*set
, old_sigset_t
*oset
);
1684 asmlinkage
int sys32_sigprocmask(int how
, old_sigset_t32
*set
, old_sigset_t32
*oset
)
1688 mm_segment_t old_fs
= get_fs();
1690 if (set
&& get_user (s
, set
)) return -EFAULT
;
1692 ret
= sys_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
);
1694 if (ret
) return ret
;
1695 if (oset
&& put_user (s
, oset
)) return -EFAULT
;
1699 extern asmlinkage
int sys_rt_sigprocmask(int how
, sigset_t
*set
, sigset_t
*oset
, size_t sigsetsize
);
1701 asmlinkage
int sys32_rt_sigprocmask(int how
, sigset_t32
*set
, sigset_t32
*oset
, compat_size_t sigsetsize
)
1706 mm_segment_t old_fs
= get_fs();
1709 if (copy_from_user (&s32
, set
, sizeof(sigset_t32
)))
1711 switch (_NSIG_WORDS
) {
1712 case 4: s
.sig
[3] = s32
.sig
[6] | (((long)s32
.sig
[7]) << 32);
1713 case 3: s
.sig
[2] = s32
.sig
[4] | (((long)s32
.sig
[5]) << 32);
1714 case 2: s
.sig
[1] = s32
.sig
[2] | (((long)s32
.sig
[3]) << 32);
1715 case 1: s
.sig
[0] = s32
.sig
[0] | (((long)s32
.sig
[1]) << 32);
1719 ret
= sys_rt_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
, sigsetsize
);
1721 if (ret
) return ret
;
1723 switch (_NSIG_WORDS
) {
1724 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
1725 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
1726 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
1727 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
1729 if (copy_to_user (oset
, &s32
, sizeof(sigset_t32
)))
1735 extern asmlinkage
int sys_sigpending(old_sigset_t
*set
);
1737 asmlinkage
int sys32_sigpending(old_sigset_t32
*set
)
1741 mm_segment_t old_fs
= get_fs();
1744 ret
= sys_sigpending(&s
);
1746 if (put_user (s
, set
)) return -EFAULT
;
1750 extern asmlinkage
int sys_rt_sigpending(sigset_t
*set
, size_t sigsetsize
);
1752 asmlinkage
int sys32_rt_sigpending(sigset_t32
*set
, compat_size_t sigsetsize
)
1757 mm_segment_t old_fs
= get_fs();
1760 ret
= sys_rt_sigpending(&s
, sigsetsize
);
1763 switch (_NSIG_WORDS
) {
1764 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
1765 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
1766 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
1767 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
1769 if (copy_to_user (set
, &s32
, sizeof(sigset_t32
)))
1776 sys32_rt_sigtimedwait(sigset_t32
*uthese
, siginfo_t32
*uinfo
,
1777 struct compat_timespec
*uts
, compat_size_t sigsetsize
)
1786 /* XXX: Don't preclude handling different sized sigset_t's. */
1787 if (sigsetsize
!= sizeof(sigset_t
))
1790 if (copy_from_user (&these32
, uthese
, sizeof(sigset_t32
)))
1793 switch (_NSIG_WORDS
) {
1794 case 4: these
.sig
[3] = these32
.sig
[6] | (((long)these32
.sig
[7]) << 32);
1795 case 3: these
.sig
[2] = these32
.sig
[4] | (((long)these32
.sig
[5]) << 32);
1796 case 2: these
.sig
[1] = these32
.sig
[2] | (((long)these32
.sig
[3]) << 32);
1797 case 1: these
.sig
[0] = these32
.sig
[0] | (((long)these32
.sig
[1]) << 32);
1801 * Invert the set of allowed signals to get those we
1804 sigdelsetmask(&these
, sigmask(SIGKILL
)|sigmask(SIGSTOP
));
1808 if (get_compat_timespec(&ts
, uts
))
1810 if (ts
.tv_nsec
>= 1000000000L || ts
.tv_nsec
< 0
1815 spin_lock_irq(¤t
->sig
->siglock
);
1816 sig
= dequeue_signal(&these
, &info
);
1818 timeout
= MAX_SCHEDULE_TIMEOUT
;
1820 timeout
= (timespec_to_jiffies(&ts
)
1821 + (ts
.tv_sec
|| ts
.tv_nsec
));
1824 /* None ready -- temporarily unblock those we're
1825 * interested while we are sleeping in so that we'll
1826 * be awakened when they arrive. */
1827 current
->real_blocked
= current
->blocked
;
1828 sigandsets(¤t
->blocked
, ¤t
->blocked
, &these
);
1829 recalc_sigpending();
1830 spin_unlock_irq(¤t
->sig
->siglock
);
1832 current
->state
= TASK_INTERRUPTIBLE
;
1833 timeout
= schedule_timeout(timeout
);
1835 spin_lock_irq(¤t
->sig
->siglock
);
1836 sig
= dequeue_signal(&these
, &info
);
1837 current
->blocked
= current
->real_blocked
;
1838 siginitset(¤t
->real_blocked
, 0);
1839 recalc_sigpending();
1842 spin_unlock_irq(¤t
->sig
->siglock
);
1847 if (copy_siginfo_to_user32(uinfo
, &info
))
1859 extern asmlinkage
int
1860 sys_rt_sigqueueinfo(int pid
, int sig
, siginfo_t
*uinfo
);
1863 sys32_rt_sigqueueinfo(int pid
, int sig
, siginfo_t32
*uinfo
)
1867 mm_segment_t old_fs
= get_fs();
1869 if (copy_from_user (&info
, uinfo
, 3*sizeof(int)) ||
1870 copy_from_user (info
._sifields
._pad
, uinfo
->_sifields
._pad
, SI_PAD_SIZE
))
1873 ret
= sys_rt_sigqueueinfo(pid
, sig
, &info
);
1878 #define RLIM_INFINITY32 0x7fffffff
1879 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
1886 extern asmlinkage
int sys_getrlimit(unsigned int resource
, struct rlimit
*rlim
);
1888 asmlinkage
int sys32_getrlimit(unsigned int resource
, struct rlimit32
*rlim
)
1892 mm_segment_t old_fs
= get_fs ();
1895 ret
= sys_getrlimit(resource
, &r
);
1898 ret
= put_user (RESOURCE32(r
.rlim_cur
), &rlim
->rlim_cur
);
1899 ret
|= __put_user (RESOURCE32(r
.rlim_max
), &rlim
->rlim_max
);
1904 extern asmlinkage
int sys_setrlimit(unsigned int resource
, struct rlimit
*rlim
);
1906 asmlinkage
int sys32_setrlimit(unsigned int resource
, struct rlimit32
*rlim
)
1910 mm_segment_t old_fs
= get_fs ();
1912 if (resource
>= RLIM_NLIMITS
) return -EINVAL
;
1913 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
1914 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
1916 if (r
.rlim_cur
== RLIM_INFINITY32
)
1917 r
.rlim_cur
= RLIM_INFINITY
;
1918 if (r
.rlim_max
== RLIM_INFINITY32
)
1919 r
.rlim_max
= RLIM_INFINITY
;
1921 ret
= sys_setrlimit(resource
, &r
);
1926 extern asmlinkage
int sys_getrusage(int who
, struct rusage
*ru
);
1928 asmlinkage
int sys32_getrusage(int who
, struct rusage32
*ru
)
1932 mm_segment_t old_fs
= get_fs();
1935 ret
= sys_getrusage(who
, &r
);
1937 if (put_rusage (ru
, &r
)) return -EFAULT
;
1941 /* XXX This really belongs in some header file... -DaveM */
1942 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
1943 16 for IP, 16 for IPX,
1945 about 80 for AX.25 */
1951 compat_size_t msg_iovlen
;
1953 compat_size_t msg_controllen
;
1958 compat_size_t cmsg_len
;
1964 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
1965 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
1967 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
1969 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
1970 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
1971 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
1973 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
1974 (struct cmsghdr32 *)(ctl) : \
1975 (struct cmsghdr32 *)NULL)
1976 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
1978 __inline__
struct cmsghdr32
*__cmsg32_nxthdr(void *__ctl
, __kernel_size_t __size
,
1979 struct cmsghdr32
*__cmsg
, int __cmsg_len
)
1981 struct cmsghdr32
* __ptr
;
1983 __ptr
= (struct cmsghdr32
*)(((unsigned char *) __cmsg
) +
1984 CMSG32_ALIGN(__cmsg_len
));
1985 if ((unsigned long)((char*)(__ptr
+1) - (char *) __ctl
) > __size
)
1991 __inline__
struct cmsghdr32
*cmsg32_nxthdr (struct msghdr
*__msg
,
1992 struct cmsghdr32
*__cmsg
,
1995 return __cmsg32_nxthdr(__msg
->msg_control
, __msg
->msg_controllen
,
1996 __cmsg
, __cmsg_len
);
1999 static inline int iov_from_user32_to_kern(struct iovec
*kiov
,
2000 struct iovec32
*uiov32
,
2008 if(get_user(len
, &uiov32
->iov_len
) ||
2009 get_user(buf
, &uiov32
->iov_base
)) {
2014 kiov
->iov_base
= (void *)A(buf
);
2015 kiov
->iov_len
= (__kernel_size_t
) len
;
2023 static int msghdr_from_user32_to_kern(struct msghdr
*kmsg
,
2024 struct msghdr32
*umsg
)
2026 u32 tmp1
, tmp2
, tmp3
;
2029 err
= get_user(tmp1
, &umsg
->msg_name
);
2030 err
|= __get_user(tmp2
, &umsg
->msg_iov
);
2031 err
|= __get_user(tmp3
, &umsg
->msg_control
);
2035 kmsg
->msg_name
= (void *)A(tmp1
);
2036 kmsg
->msg_iov
= (struct iovec
*)A(tmp2
);
2037 kmsg
->msg_control
= (void *)A(tmp3
);
2039 err
= get_user(kmsg
->msg_namelen
, &umsg
->msg_namelen
);
2040 err
|= get_user(kmsg
->msg_iovlen
, &umsg
->msg_iovlen
);
2041 err
|= get_user(kmsg
->msg_controllen
, &umsg
->msg_controllen
);
2042 err
|= get_user(kmsg
->msg_flags
, &umsg
->msg_flags
);
2047 /* I've named the args so it is easy to tell whose space the pointers are in. */
2048 static int verify_iovec32(struct msghdr
*kern_msg
, struct iovec
*kern_iov
,
2049 char *kern_address
, int mode
)
2053 if(kern_msg
->msg_namelen
) {
2054 if(mode
==VERIFY_READ
) {
2055 int err
= move_addr_to_kernel(kern_msg
->msg_name
,
2056 kern_msg
->msg_namelen
,
2061 kern_msg
->msg_name
= kern_address
;
2063 kern_msg
->msg_name
= NULL
;
2065 if(kern_msg
->msg_iovlen
> UIO_FASTIOV
) {
2066 kern_iov
= kmalloc(kern_msg
->msg_iovlen
* sizeof(struct iovec
),
2072 tot_len
= iov_from_user32_to_kern(kern_iov
,
2073 (struct iovec32
*)kern_msg
->msg_iov
,
2074 kern_msg
->msg_iovlen
);
2076 kern_msg
->msg_iov
= kern_iov
;
2077 else if(kern_msg
->msg_iovlen
> UIO_FASTIOV
)
2083 /* There is a lot of hair here because the alignment rules (and
2084 * thus placement) of cmsg headers and length are different for
2085 * 32-bit apps. -DaveM
2087 static int cmsghdr_from_user32_to_kern(struct msghdr
*kmsg
,
2088 unsigned char *stackbuf
, int stackbuf_size
)
2090 struct cmsghdr32
*ucmsg
;
2091 struct cmsghdr
*kcmsg
, *kcmsg_base
;
2092 compat_size_t ucmlen
;
2093 __kernel_size_t kcmlen
, tmp
;
2096 kcmsg_base
= kcmsg
= (struct cmsghdr
*)stackbuf
;
2097 ucmsg
= CMSG32_FIRSTHDR(kmsg
);
2098 while(ucmsg
!= NULL
) {
2099 if(get_user(ucmlen
, &ucmsg
->cmsg_len
))
2103 if(CMSG32_ALIGN(ucmlen
) <
2104 CMSG32_ALIGN(sizeof(struct cmsghdr32
)))
2106 if((unsigned long)(((char *)ucmsg
- (char *)kmsg
->msg_control
)
2107 + ucmlen
) > kmsg
->msg_controllen
)
2110 tmp
= ((ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
))) +
2111 CMSG_ALIGN(sizeof(struct cmsghdr
)));
2113 ucmsg
= CMSG32_NXTHDR(kmsg
, ucmsg
, ucmlen
);
2118 /* The kcmlen holds the 64-bit version of the control length.
2119 * It may not be modified as we do not stick it into the kmsg
2120 * until we have successfully copied over all of the data
2123 if(kcmlen
> stackbuf_size
)
2124 kcmsg_base
= kcmsg
= kmalloc(kcmlen
, GFP_KERNEL
);
2128 /* Now copy them over neatly. */
2129 memset(kcmsg
, 0, kcmlen
);
2130 ucmsg
= CMSG32_FIRSTHDR(kmsg
);
2131 while(ucmsg
!= NULL
) {
2132 __get_user(ucmlen
, &ucmsg
->cmsg_len
);
2133 tmp
= ((ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
))) +
2134 CMSG_ALIGN(sizeof(struct cmsghdr
)));
2135 kcmsg
->cmsg_len
= tmp
;
2136 __get_user(kcmsg
->cmsg_level
, &ucmsg
->cmsg_level
);
2137 __get_user(kcmsg
->cmsg_type
, &ucmsg
->cmsg_type
);
2139 /* Copy over the data. */
2140 if(copy_from_user(CMSG_DATA(kcmsg
),
2142 (ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
)))))
2143 goto out_free_efault
;
2146 kcmsg
= (struct cmsghdr
*)((char *)kcmsg
+ CMSG_ALIGN(tmp
));
2147 ucmsg
= CMSG32_NXTHDR(kmsg
, ucmsg
, ucmlen
);
2150 /* Ok, looks like we made it. Hook it up and return success. */
2151 kmsg
->msg_control
= kcmsg_base
;
2152 kmsg
->msg_controllen
= kcmlen
;
2156 if(kcmsg_base
!= (struct cmsghdr
*)stackbuf
)
2161 static void put_cmsg32(struct msghdr
*kmsg
, int level
, int type
,
2162 int len
, void *data
)
2164 struct cmsghdr32
*cm
= (struct cmsghdr32
*) kmsg
->msg_control
;
2165 struct cmsghdr32 cmhdr
;
2166 int cmlen
= CMSG32_LEN(len
);
2168 if(cm
== NULL
|| kmsg
->msg_controllen
< sizeof(*cm
)) {
2169 kmsg
->msg_flags
|= MSG_CTRUNC
;
2173 if(kmsg
->msg_controllen
< cmlen
) {
2174 kmsg
->msg_flags
|= MSG_CTRUNC
;
2175 cmlen
= kmsg
->msg_controllen
;
2177 cmhdr
.cmsg_level
= level
;
2178 cmhdr
.cmsg_type
= type
;
2179 cmhdr
.cmsg_len
= cmlen
;
2181 if(copy_to_user(cm
, &cmhdr
, sizeof cmhdr
))
2183 if(copy_to_user(CMSG32_DATA(cm
), data
, cmlen
- sizeof(struct cmsghdr32
)))
2185 cmlen
= CMSG32_SPACE(len
);
2186 kmsg
->msg_control
+= cmlen
;
2187 kmsg
->msg_controllen
-= cmlen
;
2190 static void scm_detach_fds32(struct msghdr
*kmsg
, struct scm_cookie
*scm
)
2192 struct cmsghdr32
*cm
= (struct cmsghdr32
*) kmsg
->msg_control
;
2193 int fdmax
= (kmsg
->msg_controllen
- sizeof(struct cmsghdr32
)) / sizeof(int);
2194 int fdnum
= scm
->fp
->count
;
2195 struct file
**fp
= scm
->fp
->fp
;
2202 for (i
= 0, cmfptr
= (int *) CMSG32_DATA(cm
); i
< fdmax
; i
++, cmfptr
++) {
2204 err
= get_unused_fd();
2208 err
= put_user(new_fd
, cmfptr
);
2210 put_unused_fd(new_fd
);
2213 /* Bump the usage count and install the file. */
2215 fd_install(new_fd
, fp
[i
]);
2219 int cmlen
= CMSG32_LEN(i
* sizeof(int));
2221 err
= put_user(SOL_SOCKET
, &cm
->cmsg_level
);
2223 err
= put_user(SCM_RIGHTS
, &cm
->cmsg_type
);
2225 err
= put_user(cmlen
, &cm
->cmsg_len
);
2227 cmlen
= CMSG32_SPACE(i
* sizeof(int));
2228 kmsg
->msg_control
+= cmlen
;
2229 kmsg
->msg_controllen
-= cmlen
;
2233 kmsg
->msg_flags
|= MSG_CTRUNC
;
2236 * All of the files that fit in the message have had their
2237 * usage counts incremented, so we just free the list.
2242 /* In these cases we (currently) can just copy to data over verbatim
2243 * because all CMSGs created by the kernel have well defined types which
2244 * have the same layout in both the 32-bit and 64-bit API. One must add
2245 * some special cased conversions here if we start sending control messages
2246 * with incompatible types.
2248 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2249 * we do our work. The remaining cases are:
2251 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2252 * IP_TTL int 32-bit clean
2253 * IP_TOS __u8 32-bit clean
2254 * IP_RECVOPTS variable length 32-bit clean
2255 * IP_RETOPTS variable length 32-bit clean
2256 * (these last two are clean because the types are defined
2257 * by the IPv4 protocol)
2258 * IP_RECVERR struct sock_extended_err +
2259 * struct sockaddr_in 32-bit clean
2260 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2261 * struct sockaddr_in6 32-bit clean
2262 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2263 * IPV6_HOPLIMIT int 32-bit clean
2264 * IPV6_FLOWINFO u32 32-bit clean
2265 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2266 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2267 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2268 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2270 static void cmsg32_recvmsg_fixup(struct msghdr
*kmsg
, unsigned long orig_cmsg_uptr
)
2272 unsigned char *workbuf
, *wp
;
2273 unsigned long bufsz
, space_avail
;
2274 struct cmsghdr
*ucmsg
;
2276 bufsz
= ((unsigned long)kmsg
->msg_control
) - orig_cmsg_uptr
;
2277 space_avail
= kmsg
->msg_controllen
+ bufsz
;
2278 wp
= workbuf
= kmalloc(bufsz
, GFP_KERNEL
);
2282 /* To make this more sane we assume the kernel sends back properly
2283 * formatted control messages. Because of how the kernel will truncate
2284 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2286 ucmsg
= (struct cmsghdr
*) orig_cmsg_uptr
;
2287 while(((unsigned long)ucmsg
) <=
2288 (((unsigned long)kmsg
->msg_control
) - sizeof(struct cmsghdr
))) {
2289 struct cmsghdr32
*kcmsg32
= (struct cmsghdr32
*) wp
;
2292 /* UCMSG is the 64-bit format CMSG entry in user-space.
2293 * KCMSG32 is within the kernel space temporary buffer
2294 * we use to convert into a 32-bit style CMSG.
2296 __get_user(kcmsg32
->cmsg_len
, &ucmsg
->cmsg_len
);
2297 __get_user(kcmsg32
->cmsg_level
, &ucmsg
->cmsg_level
);
2298 __get_user(kcmsg32
->cmsg_type
, &ucmsg
->cmsg_type
);
2300 clen64
= kcmsg32
->cmsg_len
;
2301 if (kcmsg32
->cmsg_level
== SOL_SOCKET
&&
2302 kcmsg32
->cmsg_type
== SO_TIMESTAMP
) {
2304 struct compat_timeval
*tv32
;
2306 if (clen64
!= CMSG_LEN(sizeof(struct timeval
))) {
2310 copy_from_user(&tv
, CMSG_DATA(ucmsg
), sizeof(tv
));
2311 tv32
= (struct compat_timeval
*) CMSG32_DATA(kcmsg32
);
2312 tv32
->tv_sec
= tv
.tv_sec
;
2313 tv32
->tv_usec
= tv
.tv_usec
;
2314 clen32
= sizeof(*tv32
) +
2315 CMSG32_ALIGN(sizeof(struct cmsghdr32
));
2317 copy_from_user(CMSG32_DATA(kcmsg32
), CMSG_DATA(ucmsg
),
2318 clen64
- CMSG_ALIGN(sizeof(*ucmsg
)));
2319 clen32
= ((clen64
- CMSG_ALIGN(sizeof(*ucmsg
))) +
2320 CMSG32_ALIGN(sizeof(struct cmsghdr32
)));
2322 kcmsg32
->cmsg_len
= clen32
;
2324 ucmsg
= (struct cmsghdr
*) (((char *)ucmsg
) + CMSG_ALIGN(clen64
));
2325 wp
= (((char *)kcmsg32
) + CMSG32_ALIGN(clen32
));
2328 /* Copy back fixed up data, and adjust pointers. */
2329 bufsz
= (wp
- workbuf
);
2330 copy_to_user((void *)orig_cmsg_uptr
, workbuf
, bufsz
);
2332 kmsg
->msg_control
= (struct cmsghdr
*)
2333 (((char *)orig_cmsg_uptr
) + bufsz
);
2334 kmsg
->msg_controllen
= space_avail
- bufsz
;
2340 /* If we leave the 64-bit format CMSG chunks in there,
2341 * the application could get confused and crash. So to
2342 * ensure greater recovery, we report no CMSGs.
2344 kmsg
->msg_controllen
+= bufsz
;
2345 kmsg
->msg_control
= (void *) orig_cmsg_uptr
;
2348 asmlinkage
int sys32_sendmsg(int fd
, struct msghdr32
*user_msg
, unsigned user_flags
)
2350 struct socket
*sock
;
2351 char address
[MAX_SOCK_ADDR
];
2352 struct iovec iov
[UIO_FASTIOV
];
2353 unsigned char ctl
[sizeof(struct cmsghdr
) + 20];
2354 unsigned char *ctl_buf
= ctl
;
2355 struct msghdr kern_msg
;
2358 if(msghdr_from_user32_to_kern(&kern_msg
, user_msg
))
2360 if(kern_msg
.msg_iovlen
> UIO_MAXIOV
)
2362 err
= verify_iovec32(&kern_msg
, iov
, address
, VERIFY_READ
);
2367 if(kern_msg
.msg_controllen
) {
2368 err
= cmsghdr_from_user32_to_kern(&kern_msg
, ctl
, sizeof(ctl
));
2371 ctl_buf
= kern_msg
.msg_control
;
2373 kern_msg
.msg_flags
= user_flags
;
2375 sock
= sockfd_lookup(fd
, &err
);
2377 if (sock
->file
->f_flags
& O_NONBLOCK
)
2378 kern_msg
.msg_flags
|= MSG_DONTWAIT
;
2379 err
= sock_sendmsg(sock
, &kern_msg
, total_len
);
2383 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2387 if(kern_msg
.msg_iov
!= iov
)
2388 kfree(kern_msg
.msg_iov
);
2393 asmlinkage
int sys32_recvmsg(int fd
, struct msghdr32
*user_msg
, unsigned int user_flags
)
2395 struct iovec iovstack
[UIO_FASTIOV
];
2396 struct msghdr kern_msg
;
2397 char addr
[MAX_SOCK_ADDR
];
2398 struct socket
*sock
;
2399 struct iovec
*iov
= iovstack
;
2400 struct sockaddr
*uaddr
;
2402 unsigned long cmsg_ptr
;
2403 int err
, total_len
, len
= 0;
2405 if(msghdr_from_user32_to_kern(&kern_msg
, user_msg
))
2407 if(kern_msg
.msg_iovlen
> UIO_MAXIOV
)
2410 uaddr
= kern_msg
.msg_name
;
2411 uaddr_len
= &user_msg
->msg_namelen
;
2412 err
= verify_iovec32(&kern_msg
, iov
, addr
, VERIFY_WRITE
);
2417 cmsg_ptr
= (unsigned long) kern_msg
.msg_control
;
2418 kern_msg
.msg_flags
= 0;
2420 sock
= sockfd_lookup(fd
, &err
);
2422 struct sock_iocb
*si
;
2425 if (sock
->file
->f_flags
& O_NONBLOCK
)
2426 user_flags
|= MSG_DONTWAIT
;
2428 init_sync_kiocb(&iocb
, NULL
);
2429 si
= kiocb_to_siocb(&iocb
);
2431 si
->scm
= &si
->async_scm
;
2432 si
->msg
= &kern_msg
;
2433 si
->size
= total_len
;
2434 si
->flags
= user_flags
;
2435 memset(si
->scm
, 0, sizeof(*si
->scm
));
2437 err
= sock
->ops
->recvmsg(&iocb
, sock
, &kern_msg
, total_len
,
2438 user_flags
, si
->scm
);
2439 if (-EIOCBQUEUED
== err
)
2440 err
= wait_on_sync_kiocb(&iocb
);
2444 if(!kern_msg
.msg_control
) {
2445 if(sock
->passcred
|| si
->scm
->fp
)
2446 kern_msg
.msg_flags
|= MSG_CTRUNC
;
2448 __scm_destroy(si
->scm
);
2450 /* If recvmsg processing itself placed some
2451 * control messages into user space, it's is
2452 * using 64-bit CMSG processing, so we need
2453 * to fix it up before we tack on more stuff.
2455 if((unsigned long) kern_msg
.msg_control
!= cmsg_ptr
)
2456 cmsg32_recvmsg_fixup(&kern_msg
, cmsg_ptr
);
2460 put_cmsg32(&kern_msg
,
2461 SOL_SOCKET
, SCM_CREDENTIALS
,
2462 sizeof(si
->scm
->creds
),
2464 if(si
->scm
->fp
!= NULL
)
2465 scm_detach_fds32(&kern_msg
, si
->scm
);
2471 if(uaddr
!= NULL
&& err
>= 0)
2472 err
= move_addr_to_user(addr
, kern_msg
.msg_namelen
, uaddr
, uaddr_len
);
2473 if(cmsg_ptr
!= 0 && err
>= 0) {
2474 unsigned long ucmsg_ptr
= ((unsigned long)kern_msg
.msg_control
);
2475 compat_size_t uclen
= (compat_size_t
) (ucmsg_ptr
- cmsg_ptr
);
2476 err
|= __put_user(uclen
, &user_msg
->msg_controllen
);
2479 err
= __put_user(kern_msg
.msg_flags
, &user_msg
->msg_flags
);
2480 if(kern_msg
.msg_iov
!= iov
)
2481 kfree(kern_msg
.msg_iov
);
2488 extern asmlinkage
int sys_setsockopt(int fd
, int level
, int optname
,
2489 char *optval
, int optlen
);
2491 static int do_netfilter_replace(int fd
, int level
, int optname
,
2492 char *optval
, int optlen
)
2494 struct ipt_replace32
{
2495 char name
[IPT_TABLE_MAXNAMELEN
];
2499 __u32 hook_entry
[NF_IP_NUMHOOKS
];
2500 __u32 underflow
[NF_IP_NUMHOOKS
];
2503 struct ipt_entry entries
[0];
2504 } *repl32
= (struct ipt_replace32
*)optval
;
2505 struct ipt_replace
*krepl
;
2506 struct ipt_counters
*counters32
;
2508 unsigned int kreplsize
, kcountersize
;
2509 mm_segment_t old_fs
;
2512 if (optlen
< sizeof(repl32
))
2515 if (copy_from_user(&origsize
,
2520 kreplsize
= sizeof(*krepl
) + origsize
;
2521 kcountersize
= krepl
->num_counters
* sizeof(struct ipt_counters
);
2523 /* Hack: Causes ipchains to give correct error msg --RR */
2524 if (optlen
!= kreplsize
)
2525 return -ENOPROTOOPT
;
2527 krepl
= (struct ipt_replace
*)kmalloc(kreplsize
, GFP_KERNEL
);
2531 if (copy_from_user(krepl
, optval
, kreplsize
)) {
2536 counters32
= (struct ipt_counters
*)AA(
2537 ((struct ipt_replace32
*)krepl
)->counters
);
2539 kcountersize
= krepl
->num_counters
* sizeof(struct ipt_counters
);
2540 krepl
->counters
= (struct ipt_counters
*)kmalloc(
2541 kcountersize
, GFP_KERNEL
);
2542 if (krepl
->counters
== NULL
) {
2549 ret
= sys_setsockopt(fd
, level
, optname
,
2550 (char *)krepl
, kreplsize
);
2554 copy_to_user(counters32
, krepl
->counters
, kcountersize
))
2557 kfree(krepl
->counters
);
2563 static int do_set_attach_filter(int fd
, int level
, int optname
,
2564 char *optval
, int optlen
)
2566 struct sock_fprog32
{
2569 } *fprog32
= (struct sock_fprog32
*)optval
;
2570 struct sock_fprog kfprog
;
2571 struct sock_filter
*kfilter
;
2573 mm_segment_t old_fs
;
2577 if (get_user(kfprog
.len
, &fprog32
->len
) ||
2578 __get_user(uptr
, &fprog32
->filter
))
2581 kfprog
.filter
= (struct sock_filter
*)A(uptr
);
2582 fsize
= kfprog
.len
* sizeof(struct sock_filter
);
2584 kfilter
= (struct sock_filter
*)kmalloc(fsize
, GFP_KERNEL
);
2585 if (kfilter
== NULL
)
2588 if (copy_from_user(kfilter
, kfprog
.filter
, fsize
)) {
2593 kfprog
.filter
= kfilter
;
2597 ret
= sys_setsockopt(fd
, level
, optname
,
2598 (char *)&kfprog
, sizeof(kfprog
));
2606 static int do_set_icmpv6_filter(int fd
, int level
, int optname
,
2607 char *optval
, int optlen
)
2609 struct icmp6_filter kfilter
;
2610 mm_segment_t old_fs
;
2613 if (copy_from_user(&kfilter
, optval
, sizeof(kfilter
)))
2617 for (i
= 0; i
< 8; i
+= 2) {
2618 u32 tmp
= kfilter
.data
[i
];
2620 kfilter
.data
[i
] = kfilter
.data
[i
+ 1];
2621 kfilter
.data
[i
+ 1] = tmp
;
2626 ret
= sys_setsockopt(fd
, level
, optname
,
2627 (char *) &kfilter
, sizeof(kfilter
));
2633 static int do_set_sock_timeout(int fd
, int level
, int optname
, char *optval
, int optlen
)
2635 struct compat_timeval
*up
= (struct compat_timeval
*) optval
;
2636 struct timeval ktime
;
2637 mm_segment_t old_fs
;
2640 if (optlen
< sizeof(*up
))
2642 if (get_user(ktime
.tv_sec
, &up
->tv_sec
) ||
2643 __get_user(ktime
.tv_usec
, &up
->tv_usec
))
2647 err
= sys_setsockopt(fd
, level
, optname
, (char *) &ktime
, sizeof(ktime
));
2653 asmlinkage
int sys32_setsockopt(int fd
, int level
, int optname
,
2654 char *optval
, int optlen
)
2656 if (optname
== IPT_SO_SET_REPLACE
)
2657 return do_netfilter_replace(fd
, level
, optname
,
2659 if (optname
== SO_ATTACH_FILTER
)
2660 return do_set_attach_filter(fd
, level
, optname
,
2662 if (optname
== SO_RCVTIMEO
|| optname
== SO_SNDTIMEO
)
2663 return do_set_sock_timeout(fd
, level
, optname
, optval
, optlen
);
2664 if (level
== SOL_ICMPV6
&& optname
== ICMPV6_FILTER
)
2665 return do_set_icmpv6_filter(fd
, level
, optname
,
2668 return sys_setsockopt(fd
, level
, optname
, optval
, optlen
);
2671 extern asmlinkage
long sys_getsockopt(int fd
, int level
, int optname
,
2672 char *optval
, int *optlen
);
2674 static int do_get_sock_timeout(int fd
, int level
, int optname
, char *optval
, int *optlen
)
2676 struct compat_timeval
*up
= (struct compat_timeval
*) optval
;
2677 struct timeval ktime
;
2678 mm_segment_t old_fs
;
2681 if (get_user(len
, optlen
))
2683 if (len
< sizeof(*up
))
2685 len
= sizeof(ktime
);
2688 err
= sys_getsockopt(fd
, level
, optname
, (char *) &ktime
, &len
);
2692 if (put_user(sizeof(*up
), optlen
) ||
2693 put_user(ktime
.tv_sec
, &up
->tv_sec
) ||
2694 __put_user(ktime
.tv_usec
, &up
->tv_usec
))
2700 asmlinkage
int sys32_getsockopt(int fd
, int level
, int optname
,
2701 char *optval
, int *optlen
)
2703 if (optname
== SO_RCVTIMEO
|| optname
== SO_SNDTIMEO
)
2704 return do_get_sock_timeout(fd
, level
, optname
, optval
, optlen
);
2705 return sys_getsockopt(fd
, level
, optname
, optval
, optlen
);
2708 extern void check_pending(int signum
);
2710 asmlinkage
int sys32_sigaction (int sig
, struct old_sigaction32
*act
, struct old_sigaction32
*oact
)
2712 struct k_sigaction new_ka
, old_ka
;
2716 set_thread_flag(TIF_NEWSIGNALS
);
2721 old_sigset_t32 mask
;
2723 ret
= get_user((long)new_ka
.sa
.sa_handler
, &act
->sa_handler
);
2724 ret
|= __get_user((long)new_ka
.sa
.sa_restorer
, &act
->sa_restorer
);
2725 ret
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
2726 ret
|= __get_user(mask
, &act
->sa_mask
);
2729 new_ka
.ka_restorer
= NULL
;
2730 siginitset(&new_ka
.sa
.sa_mask
, mask
);
2733 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
2736 ret
= put_user((long)old_ka
.sa
.sa_handler
, &oact
->sa_handler
);
2737 ret
|= __put_user((long)old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
);
2738 ret
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
2739 ret
|= __put_user(old_ka
.sa
.sa_mask
.sig
[0], &oact
->sa_mask
);
2746 sys32_rt_sigaction(int sig
, struct sigaction32
*act
, struct sigaction32
*oact
,
2747 void *restorer
, compat_size_t sigsetsize
)
2749 struct k_sigaction new_ka
, old_ka
;
2753 /* XXX: Don't preclude handling different sized sigset_t's. */
2754 if (sigsetsize
!= sizeof(sigset_t32
))
2757 /* All tasks which use RT signals (effectively) use
2758 * new style signals.
2760 set_thread_flag(TIF_NEWSIGNALS
);
2763 new_ka
.ka_restorer
= restorer
;
2764 ret
= get_user((long)new_ka
.sa
.sa_handler
, &act
->sa_handler
);
2765 ret
|= __copy_from_user(&set32
, &act
->sa_mask
, sizeof(sigset_t32
));
2766 switch (_NSIG_WORDS
) {
2767 case 4: new_ka
.sa
.sa_mask
.sig
[3] = set32
.sig
[6] | (((long)set32
.sig
[7]) << 32);
2768 case 3: new_ka
.sa
.sa_mask
.sig
[2] = set32
.sig
[4] | (((long)set32
.sig
[5]) << 32);
2769 case 2: new_ka
.sa
.sa_mask
.sig
[1] = set32
.sig
[2] | (((long)set32
.sig
[3]) << 32);
2770 case 1: new_ka
.sa
.sa_mask
.sig
[0] = set32
.sig
[0] | (((long)set32
.sig
[1]) << 32);
2772 ret
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
2773 ret
|= __get_user((long)new_ka
.sa
.sa_restorer
, &act
->sa_restorer
);
2778 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
2781 switch (_NSIG_WORDS
) {
2782 case 4: set32
.sig
[7] = (old_ka
.sa
.sa_mask
.sig
[3] >> 32); set32
.sig
[6] = old_ka
.sa
.sa_mask
.sig
[3];
2783 case 3: set32
.sig
[5] = (old_ka
.sa
.sa_mask
.sig
[2] >> 32); set32
.sig
[4] = old_ka
.sa
.sa_mask
.sig
[2];
2784 case 2: set32
.sig
[3] = (old_ka
.sa
.sa_mask
.sig
[1] >> 32); set32
.sig
[2] = old_ka
.sa
.sa_mask
.sig
[1];
2785 case 1: set32
.sig
[1] = (old_ka
.sa
.sa_mask
.sig
[0] >> 32); set32
.sig
[0] = old_ka
.sa
.sa_mask
.sig
[0];
2787 ret
= put_user((long)old_ka
.sa
.sa_handler
, &oact
->sa_handler
);
2788 ret
|= __copy_to_user(&oact
->sa_mask
, &set32
, sizeof(sigset_t32
));
2789 ret
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
2790 ret
|= __put_user((long)old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
);
2800 * count32() counts the number of arguments/envelopes
2802 static int count32(u32
* argv
, int max
)
2810 error
= get_user(p
,argv
);
2824 * 'copy_string32()' copies argument/envelope strings from user
2825 * memory to free pages in kernel mem. These are in a format ready
2826 * to be put directly into the top of new user memory.
2828 static int copy_strings32(int argc
, u32
* argv
, struct linux_binprm
*bprm
)
2830 while (argc
-- > 0) {
2835 if (get_user(str
, argv
+ argc
) ||
2837 !(len
= strnlen_user((char *)A(str
), bprm
->p
)))
2849 int offset
, bytes_to_copy
, new, err
;
2851 offset
= pos
% PAGE_SIZE
;
2852 page
= bprm
->page
[pos
/ PAGE_SIZE
];
2855 page
= alloc_page(GFP_USER
);
2856 bprm
->page
[pos
/ PAGE_SIZE
] = page
;
2864 memset(kaddr
, 0, offset
);
2865 bytes_to_copy
= PAGE_SIZE
- offset
;
2866 if (bytes_to_copy
> len
) {
2867 bytes_to_copy
= len
;
2869 memset(kaddr
+offset
+len
, 0,
2870 PAGE_SIZE
-offset
-len
);
2873 err
= copy_from_user(kaddr
+ offset
, (char *)A(str
),
2880 pos
+= bytes_to_copy
;
2881 str
+= bytes_to_copy
;
2882 len
-= bytes_to_copy
;
2889 * sys32_execve() executes a new program.
2892 do_execve32(char * filename
, u32
* argv
, u32
* envp
, struct pt_regs
* regs
)
2894 struct linux_binprm bprm
;
2899 file
= open_exec(filename
);
2901 retval
= PTR_ERR(file
);
2905 bprm
.p
= PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(void *);
2906 memset(bprm
.page
, 0, MAX_ARG_PAGES
* sizeof(bprm
.page
[0]));
2909 bprm
.filename
= filename
;
2913 bprm
.security
= NULL
;
2914 bprm
.mm
= mm_alloc();
2919 retval
= init_new_context(current
, bprm
.mm
);
2923 bprm
.argc
= count32(argv
, bprm
.p
/ sizeof(u32
));
2924 if ((retval
= bprm
.argc
) < 0)
2927 bprm
.envc
= count32(envp
, bprm
.p
/ sizeof(u32
));
2928 if ((retval
= bprm
.envc
) < 0)
2931 retval
= security_bprm_alloc(&bprm
);
2935 retval
= prepare_binprm(&bprm
);
2939 retval
= copy_strings_kernel(1, &bprm
.filename
, &bprm
);
2944 retval
= copy_strings32(bprm
.envc
, envp
, &bprm
);
2948 retval
= copy_strings32(bprm
.argc
, argv
, &bprm
);
2952 retval
= search_binary_handler(&bprm
, regs
);
2954 /* execve success */
2955 security_bprm_free(&bprm
);
2960 /* Something went wrong, return the inode and free the argument pages*/
2961 for (i
= 0 ; i
< MAX_ARG_PAGES
; i
++) {
2962 struct page
* page
= bprm
.page
[i
];
2968 security_bprm_free(&bprm
);
2975 allow_write_access(bprm
.file
);
2982 * sparc32_execve() executes a new program after the asm stub has set
2983 * things up for us. This should basically do what I want it to.
2985 asmlinkage
int sparc32_execve(struct pt_regs
*regs
)
2987 int error
, base
= 0;
2990 /* User register window flush is done by entry.S */
2992 /* Check for indirect call. */
2993 if((u32
)regs
->u_regs
[UREG_G1
] == 0)
2996 filename
= getname((char *)AA(regs
->u_regs
[base
+ UREG_I0
]));
2997 error
= PTR_ERR(filename
);
2998 if(IS_ERR(filename
))
3000 error
= do_execve32(filename
,
3001 (u32
*)AA((u32
)regs
->u_regs
[base
+ UREG_I1
]),
3002 (u32
*)AA((u32
)regs
->u_regs
[base
+ UREG_I2
]), regs
);
3007 current_thread_info()->xfsr
[0] = 0;
3008 current_thread_info()->fpsaved
[0] = 0;
3009 regs
->tstate
&= ~TSTATE_PEF
;
3010 current
->ptrace
&= ~PT_DTRACE
;
3016 #ifdef CONFIG_MODULES
3018 extern asmlinkage
long sys_init_module(void *, unsigned long, const char *);
3020 asmlinkage
int sys32_init_module(void *umod
, u32 len
, const char *uargs
)
3022 return sys_init_module(umod
, len
, uargs
);
3025 extern asmlinkage
long sys_delete_module(const char *, unsigned int);
3027 asmlinkage
int sys32_delete_module(const char *name_user
, unsigned int flags
)
3029 return sys_delete_module(name_user
, flags
);
3032 #else /* CONFIG_MODULES */
3035 sys32_init_module(const char *name_user
, struct module
*mod_user
)
3041 sys32_delete_module(const char *name_user
)
3046 #endif /* CONFIG_MODULES */
3048 #if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
3049 /* Stuff for NFS server syscalls... */
3050 struct nfsctl_svc32
{
3055 struct nfsctl_client32
{
3056 s8 cl32_ident
[NFSCLNT_IDMAX
+1];
3058 struct in_addr cl32_addrlist
[NFSCLNT_ADDRMAX
];
3061 u8 cl32_fhkey
[NFSCLNT_KEYMAX
];
3064 struct nfsctl_export32
{
3065 s8 ex32_client
[NFSCLNT_IDMAX
+1];
3066 s8 ex32_path
[NFS_MAXPATHLEN
+1];
3067 compat_dev_t ex32_dev
;
3068 compat_ino_t ex32_ino
;
3070 compat_uid_t ex32_anon_uid
;
3071 compat_gid_t ex32_anon_gid
;
3074 struct nfsctl_uidmap32
{
3075 u32 ug32_ident
; /* char * */
3076 compat_uid_t ug32_uidbase
;
3078 u32 ug32_udimap
; /* uid_t * */
3079 compat_uid_t ug32_gidbase
;
3081 u32 ug32_gdimap
; /* gid_t * */
3084 struct nfsctl_fhparm32
{
3085 struct sockaddr gf32_addr
;
3086 compat_dev_t gf32_dev
;
3087 compat_ino_t gf32_ino
;
3091 struct nfsctl_fdparm32
{
3092 struct sockaddr gd32_addr
;
3093 s8 gd32_path
[NFS_MAXPATHLEN
+1];
3097 struct nfsctl_fsparm32
{
3098 struct sockaddr gd32_addr
;
3099 s8 gd32_path
[NFS_MAXPATHLEN
+1];
3103 struct nfsctl_arg32
{
3104 s32 ca32_version
; /* safeguard */
3106 struct nfsctl_svc32 u32_svc
;
3107 struct nfsctl_client32 u32_client
;
3108 struct nfsctl_export32 u32_export
;
3109 struct nfsctl_uidmap32 u32_umap
;
3110 struct nfsctl_fhparm32 u32_getfh
;
3111 struct nfsctl_fdparm32 u32_getfd
;
3112 struct nfsctl_fsparm32 u32_getfs
;
3114 #define ca32_svc u.u32_svc
3115 #define ca32_client u.u32_client
3116 #define ca32_export u.u32_export
3117 #define ca32_umap u.u32_umap
3118 #define ca32_getfh u.u32_getfh
3119 #define ca32_getfd u.u32_getfd
3120 #define ca32_getfs u.u32_getfs
3121 #define ca32_authd u.u32_authd
3124 union nfsctl_res32
{
3125 __u8 cr32_getfh
[NFS_FHSIZE
];
3126 struct knfsd_fh cr32_getfs
;
3129 static int nfs_svc32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3133 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3134 err
|= __get_user(karg
->ca_svc
.svc_port
, &arg32
->ca32_svc
.svc32_port
);
3135 err
|= __get_user(karg
->ca_svc
.svc_nthreads
, &arg32
->ca32_svc
.svc32_nthreads
);
3139 static int nfs_clnt32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3143 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3144 err
|= copy_from_user(&karg
->ca_client
.cl_ident
[0],
3145 &arg32
->ca32_client
.cl32_ident
[0],
3147 err
|= __get_user(karg
->ca_client
.cl_naddr
, &arg32
->ca32_client
.cl32_naddr
);
3148 err
|= copy_from_user(&karg
->ca_client
.cl_addrlist
[0],
3149 &arg32
->ca32_client
.cl32_addrlist
[0],
3150 (sizeof(struct in_addr
) * NFSCLNT_ADDRMAX
));
3151 err
|= __get_user(karg
->ca_client
.cl_fhkeytype
,
3152 &arg32
->ca32_client
.cl32_fhkeytype
);
3153 err
|= __get_user(karg
->ca_client
.cl_fhkeylen
,
3154 &arg32
->ca32_client
.cl32_fhkeylen
);
3155 err
|= copy_from_user(&karg
->ca_client
.cl_fhkey
[0],
3156 &arg32
->ca32_client
.cl32_fhkey
[0],
3158 return (err
? -EFAULT
: 0);
3161 static int nfs_exp32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3165 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3166 err
|= copy_from_user(&karg
->ca_export
.ex_client
[0],
3167 &arg32
->ca32_export
.ex32_client
[0],
3169 err
|= copy_from_user(&karg
->ca_export
.ex_path
[0],
3170 &arg32
->ca32_export
.ex32_path
[0],
3172 err
|= __get_user(karg
->ca_export
.ex_dev
,
3173 &arg32
->ca32_export
.ex32_dev
);
3174 err
|= __get_user(karg
->ca_export
.ex_ino
,
3175 &arg32
->ca32_export
.ex32_ino
);
3176 err
|= __get_user(karg
->ca_export
.ex_flags
,
3177 &arg32
->ca32_export
.ex32_flags
);
3178 err
|= __get_user(karg
->ca_export
.ex_anon_uid
,
3179 &arg32
->ca32_export
.ex32_anon_uid
);
3180 err
|= __get_user(karg
->ca_export
.ex_anon_gid
,
3181 &arg32
->ca32_export
.ex32_anon_gid
);
3182 karg
->ca_export
.ex_anon_uid
= high2lowuid(karg
->ca_export
.ex_anon_uid
);
3183 karg
->ca_export
.ex_anon_gid
= high2lowgid(karg
->ca_export
.ex_anon_gid
);
3184 return (err
? -EFAULT
: 0);
3187 static int nfs_uud32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3193 memset(karg
, 0, sizeof(*karg
));
3194 if(__get_user(karg
->ca_version
, &arg32
->ca32_version
))
3196 karg
->ca_umap
.ug_ident
= (char *)get_zeroed_page(GFP_USER
);
3197 if(!karg
->ca_umap
.ug_ident
)
3199 err
= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_ident
);
3200 if(strncpy_from_user(karg
->ca_umap
.ug_ident
,
3201 (char *)A(uaddr
), PAGE_SIZE
) <= 0)
3203 err
|= __get_user(karg
->ca_umap
.ug_uidbase
,
3204 &arg32
->ca32_umap
.ug32_uidbase
);
3205 err
|= __get_user(karg
->ca_umap
.ug_uidlen
,
3206 &arg32
->ca32_umap
.ug32_uidlen
);
3207 err
|= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_udimap
);
3210 karg
->ca_umap
.ug_udimap
= kmalloc((sizeof(uid_t
) * karg
->ca_umap
.ug_uidlen
),
3212 if(!karg
->ca_umap
.ug_udimap
)
3214 for(i
= 0; i
< karg
->ca_umap
.ug_uidlen
; i
++)
3215 err
|= __get_user(karg
->ca_umap
.ug_udimap
[i
],
3216 &(((compat_uid_t
*)A(uaddr
))[i
]));
3217 err
|= __get_user(karg
->ca_umap
.ug_gidbase
,
3218 &arg32
->ca32_umap
.ug32_gidbase
);
3219 err
|= __get_user(karg
->ca_umap
.ug_uidlen
,
3220 &arg32
->ca32_umap
.ug32_gidlen
);
3221 err
|= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_gdimap
);
3224 karg
->ca_umap
.ug_gdimap
= kmalloc((sizeof(gid_t
) * karg
->ca_umap
.ug_uidlen
),
3226 if(!karg
->ca_umap
.ug_gdimap
)
3228 for(i
= 0; i
< karg
->ca_umap
.ug_gidlen
; i
++)
3229 err
|= __get_user(karg
->ca_umap
.ug_gdimap
[i
],
3230 &(((compat_gid_t
*)A(uaddr
))[i
]));
3232 return (err
? -EFAULT
: 0);
3235 static int nfs_getfh32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3239 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3240 err
|= copy_from_user(&karg
->ca_getfh
.gf_addr
,
3241 &arg32
->ca32_getfh
.gf32_addr
,
3242 (sizeof(struct sockaddr
)));
3243 err
|= __get_user(karg
->ca_getfh
.gf_dev
,
3244 &arg32
->ca32_getfh
.gf32_dev
);
3245 err
|= __get_user(karg
->ca_getfh
.gf_ino
,
3246 &arg32
->ca32_getfh
.gf32_ino
);
3247 err
|= __get_user(karg
->ca_getfh
.gf_version
,
3248 &arg32
->ca32_getfh
.gf32_version
);
3249 return (err
? -EFAULT
: 0);
3252 static int nfs_getfd32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3256 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3257 err
|= copy_from_user(&karg
->ca_getfd
.gd_addr
,
3258 &arg32
->ca32_getfd
.gd32_addr
,
3259 (sizeof(struct sockaddr
)));
3260 err
|= copy_from_user(&karg
->ca_getfd
.gd_path
,
3261 &arg32
->ca32_getfd
.gd32_path
,
3262 (NFS_MAXPATHLEN
+1));
3263 err
|= __get_user(karg
->ca_getfd
.gd_version
,
3264 &arg32
->ca32_getfd
.gd32_version
);
3265 return (err
? -EFAULT
: 0);
3268 static int nfs_getfs32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3272 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3273 err
|= copy_from_user(&karg
->ca_getfs
.gd_addr
,
3274 &arg32
->ca32_getfs
.gd32_addr
,
3275 (sizeof(struct sockaddr
)));
3276 err
|= copy_from_user(&karg
->ca_getfs
.gd_path
,
3277 &arg32
->ca32_getfs
.gd32_path
,
3278 (NFS_MAXPATHLEN
+1));
3279 err
|= __get_user(karg
->ca_getfs
.gd_maxlen
,
3280 &arg32
->ca32_getfs
.gd32_maxlen
);
3281 return (err
? -EFAULT
: 0);
3284 /* This really doesn't need translations, we are only passing
3285 * back a union which contains opaque nfs file handle data.
3287 static int nfs_getfh32_res_trans(union nfsctl_res
*kres
, union nfsctl_res32
*res32
)
3289 return (copy_to_user(res32
, kres
, sizeof(*res32
)) ? -EFAULT
: 0);
3292 int asmlinkage
sys32_nfsservctl(int cmd
, struct nfsctl_arg32
*arg32
, union nfsctl_res32
*res32
)
3294 struct nfsctl_arg
*karg
= NULL
;
3295 union nfsctl_res
*kres
= NULL
;
3299 karg
= kmalloc(sizeof(*karg
), GFP_USER
);
3303 kres
= kmalloc(sizeof(*kres
), GFP_USER
);
3311 err
= nfs_svc32_trans(karg
, arg32
);
3313 case NFSCTL_ADDCLIENT
:
3314 err
= nfs_clnt32_trans(karg
, arg32
);
3316 case NFSCTL_DELCLIENT
:
3317 err
= nfs_clnt32_trans(karg
, arg32
);
3320 case NFSCTL_UNEXPORT
:
3321 err
= nfs_exp32_trans(karg
, arg32
);
3323 /* This one is unimplemented, be we're ready for it. */
3324 case NFSCTL_UGIDUPDATE
:
3325 err
= nfs_uud32_trans(karg
, arg32
);
3328 err
= nfs_getfh32_trans(karg
, arg32
);
3331 err
= nfs_getfd32_trans(karg
, arg32
);
3334 err
= nfs_getfs32_trans(karg
, arg32
);
3344 err
= sys_nfsservctl(cmd
, karg
, kres
);
3350 if((cmd
== NFSCTL_GETFH
) ||
3351 (cmd
== NFSCTL_GETFD
) ||
3352 (cmd
== NFSCTL_GETFS
))
3353 err
= nfs_getfh32_res_trans(kres
, res32
);
3357 if(cmd
== NFSCTL_UGIDUPDATE
) {
3358 if(karg
->ca_umap
.ug_ident
)
3359 kfree(karg
->ca_umap
.ug_ident
);
3360 if(karg
->ca_umap
.ug_udimap
)
3361 kfree(karg
->ca_umap
.ug_udimap
);
3362 if(karg
->ca_umap
.ug_gdimap
)
3363 kfree(karg
->ca_umap
.ug_gdimap
);
3372 extern asmlinkage
long sys_ni_syscall(void);
3373 int asmlinkage
sys32_nfsservctl(int cmd
, void *notused
, void *notused2
)
3375 return sys_ni_syscall();
3379 /* Translations due to time_t size differences. Which affects all
3380 sorts of things, like timeval and itimerval. */
3382 extern struct timezone sys_tz
;
3383 extern int do_sys_settimeofday(struct timeval
*tv
, struct timezone
*tz
);
3385 asmlinkage
int sys32_gettimeofday(struct compat_timeval
*tv
, struct timezone
*tz
)
3389 do_gettimeofday(&ktv
);
3390 if (put_tv32(tv
, &ktv
))
3394 if (copy_to_user(tz
, &sys_tz
, sizeof(sys_tz
)))
3400 asmlinkage
int sys32_settimeofday(struct compat_timeval
*tv
, struct timezone
*tz
)
3403 struct timezone ktz
;
3406 if (get_tv32(&ktv
, tv
))
3410 if (copy_from_user(&ktz
, tz
, sizeof(ktz
)))
3414 return do_sys_settimeofday(tv
? &ktv
: NULL
, tz
? &ktz
: NULL
);
3417 asmlinkage
int sys32_utimes(char *filename
, struct compat_timeval
*tvs
)
3420 struct timeval ktvs
[2];
3421 mm_segment_t old_fs
;
3424 kfilename
= getname(filename
);
3425 ret
= PTR_ERR(kfilename
);
3426 if (!IS_ERR(kfilename
)) {
3428 if (get_tv32(&ktvs
[0], tvs
) ||
3429 get_tv32(&ktvs
[1], 1+tvs
))
3435 ret
= do_utimes(kfilename
, (tvs
? &ktvs
[0] : NULL
));
3443 /* These are here just in case some old sparc32 binary calls it. */
3444 asmlinkage
int sys32_pause(void)
3446 current
->state
= TASK_INTERRUPTIBLE
;
3448 return -ERESTARTNOHAND
;
3451 /* PCI config space poking. */
3452 extern asmlinkage
int sys_pciconfig_read(unsigned long bus
,
3456 unsigned char *buf
);
3458 extern asmlinkage
int sys_pciconfig_write(unsigned long bus
,
3462 unsigned char *buf
);
3464 asmlinkage
int sys32_pciconfig_read(u32 bus
, u32 dfn
, u32 off
, u32 len
, u32 ubuf
)
3466 return sys_pciconfig_read((unsigned long) bus
,
3467 (unsigned long) dfn
,
3468 (unsigned long) off
,
3469 (unsigned long) len
,
3470 (unsigned char *)AA(ubuf
));
3473 asmlinkage
int sys32_pciconfig_write(u32 bus
, u32 dfn
, u32 off
, u32 len
, u32 ubuf
)
3475 return sys_pciconfig_write((unsigned long) bus
,
3476 (unsigned long) dfn
,
3477 (unsigned long) off
,
3478 (unsigned long) len
,
3479 (unsigned char *)AA(ubuf
));
3482 extern asmlinkage
int sys_prctl(int option
, unsigned long arg2
, unsigned long arg3
,
3483 unsigned long arg4
, unsigned long arg5
);
3485 asmlinkage
int sys32_prctl(int option
, u32 arg2
, u32 arg3
, u32 arg4
, u32 arg5
)
3487 return sys_prctl(option
,
3488 (unsigned long) arg2
,
3489 (unsigned long) arg3
,
3490 (unsigned long) arg4
,
3491 (unsigned long) arg5
);
3495 extern asmlinkage ssize_t
sys_pread64(unsigned int fd
, char * buf
,
3496 size_t count
, loff_t pos
);
3498 extern asmlinkage ssize_t
sys_pwrite64(unsigned int fd
, const char * buf
,
3499 size_t count
, loff_t pos
);
3501 asmlinkage compat_ssize_t
sys32_pread64(unsigned int fd
, char *ubuf
,
3502 compat_size_t count
, u32 poshi
, u32 poslo
)
3504 return sys_pread64(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
3507 asmlinkage compat_ssize_t
sys32_pwrite64(unsigned int fd
, char *ubuf
,
3508 compat_size_t count
, u32 poshi
, u32 poslo
)
3510 return sys_pwrite64(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
3513 extern asmlinkage ssize_t
sys_readahead(int fd
, loff_t offset
, size_t count
);
3515 asmlinkage compat_ssize_t
sys32_readahead(int fd
, u32 offhi
, u32 offlo
, s32 count
)
3517 return sys_readahead(fd
, ((loff_t
)AA(offhi
) << 32) | AA(offlo
), count
);
3520 extern asmlinkage ssize_t
sys_sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
);
3522 asmlinkage
int sys32_sendfile(int out_fd
, int in_fd
, compat_off_t
*offset
, s32 count
)
3524 mm_segment_t old_fs
= get_fs();
3528 if (offset
&& get_user(of
, offset
))
3532 ret
= sys_sendfile(out_fd
, in_fd
, offset
? &of
: NULL
, count
);
3535 if (offset
&& put_user(of
, offset
))
3541 extern asmlinkage ssize_t
sys_sendfile64(int out_fd
, int in_fd
, loff_t
*offset
, size_t count
);
3543 asmlinkage
int sys32_sendfile64(int out_fd
, int in_fd
, compat_loff_t
*offset
, s32 count
)
3545 mm_segment_t old_fs
= get_fs();
3549 if (offset
&& get_user(lof
, offset
))
3553 ret
= sys_sendfile64(out_fd
, in_fd
, offset
? &lof
: NULL
, count
);
3556 if (offset
&& put_user(lof
, offset
))
3562 /* Handle adjtimex compatability. */
3566 s32 offset
, freq
, maxerror
, esterror
;
3567 s32 status
, constant
, precision
, tolerance
;
3568 struct compat_timeval time
;
3570 s32 ppsfreq
, jitter
, shift
, stabil
;
3571 s32 jitcnt
, calcnt
, errcnt
, stbcnt
;
3572 s32
:32; s32
:32; s32
:32; s32
:32;
3573 s32
:32; s32
:32; s32
:32; s32
:32;
3574 s32
:32; s32
:32; s32
:32; s32
:32;
3577 extern int do_adjtimex(struct timex
*);
3579 asmlinkage
int sys32_adjtimex(struct timex32
*utp
)
3584 memset(&txc
, 0, sizeof(struct timex
));
3586 if(get_user(txc
.modes
, &utp
->modes
) ||
3587 __get_user(txc
.offset
, &utp
->offset
) ||
3588 __get_user(txc
.freq
, &utp
->freq
) ||
3589 __get_user(txc
.maxerror
, &utp
->maxerror
) ||
3590 __get_user(txc
.esterror
, &utp
->esterror
) ||
3591 __get_user(txc
.status
, &utp
->status
) ||
3592 __get_user(txc
.constant
, &utp
->constant
) ||
3593 __get_user(txc
.precision
, &utp
->precision
) ||
3594 __get_user(txc
.tolerance
, &utp
->tolerance
) ||
3595 __get_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
3596 __get_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
3597 __get_user(txc
.tick
, &utp
->tick
) ||
3598 __get_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
3599 __get_user(txc
.jitter
, &utp
->jitter
) ||
3600 __get_user(txc
.shift
, &utp
->shift
) ||
3601 __get_user(txc
.stabil
, &utp
->stabil
) ||
3602 __get_user(txc
.jitcnt
, &utp
->jitcnt
) ||
3603 __get_user(txc
.calcnt
, &utp
->calcnt
) ||
3604 __get_user(txc
.errcnt
, &utp
->errcnt
) ||
3605 __get_user(txc
.stbcnt
, &utp
->stbcnt
))
3608 ret
= do_adjtimex(&txc
);
3610 if(put_user(txc
.modes
, &utp
->modes
) ||
3611 __put_user(txc
.offset
, &utp
->offset
) ||
3612 __put_user(txc
.freq
, &utp
->freq
) ||
3613 __put_user(txc
.maxerror
, &utp
->maxerror
) ||
3614 __put_user(txc
.esterror
, &utp
->esterror
) ||
3615 __put_user(txc
.status
, &utp
->status
) ||
3616 __put_user(txc
.constant
, &utp
->constant
) ||
3617 __put_user(txc
.precision
, &utp
->precision
) ||
3618 __put_user(txc
.tolerance
, &utp
->tolerance
) ||
3619 __put_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
3620 __put_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
3621 __put_user(txc
.tick
, &utp
->tick
) ||
3622 __put_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
3623 __put_user(txc
.jitter
, &utp
->jitter
) ||
3624 __put_user(txc
.shift
, &utp
->shift
) ||
3625 __put_user(txc
.stabil
, &utp
->stabil
) ||
3626 __put_user(txc
.jitcnt
, &utp
->jitcnt
) ||
3627 __put_user(txc
.calcnt
, &utp
->calcnt
) ||
3628 __put_user(txc
.errcnt
, &utp
->errcnt
) ||
3629 __put_user(txc
.stbcnt
, &utp
->stbcnt
))
3635 /* This is just a version for 32-bit applications which does
3636 * not force O_LARGEFILE on.
3639 asmlinkage
long sparc32_open(const char * filename
, int flags
, int mode
)
3644 tmp
= getname(filename
);
3647 fd
= get_unused_fd();
3649 struct file
* f
= filp_open(tmp
, flags
, mode
);
3666 extern unsigned long do_mremap(unsigned long addr
,
3667 unsigned long old_len
, unsigned long new_len
,
3668 unsigned long flags
, unsigned long new_addr
);
3670 asmlinkage
unsigned long sys32_mremap(unsigned long addr
,
3671 unsigned long old_len
, unsigned long new_len
,
3672 unsigned long flags
, u32 __new_addr
)
3674 struct vm_area_struct
*vma
;
3675 unsigned long ret
= -EINVAL
;
3676 unsigned long new_addr
= AA(__new_addr
);
3678 if (old_len
> 0xf0000000UL
|| new_len
> 0xf0000000UL
)
3680 if (addr
> 0xf0000000UL
- old_len
)
3682 down_write(¤t
->mm
->mmap_sem
);
3683 if (flags
& MREMAP_FIXED
) {
3684 if (new_addr
> 0xf0000000UL
- new_len
)
3686 } else if (addr
> 0xf0000000UL
- new_len
) {
3687 unsigned long map_flags
= 0;
3688 struct file
*file
= NULL
;
3691 if (!(flags
& MREMAP_MAYMOVE
))
3694 vma
= find_vma(current
->mm
, addr
);
3696 if (vma
->vm_flags
& VM_SHARED
)
3697 map_flags
|= MAP_SHARED
;
3698 file
= vma
->vm_file
;
3701 /* MREMAP_FIXED checked above. */
3702 new_addr
= get_unmapped_area(file
, addr
, new_len
,
3703 vma
? vma
->vm_pgoff
: 0,
3706 if (new_addr
& ~PAGE_MASK
)
3708 flags
|= MREMAP_FIXED
;
3710 ret
= do_mremap(addr
, old_len
, new_len
, flags
, new_addr
);
3712 up_write(¤t
->mm
->mmap_sem
);
3717 extern asmlinkage
long sys_setpriority(int which
, int who
, int niceval
);
3719 asmlinkage
int sys_setpriority32(u32 which
, u32 who
, u32 niceval
)
3721 return sys_setpriority((int) which
,
3726 struct __sysctl_args32
{
3736 asmlinkage
long sys32_sysctl(struct __sysctl_args32
*args
)
3738 struct __sysctl_args32 tmp
;
3740 size_t oldlen
, *oldlenp
= NULL
;
3741 unsigned long addr
= (((long)&args
->__unused
[0]) + 7) & ~7;
3743 if (copy_from_user(&tmp
, args
, sizeof(tmp
)))
3746 if (tmp
.oldval
&& tmp
.oldlenp
) {
3747 /* Duh, this is ugly and might not work if sysctl_args
3748 is in read-only memory, but do_sysctl does indirectly
3749 a lot of uaccess in both directions and we'd have to
3750 basically copy the whole sysctl.c here, and
3751 glibc's __sysctl uses rw memory for the structure
3753 if (get_user(oldlen
, (u32
*)A(tmp
.oldlenp
)) ||
3754 put_user(oldlen
, (size_t *)addr
))
3756 oldlenp
= (size_t *)addr
;
3760 error
= do_sysctl((int *)A(tmp
.name
), tmp
.nlen
, (void *)A(tmp
.oldval
),
3761 oldlenp
, (void *)A(tmp
.newval
), tmp
.newlen
);
3765 if (get_user(oldlen
, (size_t *)addr
) ||
3766 put_user(oldlen
, (u32
*)A(tmp
.oldlenp
)))
3769 copy_to_user(args
->__unused
, tmp
.__unused
, sizeof(tmp
.__unused
));
3774 extern asmlinkage
int sys_sched_setaffinity(pid_t pid
, unsigned int len
,
3775 unsigned long *user_mask_ptr
);
3777 asmlinkage
int sys32_sched_setaffinity(compat_pid_t pid
, unsigned int len
,
3780 unsigned long kernel_mask
;
3781 mm_segment_t old_fs
;
3784 if (get_user(kernel_mask
, user_mask_ptr
))
3789 ret
= sys_sched_setaffinity(pid
,
3790 /* XXX Nice api... */
3791 sizeof(kernel_mask
),
3798 extern asmlinkage
int sys_sched_getaffinity(pid_t pid
, unsigned int len
,
3799 unsigned long *user_mask_ptr
);
3801 asmlinkage
int sys32_sched_getaffinity(compat_pid_t pid
, unsigned int len
,
3804 unsigned long kernel_mask
;
3805 mm_segment_t old_fs
;
3810 ret
= sys_sched_getaffinity(pid
,
3811 /* XXX Nice api... */
3812 sizeof(kernel_mask
),
3817 if (put_user(kernel_mask
, user_mask_ptr
))
3824 extern int sys_lookup_dcookie(u64 cookie64
, char *buf
, size_t len
);
3826 int sys32_lookup_dcookie(u32 cookie_high
, u32 cookie_low
, char *buf
, size_t len
)
3828 return sys_lookup_dcookie((u64
)cookie_high
<< 32 | cookie_low
,