2 * arch/s390x/kernel/linux32.c
5 * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7 * Gerhard Tonn (ton@de.ibm.com)
9 * Conversion between 31bit and 64bit native syscalls.
11 * Heavily inspired by the 32-bit Sparc compat code which is
12 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
13 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
18 #include <linux/config.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
23 #include <linux/file.h>
24 #include <linux/signal.h>
25 #include <linux/resource.h>
26 #include <linux/times.h>
27 #include <linux/utsname.h>
28 #include <linux/timex.h>
29 #include <linux/smp.h>
30 #include <linux/smp_lock.h>
31 #include <linux/sem.h>
32 #include <linux/msg.h>
33 #include <linux/shm.h>
34 #include <linux/slab.h>
35 #include <linux/uio.h>
36 #include <linux/nfs_fs.h>
37 #include <linux/smb_fs.h>
38 #include <linux/smb_mount.h>
39 #include <linux/ncp_fs.h>
40 #include <linux/quota.h>
41 #include <linux/module.h>
42 #include <linux/sunrpc/svc.h>
43 #include <linux/nfsd/nfsd.h>
44 #include <linux/nfsd/cache.h>
45 #include <linux/nfsd/xdr.h>
46 #include <linux/nfsd/syscall.h>
47 #include <linux/poll.h>
48 #include <linux/personality.h>
49 #include <linux/stat.h>
50 #include <linux/filter.h>
51 #include <linux/highmem.h>
52 #include <linux/highuid.h>
53 #include <linux/mman.h>
54 #include <linux/ipv6.h>
56 #include <linux/icmpv6.h>
57 #include <linux/sysctl.h>
58 #include <linux/binfmts.h>
59 #include <linux/compat.h>
60 #include <linux/vfs.h>
61 #include <linux/ptrace.h>
63 #include <asm/types.h>
65 #include <asm/uaccess.h>
66 #include <asm/semaphore.h>
71 #include "compat_linux.h"
73 extern asmlinkage
long sys_chown(const char *, uid_t
,gid_t
);
74 extern asmlinkage
long sys_lchown(const char *, uid_t
,gid_t
);
75 extern asmlinkage
long sys_fchown(unsigned int, uid_t
,gid_t
);
76 extern asmlinkage
long sys_setregid(gid_t
, gid_t
);
77 extern asmlinkage
long sys_setgid(gid_t
);
78 extern asmlinkage
long sys_setreuid(uid_t
, uid_t
);
79 extern asmlinkage
long sys_setuid(uid_t
);
80 extern asmlinkage
long sys_setresuid(uid_t
, uid_t
, uid_t
);
81 extern asmlinkage
long sys_setresgid(gid_t
, gid_t
, gid_t
);
82 extern asmlinkage
long sys_setfsuid(uid_t
);
83 extern asmlinkage
long sys_setfsgid(gid_t
);
85 /* For this source file, we want overflow handling. */
95 #undef SET_OLDSTAT_UID
96 #undef SET_OLDSTAT_GID
100 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
101 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
102 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
103 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
104 #define SET_UID16(var, uid) var = high2lowuid(uid)
105 #define SET_GID16(var, gid) var = high2lowgid(gid)
106 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
107 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
108 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
109 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
110 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
111 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
113 asmlinkage
long sys32_chown16(const char * filename
, u16 user
, u16 group
)
115 return sys_chown(filename
, low2highuid(user
), low2highgid(group
));
118 asmlinkage
long sys32_lchown16(const char * filename
, u16 user
, u16 group
)
120 return sys_lchown(filename
, low2highuid(user
), low2highgid(group
));
123 asmlinkage
long sys32_fchown16(unsigned int fd
, u16 user
, u16 group
)
125 return sys_fchown(fd
, low2highuid(user
), low2highgid(group
));
128 asmlinkage
long sys32_setregid16(u16 rgid
, u16 egid
)
130 return sys_setregid(low2highgid(rgid
), low2highgid(egid
));
133 asmlinkage
long sys32_setgid16(u16 gid
)
135 return sys_setgid((gid_t
)gid
);
138 asmlinkage
long sys32_setreuid16(u16 ruid
, u16 euid
)
140 return sys_setreuid(low2highuid(ruid
), low2highuid(euid
));
143 asmlinkage
long sys32_setuid16(u16 uid
)
145 return sys_setuid((uid_t
)uid
);
148 asmlinkage
long sys32_setresuid16(u16 ruid
, u16 euid
, u16 suid
)
150 return sys_setresuid(low2highuid(ruid
), low2highuid(euid
),
154 asmlinkage
long sys32_getresuid16(u16
*ruid
, u16
*euid
, u16
*suid
)
158 if (!(retval
= put_user(high2lowuid(current
->uid
), ruid
)) &&
159 !(retval
= put_user(high2lowuid(current
->euid
), euid
)))
160 retval
= put_user(high2lowuid(current
->suid
), suid
);
165 asmlinkage
long sys32_setresgid16(u16 rgid
, u16 egid
, u16 sgid
)
167 return sys_setresgid(low2highgid(rgid
), low2highgid(egid
),
171 asmlinkage
long sys32_getresgid16(u16
*rgid
, u16
*egid
, u16
*sgid
)
175 if (!(retval
= put_user(high2lowgid(current
->gid
), rgid
)) &&
176 !(retval
= put_user(high2lowgid(current
->egid
), egid
)))
177 retval
= put_user(high2lowgid(current
->sgid
), sgid
);
182 asmlinkage
long sys32_setfsuid16(u16 uid
)
184 return sys_setfsuid((uid_t
)uid
);
187 asmlinkage
long sys32_setfsgid16(u16 gid
)
189 return sys_setfsgid((gid_t
)gid
);
192 asmlinkage
long sys32_getgroups16(int gidsetsize
, u16
*grouplist
)
199 i
= current
->ngroups
;
204 groups
[j
] = current
->groups
[j
];
205 if (copy_to_user(grouplist
, groups
, sizeof(u16
)*i
))
211 asmlinkage
long sys32_setgroups16(int gidsetsize
, u16
*grouplist
)
216 if (!capable(CAP_SETGID
))
218 if ((unsigned) gidsetsize
> NGROUPS
)
220 if (copy_from_user(groups
, grouplist
, gidsetsize
* sizeof(u16
)))
222 for (i
= 0 ; i
< gidsetsize
; i
++)
223 current
->groups
[i
] = (gid_t
)groups
[i
];
224 current
->ngroups
= gidsetsize
;
228 asmlinkage
long sys32_getuid16(void)
230 return high2lowuid(current
->uid
);
233 asmlinkage
long sys32_geteuid16(void)
235 return high2lowuid(current
->euid
);
238 asmlinkage
long sys32_getgid16(void)
240 return high2lowgid(current
->gid
);
243 asmlinkage
long sys32_getegid16(void)
245 return high2lowgid(current
->egid
);
248 /* 32-bit timeval and related flotsam. */
250 static inline long get_tv32(struct timeval
*o
, struct compat_timeval
*i
)
252 return (!access_ok(VERIFY_READ
, tv32
, sizeof(*tv32
)) ||
253 (__get_user(o
->tv_sec
, &i
->tv_sec
) |
254 __get_user(o
->tv_usec
, &i
->tv_usec
)));
257 static inline long put_tv32(struct compat_timeval
*o
, struct timeval
*i
)
259 return (!access_ok(VERIFY_WRITE
, o
, sizeof(*o
)) ||
260 (__put_user(i
->tv_sec
, &o
->tv_sec
) |
261 __put_user(i
->tv_usec
, &o
->tv_usec
)));
264 struct msgbuf32
{ s32 mtype
; char mtext
[1]; };
266 struct ipc64_perm_ds32
269 __kernel_uid32_t uid
;
270 __kernel_gid32_t gid
;
271 __kernel_uid32_t cuid
;
272 __kernel_gid32_t cgid
;
274 unsigned short __pad1
;
276 unsigned short __pad2
;
277 unsigned int __unused1
;
278 unsigned int __unused2
;
293 struct ipc_perm32 sem_perm
; /* permissions .. see ipc.h */
294 compat_time_t sem_otime
; /* last semop time */
295 compat_time_t sem_ctime
; /* last change time */
296 u32 sem_base
; /* ptr to first semaphore in array */
297 u32 sem_pending
; /* pending operations to be processed */
298 u32 sem_pending_last
; /* last pending operation */
299 u32 undo
; /* undo requests on this array */
300 unsigned short sem_nsems
; /* no. of semaphores in array */
303 struct semid64_ds32
{
304 struct ipc64_perm_ds32 sem_perm
;
306 compat_time_t sem_otime
;
308 compat_time_t sem_ctime
;
316 struct ipc_perm32 msg_perm
;
319 compat_time_t msg_stime
;
320 compat_time_t msg_rtime
;
321 compat_time_t msg_ctime
;
324 unsigned short msg_cbytes
;
325 unsigned short msg_qnum
;
326 unsigned short msg_qbytes
;
327 compat_ipc_pid_t msg_lspid
;
328 compat_ipc_pid_t msg_lrpid
;
331 struct msqid64_ds32
{
332 struct ipc64_perm_ds32 msg_perm
;
334 compat_time_t msg_stime
;
336 compat_time_t msg_rtime
;
338 compat_time_t msg_ctime
;
339 unsigned int msg_cbytes
;
340 unsigned int msg_qnum
;
341 unsigned int msg_qbytes
;
342 compat_pid_t msg_lspid
;
343 compat_pid_t msg_lrpid
;
344 unsigned int __unused1
;
345 unsigned int __unused2
;
350 struct ipc_perm32 shm_perm
;
352 compat_time_t shm_atime
;
353 compat_time_t shm_dtime
;
354 compat_time_t shm_ctime
;
355 compat_ipc_pid_t shm_cpid
;
356 compat_ipc_pid_t shm_lpid
;
357 unsigned short shm_nattch
;
360 struct shmid64_ds32
{
361 struct ipc64_perm_ds32 shm_perm
;
362 compat_size_t shm_segsz
;
363 compat_time_t shm_atime
;
364 unsigned int __unused1
;
365 compat_time_t shm_dtime
;
366 unsigned int __unused2
;
367 compat_time_t shm_ctime
;
368 unsigned int __unused3
;
369 compat_pid_t shm_cpid
;
370 compat_pid_t shm_lpid
;
371 unsigned int shm_nattch
;
372 unsigned int __unused4
;
373 unsigned int __unused5
;
376 extern int sem_ctls
[];
377 #define sc_semopm (sem_ctls[2])
378 #define SEMOPM_FAST 64 /* ~ 372 bytes on stack */
381 do_sys32_semtimedop (int semid
, struct sembuf
*tsops
, int nsops
,
382 struct compat_timespec
*timeout32
)
384 struct sembuf
*sops
, fast_sops
[SEMOPM_FAST
];
389 /* parameter checking precedence should mirror sys_semtimedop() */
390 if (nsops
< 1 || semid
< 0)
392 if (nsops
> sc_semopm
)
394 if (nsops
<= SEMOPM_FAST
)
397 sops
= kmalloc(nsops
* sizeof(*sops
), GFP_KERNEL
);
401 if (copy_from_user(sops
, tsops
, nsops
* sizeof(*tsops
)) ||
402 get_compat_timespec(&t
, timeout32
))
407 ret
= sys_semtimedop(semid
, sops
, nsops
, &t
);
410 if (sops
!= fast_sops
)
415 #define IPCOP_MASK(__x) (1UL << (__x))
416 static int do_sys32_semctl(int first
, int second
, int third
, void *uptr
)
425 if (get_user (pad
, (u32
*)uptr
))
428 fourth
.val
= (int)pad
;
430 fourth
.__pad
= (void *)A(pad
);
431 if (IPCOP_MASK (third
) &
432 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SEM_INFO
) | IPCOP_MASK (GETVAL
) |
433 IPCOP_MASK (GETPID
) | IPCOP_MASK (GETNCNT
) | IPCOP_MASK (GETZCNT
) |
434 IPCOP_MASK (GETALL
) | IPCOP_MASK (SETALL
) | IPCOP_MASK (IPC_RMID
))) {
435 err
= sys_semctl (first
, second
, third
, fourth
);
436 } else if (third
& IPC_64
) {
438 struct semid64_ds32
*usp
= (struct semid64_ds32
*)A(pad
);
440 int need_back_translation
;
442 if (third
== (IPC_SET
|IPC_64
)) {
443 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
444 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
445 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
450 need_back_translation
=
451 (IPCOP_MASK (third
) &
452 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
453 if (need_back_translation
)
457 err
= sys_semctl (first
, second
, third
, fourth
);
459 if (need_back_translation
) {
460 int err2
= put_user (s
.sem_perm
.key
, &usp
->sem_perm
.key
);
461 err2
|= __put_user (high2lowuid(s
.sem_perm
.uid
), &usp
->sem_perm
.uid
);
462 err2
|= __put_user (high2lowgid(s
.sem_perm
.gid
), &usp
->sem_perm
.gid
);
463 err2
|= __put_user (high2lowuid(s
.sem_perm
.cuid
), &usp
->sem_perm
.cuid
);
464 err2
|= __put_user (high2lowgid(s
.sem_perm
.cgid
), &usp
->sem_perm
.cgid
);
465 err2
|= __put_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
466 err2
|= __put_user (s
.sem_perm
.seq
, &usp
->sem_perm
.seq
);
467 err2
|= __put_user (s
.sem_otime
, &usp
->sem_otime
);
468 err2
|= __put_user (s
.sem_ctime
, &usp
->sem_ctime
);
469 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
470 if (err2
) err
= -EFAULT
;
474 struct semid_ds32
*usp
= (struct semid_ds32
*)A(pad
);
476 int need_back_translation
;
478 if (third
== IPC_SET
) {
479 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
480 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
481 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
486 need_back_translation
=
487 (IPCOP_MASK (third
) &
488 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
489 if (need_back_translation
)
493 err
= sys_semctl (first
, second
, third
, fourth
);
495 if (need_back_translation
) {
496 int err2
= put_user (s
.sem_perm
.key
, &usp
->sem_perm
.key
);
497 err2
|= __put_user (high2lowuid(s
.sem_perm
.uid
), &usp
->sem_perm
.uid
);
498 err2
|= __put_user (high2lowgid(s
.sem_perm
.gid
), &usp
->sem_perm
.gid
);
499 err2
|= __put_user (high2lowuid(s
.sem_perm
.cuid
), &usp
->sem_perm
.cuid
);
500 err2
|= __put_user (high2lowgid(s
.sem_perm
.cgid
), &usp
->sem_perm
.cgid
);
501 err2
|= __put_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
502 err2
|= __put_user (s
.sem_perm
.seq
, &usp
->sem_perm
.seq
);
503 err2
|= __put_user (s
.sem_otime
, &usp
->sem_otime
);
504 err2
|= __put_user (s
.sem_ctime
, &usp
->sem_ctime
);
505 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
506 if (err2
) err
= -EFAULT
;
513 static int do_sys32_msgsnd (int first
, int second
, int third
, void *uptr
)
515 struct msgbuf
*p
= kmalloc (second
+ sizeof (struct msgbuf
), GFP_USER
);
516 struct msgbuf32
*up
= (struct msgbuf32
*)uptr
;
524 if (second
> MSGMAX
|| first
< 0 || second
< 0)
530 if (get_user (p
->mtype
, &up
->mtype
) ||
531 __copy_from_user (p
->mtext
, &up
->mtext
, second
))
535 err
= sys_msgsnd (first
, p
, second
, third
);
542 static int do_sys32_msgrcv (int first
, int second
, int msgtyp
, int third
,
543 int version
, void *uptr
)
550 if (first
< 0 || second
< 0)
554 struct ipc_kludge_32
*uipck
= (struct ipc_kludge_32
*)uptr
;
555 struct ipc_kludge_32 ipck
;
561 if (copy_from_user (&ipck
, uipck
, sizeof (struct ipc_kludge_32
)))
563 uptr
= (void *)A(ipck
.msgp
);
564 msgtyp
= ipck
.msgtyp
;
567 p
= kmalloc (second
+ sizeof (struct msgbuf
), GFP_USER
);
572 err
= sys_msgrcv (first
, p
, second
, msgtyp
, third
);
576 up
= (struct msgbuf32
*)uptr
;
577 if (put_user (p
->mtype
, &up
->mtype
) ||
578 __copy_to_user (&up
->mtext
, p
->mtext
, err
))
586 static int do_sys32_msgctl (int first
, int second
, void *uptr
)
590 if (IPCOP_MASK (second
) &
591 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (MSG_INFO
) |
592 IPCOP_MASK (IPC_RMID
))) {
593 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)uptr
);
594 } else if (second
& IPC_64
) {
596 struct msqid64_ds32
*up
= (struct msqid64_ds32
*)uptr
;
599 if (second
== (IPC_SET
|IPC_64
)) {
600 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
601 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
602 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
603 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
609 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)&m
);
611 if (IPCOP_MASK (second
) &
612 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
613 int err2
= put_user (m
.msg_perm
.key
, &up
->msg_perm
.key
);
614 err2
|= __put_user (high2lowuid(m
.msg_perm
.uid
), &up
->msg_perm
.uid
);
615 err2
|= __put_user (high2lowgid(m
.msg_perm
.gid
), &up
->msg_perm
.gid
);
616 err2
|= __put_user (high2lowuid(m
.msg_perm
.cuid
), &up
->msg_perm
.cuid
);
617 err2
|= __put_user (high2lowgid(m
.msg_perm
.cgid
), &up
->msg_perm
.cgid
);
618 err2
|= __put_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
619 err2
|= __put_user (m
.msg_perm
.seq
, &up
->msg_perm
.seq
);
620 err2
|= __put_user (m
.msg_stime
, &up
->msg_stime
);
621 err2
|= __put_user (m
.msg_rtime
, &up
->msg_rtime
);
622 err2
|= __put_user (m
.msg_ctime
, &up
->msg_ctime
);
623 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
624 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
625 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
626 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
627 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
633 struct msqid_ds32
*up
= (struct msqid_ds32
*)uptr
;
636 if (second
== IPC_SET
) {
637 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
638 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
639 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
640 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
646 err
= sys_msgctl (first
, second
, &m
);
648 if (IPCOP_MASK (second
) &
649 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
650 int err2
= put_user (m
.msg_perm
.key
, &up
->msg_perm
.key
);
651 err2
|= __put_user (high2lowuid(m
.msg_perm
.uid
), &up
->msg_perm
.uid
);
652 err2
|= __put_user (high2lowgid(m
.msg_perm
.gid
), &up
->msg_perm
.gid
);
653 err2
|= __put_user (high2lowuid(m
.msg_perm
.cuid
), &up
->msg_perm
.cuid
);
654 err2
|= __put_user (high2lowgid(m
.msg_perm
.cgid
), &up
->msg_perm
.cgid
);
655 err2
|= __put_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
656 err2
|= __put_user (m
.msg_perm
.seq
, &up
->msg_perm
.seq
);
657 err2
|= __put_user (m
.msg_stime
, &up
->msg_stime
);
658 err2
|= __put_user (m
.msg_rtime
, &up
->msg_rtime
);
659 err2
|= __put_user (m
.msg_ctime
, &up
->msg_ctime
);
660 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
661 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
662 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
663 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
664 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
674 static int do_sys32_shmat (int first
, int second
, int third
, int version
, void *uptr
)
677 u32
*uaddr
= (u32
*)A((u32
)third
);
682 err
= sys_shmat (first
, uptr
, second
, &raddr
);
685 err
= put_user (raddr
, uaddr
);
690 static int do_sys32_shmctl (int first
, int second
, void *uptr
)
694 if (IPCOP_MASK (second
) &
695 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SHM_LOCK
) | IPCOP_MASK (SHM_UNLOCK
) |
696 IPCOP_MASK (IPC_RMID
))) {
697 if (second
== (IPC_INFO
|IPC_64
))
698 second
= IPC_INFO
; /* So that we don't have to translate it */
699 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)uptr
);
700 } else if ((second
& IPC_64
) && second
!= (SHM_INFO
|IPC_64
)) {
702 struct shmid64_ds32
*up
= (struct shmid64_ds32
*)uptr
;
705 if (second
== (IPC_SET
|IPC_64
)) {
706 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
707 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
708 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
714 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)&s
);
719 /* Mask it even in this case so it becomes a CSE. */
720 if (IPCOP_MASK (second
) &
721 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
722 int err2
= put_user (s
.shm_perm
.key
, &up
->shm_perm
.key
);
723 err2
|= __put_user (high2lowuid(s
.shm_perm
.uid
), &up
->shm_perm
.uid
);
724 err2
|= __put_user (high2lowgid(s
.shm_perm
.gid
), &up
->shm_perm
.gid
);
725 err2
|= __put_user (high2lowuid(s
.shm_perm
.cuid
), &up
->shm_perm
.cuid
);
726 err2
|= __put_user (high2lowgid(s
.shm_perm
.cgid
), &up
->shm_perm
.cgid
);
727 err2
|= __put_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
728 err2
|= __put_user (s
.shm_perm
.seq
, &up
->shm_perm
.seq
);
729 err2
|= __put_user (s
.shm_atime
, &up
->shm_atime
);
730 err2
|= __put_user (s
.shm_dtime
, &up
->shm_dtime
);
731 err2
|= __put_user (s
.shm_ctime
, &up
->shm_ctime
);
732 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
733 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
734 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
735 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
741 struct shmid_ds32
*up
= (struct shmid_ds32
*)uptr
;
745 if (second
== IPC_SET
) {
746 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
747 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
748 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
754 err
= sys_shmctl (first
, second
, &s
);
759 /* Mask it even in this case so it becomes a CSE. */
760 if (second
== SHM_INFO
) {
763 u32 shm_tot
, shm_rss
, shm_swp
;
764 u32 swap_attempts
, swap_successes
;
765 } *uip
= (struct shm_info32
*)uptr
;
766 struct shm_info
*kp
= (struct shm_info
*)&s
;
767 int err2
= put_user (kp
->used_ids
, &uip
->used_ids
);
768 err2
|= __put_user (kp
->shm_tot
, &uip
->shm_tot
);
769 err2
|= __put_user (kp
->shm_rss
, &uip
->shm_rss
);
770 err2
|= __put_user (kp
->shm_swp
, &uip
->shm_swp
);
771 err2
|= __put_user (kp
->swap_attempts
, &uip
->swap_attempts
);
772 err2
|= __put_user (kp
->swap_successes
, &uip
->swap_successes
);
775 } else if (IPCOP_MASK (second
) &
776 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
777 int err2
= put_user (s
.shm_perm
.key
, &up
->shm_perm
.key
);
778 err2
|= __put_user (high2lowuid(s
.shm_perm
.uid
), &up
->shm_perm
.uid
);
779 err2
|= __put_user (high2lowgid(s
.shm_perm
.gid
), &up
->shm_perm
.gid
);
780 err2
|= __put_user (high2lowuid(s
.shm_perm
.cuid
), &up
->shm_perm
.cuid
);
781 err2
|= __put_user (high2lowgid(s
.shm_perm
.cgid
), &up
->shm_perm
.cgid
);
782 err2
|= __put_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
783 err2
|= __put_user (s
.shm_perm
.seq
, &up
->shm_perm
.seq
);
784 err2
|= __put_user (s
.shm_atime
, &up
->shm_atime
);
785 err2
|= __put_user (s
.shm_dtime
, &up
->shm_dtime
);
786 err2
|= __put_user (s
.shm_ctime
, &up
->shm_ctime
);
787 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
788 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
789 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
790 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
800 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.
802 * This is really horribly ugly.
804 asmlinkage
int sys32_ipc (u32 call
, int first
, int second
, int third
, u32 ptr
)
808 version
= call
>> 16; /* hack for backward compatibility */
814 if (call
<= SEMTIMEDOP
)
818 err
= do_sys32_semtimedop(first
,
819 (struct sembuf
*)AA(ptr
),
821 (struct compat_timespec
*)
825 /* else fall through for normal semop() */
827 /* struct sembuf is the same on 32 and 64bit :)) */
828 err
= sys_semtimedop (first
, (struct sembuf
*)AA(ptr
),
832 err
= sys_semget (first
, second
, third
);
835 err
= do_sys32_semctl (first
, second
, third
, (void *)AA(ptr
));
844 err
= do_sys32_msgsnd (first
, second
, third
, (void *)AA(ptr
));
847 err
= do_sys32_msgrcv (first
, second
, 0, third
,
848 version
, (void *)AA(ptr
));
851 err
= sys_msgget ((key_t
) first
, second
);
854 err
= do_sys32_msgctl (first
, second
, (void *)AA(ptr
));
863 err
= do_sys32_shmat (first
, second
, third
,
864 version
, (void *)AA(ptr
));
867 err
= sys_shmdt ((char *)AA(ptr
));
870 err
= sys_shmget (first
, second
, third
);
873 err
= do_sys32_shmctl (first
, second
, (void *)AA(ptr
));
886 extern asmlinkage
long sys_truncate(const char * path
, unsigned long length
);
887 extern asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
);
889 asmlinkage
int sys32_truncate64(const char * path
, unsigned long high
, unsigned long low
)
894 return sys_truncate(path
, (high
<< 32) | low
);
897 asmlinkage
int sys32_ftruncate64(unsigned int fd
, unsigned long high
, unsigned long low
)
902 return sys_ftruncate(fd
, (high
<< 32) | low
);
905 typedef ssize_t (*io_fn_t
)(struct file
*, char *, size_t, loff_t
*);
906 typedef ssize_t (*iov_fn_t
)(struct file
*, const struct iovec
*, unsigned long, loff_t
*);
908 static long do_readv_writev32(int type
, struct file
*file
,
909 const struct compat_iovec
*vector
, u32 count
)
911 unsigned long tot_len
;
912 struct iovec iovstack
[UIO_FASTIOV
];
913 struct iovec
*iov
=iovstack
, *ivp
;
919 /* First get the "struct iovec" from user memory and
920 * verify all the pointers
924 if (verify_area(VERIFY_READ
, vector
, sizeof(struct compat_iovec
)*count
))
926 if (count
> UIO_MAXIOV
)
928 if (count
> UIO_FASTIOV
) {
929 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
941 __get_user(len
, &vector
->iov_len
);
942 __get_user(buf
, &vector
->iov_base
);
944 ivp
->iov_base
= (void *)A(buf
);
945 ivp
->iov_len
= (__kernel_size_t
) len
;
951 inode
= file
->f_dentry
->d_inode
;
952 /* VERIFY_WRITE actually means a read, as we write to user space */
953 retval
= locks_verify_area((type
== VERIFY_WRITE
954 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
955 inode
, file
, file
->f_pos
, tot_len
);
959 /* VERIFY_WRITE actually means a read, as we write to user space */
960 fnv
= (type
== VERIFY_WRITE
? file
->f_op
->readv
: file
->f_op
->writev
);
962 retval
= fnv(file
, iov
, count
, &file
->f_pos
);
966 fn
= (type
== VERIFY_WRITE
? file
->f_op
->read
:
967 (io_fn_t
) file
->f_op
->write
);
974 base
= ivp
->iov_base
;
978 nr
= fn(file
, base
, len
, &file
->f_pos
);
995 asmlinkage
long sys32_readv(int fd
, struct compat_iovec
*vector
, u32 count
)
1004 if (file
->f_op
&& (file
->f_mode
& FMODE_READ
) &&
1005 (file
->f_op
->readv
|| file
->f_op
->read
))
1006 ret
= do_readv_writev32(VERIFY_WRITE
, file
, vector
, count
);
1013 asmlinkage
long sys32_writev(int fd
, struct compat_iovec
*vector
, u32 count
)
1021 if (file
->f_op
&& (file
->f_mode
& FMODE_WRITE
) &&
1022 (file
->f_op
->writev
|| file
->f_op
->write
))
1023 ret
= do_readv_writev32(VERIFY_READ
, file
, vector
, count
);
1030 /* readdir & getdents */
1032 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1033 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1035 struct old_linux_dirent32
{
1038 unsigned short d_namlen
;
1042 struct readdir_callback32
{
1043 struct old_linux_dirent32
* dirent
;
1047 static int fillonedir(void * __buf
, const char * name
, int namlen
,
1048 loff_t offset
, ino_t ino
, unsigned int d_type
)
1050 struct readdir_callback32
* buf
= (struct readdir_callback32
*) __buf
;
1051 struct old_linux_dirent32
* dirent
;
1056 dirent
= buf
->dirent
;
1057 put_user(ino
, &dirent
->d_ino
);
1058 put_user(offset
, &dirent
->d_offset
);
1059 put_user(namlen
, &dirent
->d_namlen
);
1060 copy_to_user(dirent
->d_name
, name
, namlen
);
1061 put_user(0, dirent
->d_name
+ namlen
);
1065 asmlinkage
int old32_readdir(unsigned int fd
, struct old_linux_dirent32
*dirent
, unsigned int count
)
1069 struct readdir_callback32 buf
;
1076 buf
.dirent
= dirent
;
1078 error
= vfs_readdir(file
, fillonedir
, &buf
);
1089 struct linux_dirent32
{
1092 unsigned short d_reclen
;
1096 struct getdents_callback32
{
1097 struct linux_dirent32
* current_dir
;
1098 struct linux_dirent32
* previous
;
1103 static int filldir(void * __buf
, const char * name
, int namlen
, loff_t offset
, ino_t ino
,
1104 unsigned int d_type
)
1106 struct linux_dirent32
* dirent
;
1107 struct getdents_callback32
* buf
= (struct getdents_callback32
*) __buf
;
1108 int reclen
= ROUND_UP(NAME_OFFSET(dirent
) + namlen
+ 1);
1110 buf
->error
= -EINVAL
; /* only used if we fail.. */
1111 if (reclen
> buf
->count
)
1113 dirent
= buf
->previous
;
1115 put_user(offset
, &dirent
->d_off
);
1116 dirent
= buf
->current_dir
;
1117 buf
->previous
= dirent
;
1118 put_user(ino
, &dirent
->d_ino
);
1119 put_user(reclen
, &dirent
->d_reclen
);
1120 copy_to_user(dirent
->d_name
, name
, namlen
);
1121 put_user(0, dirent
->d_name
+ namlen
);
1122 ((char *) dirent
) += reclen
;
1123 buf
->current_dir
= dirent
;
1124 buf
->count
-= reclen
;
1128 asmlinkage
int sys32_getdents(unsigned int fd
, struct linux_dirent32
*dirent
, unsigned int count
)
1131 struct linux_dirent32
* lastdirent
;
1132 struct getdents_callback32 buf
;
1139 buf
.current_dir
= dirent
;
1140 buf
.previous
= NULL
;
1144 error
= vfs_readdir(file
, filldir
, &buf
);
1147 lastdirent
= buf
.previous
;
1150 put_user(file
->f_pos
, &lastdirent
->d_off
);
1151 error
= count
- buf
.count
;
1159 /* end of readdir & getdents */
1162 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1163 * 64-bit unsigned longs.
1167 get_fd_set32(unsigned long n
, unsigned long *fdset
, u32
*ufdset
)
1172 if (verify_area(VERIFY_WRITE
, ufdset
, n
*sizeof(u32
)))
1179 __get_user(l
, ufdset
);
1180 __get_user(h
, ufdset
+1);
1182 *fdset
++ = h
<< 32 | l
;
1186 __get_user(*fdset
, ufdset
);
1188 /* Tricky, must clear full unsigned long in the
1189 * kernel fdset at the end, this makes sure that
1192 memset(fdset
, 0, ((n
+ 1) & ~1)*sizeof(u32
));
1198 set_fd_set32(unsigned long n
, u32
*ufdset
, unsigned long *fdset
)
1211 __put_user(l
, ufdset
);
1212 __put_user(h
, ufdset
+1);
1217 __put_user(*fdset
, ufdset
);
1220 #define MAX_SELECT_SECONDS \
1221 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1223 asmlinkage
int sys32_select(int n
, u32
*inp
, u32
*outp
, u32
*exp
, u32 tvp_x
)
1226 struct compat_timeval
*tvp
= (struct compat_timeval
*)AA(tvp_x
);
1232 timeout
= MAX_SCHEDULE_TIMEOUT
;
1236 if ((ret
= verify_area(VERIFY_READ
, tvp
, sizeof(*tvp
)))
1237 || (ret
= __get_user(sec
, &tvp
->tv_sec
))
1238 || (ret
= __get_user(usec
, &tvp
->tv_usec
)))
1242 if(sec
< 0 || usec
< 0)
1245 if ((unsigned long) sec
< MAX_SELECT_SECONDS
) {
1246 timeout
= (usec
+ 1000000/HZ
- 1) / (1000000/HZ
);
1247 timeout
+= sec
* (unsigned long) HZ
;
1254 if (n
> current
->files
->max_fdset
)
1255 n
= current
->files
->max_fdset
;
1258 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1259 * since we used fdset we need to allocate memory in units of
1263 size
= FDS_BYTES(n
);
1264 bits
= kmalloc(6 * size
, GFP_KERNEL
);
1267 fds
.in
= (unsigned long *) bits
;
1268 fds
.out
= (unsigned long *) (bits
+ size
);
1269 fds
.ex
= (unsigned long *) (bits
+ 2*size
);
1270 fds
.res_in
= (unsigned long *) (bits
+ 3*size
);
1271 fds
.res_out
= (unsigned long *) (bits
+ 4*size
);
1272 fds
.res_ex
= (unsigned long *) (bits
+ 5*size
);
1274 nn
= (n
+ 8*sizeof(u32
) - 1) / (8*sizeof(u32
));
1275 if ((ret
= get_fd_set32(nn
, fds
.in
, inp
)) ||
1276 (ret
= get_fd_set32(nn
, fds
.out
, outp
)) ||
1277 (ret
= get_fd_set32(nn
, fds
.ex
, exp
)))
1279 zero_fd_set(n
, fds
.res_in
);
1280 zero_fd_set(n
, fds
.res_out
);
1281 zero_fd_set(n
, fds
.res_ex
);
1283 ret
= do_select(n
, &fds
, &timeout
);
1285 if (tvp
&& !(current
->personality
& STICKY_TIMEOUTS
)) {
1286 int sec
= 0, usec
= 0;
1289 usec
= timeout
% HZ
;
1290 usec
*= (1000000/HZ
);
1292 put_user(sec
, &tvp
->tv_sec
);
1293 put_user(usec
, &tvp
->tv_usec
);
1299 ret
= -ERESTARTNOHAND
;
1300 if (signal_pending(current
))
1305 set_fd_set32(nn
, inp
, fds
.res_in
);
1306 set_fd_set32(nn
, outp
, fds
.res_out
);
1307 set_fd_set32(nn
, exp
, fds
.res_ex
);
1315 int cp_compat_stat(struct kstat
*stat
, struct compat_stat
*statbuf
)
1319 err
= put_user(stat
->dev
, &statbuf
->st_dev
);
1320 err
|= put_user(stat
->ino
, &statbuf
->st_ino
);
1321 err
|= put_user(stat
->mode
, &statbuf
->st_mode
);
1322 err
|= put_user(stat
->nlink
, &statbuf
->st_nlink
);
1323 err
|= put_user(high2lowuid(stat
->uid
), &statbuf
->st_uid
);
1324 err
|= put_user(high2lowgid(stat
->gid
), &statbuf
->st_gid
);
1325 err
|= put_user(stat
->rdev
, &statbuf
->st_rdev
);
1326 err
|= put_user(stat
->size
, &statbuf
->st_size
);
1327 err
|= put_user(stat
->atime
.tv_sec
, &statbuf
->st_atime
);
1328 err
|= put_user(stat
->atime
.tv_nsec
, &statbuf
->st_atime_nsec
);
1329 err
|= put_user(stat
->mtime
.tv_sec
, &statbuf
->st_mtime
);
1330 err
|= put_user(stat
->mtime
.tv_nsec
, &statbuf
->st_mtime_nsec
);
1331 err
|= put_user(stat
->ctime
.tv_sec
, &statbuf
->st_ctime
);
1332 err
|= put_user(stat
->ctime
.tv_nsec
, &statbuf
->st_ctime_nsec
);
1333 err
|= put_user(stat
->blksize
, &statbuf
->st_blksize
);
1334 err
|= put_user(stat
->blocks
, &statbuf
->st_blocks
);
1336 err |= put_user(0, &statbuf->__unused4[0]);
1337 err |= put_user(0, &statbuf->__unused4[1]);
1342 extern asmlinkage
int sys_sysfs(int option
, unsigned long arg1
, unsigned long arg2
);
1344 asmlinkage
int sys32_sysfs(int option
, u32 arg1
, u32 arg2
)
1346 return sys_sysfs(option
, arg1
, arg2
);
1349 struct ncp_mount_data32
{
1351 unsigned int ncp_fd
;
1352 compat_uid_t mounted_uid
;
1353 compat_pid_t wdog_pid
;
1354 unsigned char mounted_vol
[NCP_VOLNAME_LEN
+ 1];
1355 unsigned int time_out
;
1356 unsigned int retry_count
;
1360 compat_mode_t file_mode
;
1361 compat_mode_t dir_mode
;
1364 static void *do_ncp_super_data_conv(void *raw_data
)
1366 struct ncp_mount_data
*n
= (struct ncp_mount_data
*)raw_data
;
1367 struct ncp_mount_data32
*n32
= (struct ncp_mount_data32
*)raw_data
;
1369 n
->dir_mode
= n32
->dir_mode
;
1370 n
->file_mode
= n32
->file_mode
;
1371 n
->gid
= low2highgid(n32
->gid
);
1372 n
->uid
= low2highuid(n32
->uid
);
1373 memmove (n
->mounted_vol
, n32
->mounted_vol
, (sizeof (n32
->mounted_vol
) + 3 * sizeof (unsigned int)));
1374 n
->wdog_pid
= n32
->wdog_pid
;
1375 n
->mounted_uid
= low2highuid(n32
->mounted_uid
);
1379 struct smb_mount_data32
{
1381 compat_uid_t mounted_uid
;
1384 compat_mode_t file_mode
;
1385 compat_mode_t dir_mode
;
1388 static void *do_smb_super_data_conv(void *raw_data
)
1390 struct smb_mount_data
*s
= (struct smb_mount_data
*)raw_data
;
1391 struct smb_mount_data32
*s32
= (struct smb_mount_data32
*)raw_data
;
1393 if (s32
->version
!= SMB_MOUNT_OLDVERSION
)
1395 s
->version
= s32
->version
;
1396 s
->mounted_uid
= low2highuid(s32
->mounted_uid
);
1397 s
->uid
= low2highuid(s32
->uid
);
1398 s
->gid
= low2highgid(s32
->gid
);
1399 s
->file_mode
= s32
->file_mode
;
1400 s
->dir_mode
= s32
->dir_mode
;
1405 static int copy_mount_stuff_to_kernel(const void *user
, unsigned long *kernel
)
1409 struct vm_area_struct
*vma
;
1414 vma
= find_vma(current
->mm
, (unsigned long)user
);
1415 if(!vma
|| (unsigned long)user
< vma
->vm_start
)
1417 if(!(vma
->vm_flags
& VM_READ
))
1419 i
= vma
->vm_end
- (unsigned long) user
;
1420 if(PAGE_SIZE
<= (unsigned long) i
)
1422 if(!(page
= __get_free_page(GFP_KERNEL
)))
1424 if(copy_from_user((void *) page
, user
, i
)) {
1432 #define SMBFS_NAME "smbfs"
1433 #define NCPFS_NAME "ncpfs"
1435 asmlinkage
int sys32_mount(char *dev_name
, char *dir_name
, char *type
, unsigned long new_flags
, u32 data
)
1437 unsigned long type_page
= 0;
1438 unsigned long data_page
= 0;
1439 unsigned long dev_page
= 0;
1440 unsigned long dir_page
= 0;
1441 int err
, is_smb
, is_ncp
;
1443 is_smb
= is_ncp
= 0;
1445 err
= copy_mount_stuff_to_kernel((const void *)type
, &type_page
);
1454 is_smb
= !strcmp((char *)type_page
, SMBFS_NAME
);
1455 is_ncp
= !strcmp((char *)type_page
, NCPFS_NAME
);
1457 err
= copy_mount_stuff_to_kernel((const void *)AA(data
), &data_page
);
1461 err
= copy_mount_stuff_to_kernel(dev_name
, &dev_page
);
1465 err
= copy_mount_stuff_to_kernel(dir_name
, &dir_page
);
1469 if (!is_smb
&& !is_ncp
) {
1471 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1472 (char*)type_page
, new_flags
, (char*)data_page
);
1476 do_ncp_super_data_conv((void *)data_page
);
1478 do_smb_super_data_conv((void *)data_page
);
1481 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1482 (char*)type_page
, new_flags
, (char*)data_page
);
1485 free_page(dir_page
);
1488 free_page(dev_page
);
1491 free_page(data_page
);
1494 free_page(type_page
);
1501 struct compat_timeval ru_utime
;
1502 struct compat_timeval ru_stime
;
1519 static int put_rusage (struct rusage32
*ru
, struct rusage
*r
)
1523 err
= put_user (r
->ru_utime
.tv_sec
, &ru
->ru_utime
.tv_sec
);
1524 err
|= __put_user (r
->ru_utime
.tv_usec
, &ru
->ru_utime
.tv_usec
);
1525 err
|= __put_user (r
->ru_stime
.tv_sec
, &ru
->ru_stime
.tv_sec
);
1526 err
|= __put_user (r
->ru_stime
.tv_usec
, &ru
->ru_stime
.tv_usec
);
1527 err
|= __put_user (r
->ru_maxrss
, &ru
->ru_maxrss
);
1528 err
|= __put_user (r
->ru_ixrss
, &ru
->ru_ixrss
);
1529 err
|= __put_user (r
->ru_idrss
, &ru
->ru_idrss
);
1530 err
|= __put_user (r
->ru_isrss
, &ru
->ru_isrss
);
1531 err
|= __put_user (r
->ru_minflt
, &ru
->ru_minflt
);
1532 err
|= __put_user (r
->ru_majflt
, &ru
->ru_majflt
);
1533 err
|= __put_user (r
->ru_nswap
, &ru
->ru_nswap
);
1534 err
|= __put_user (r
->ru_inblock
, &ru
->ru_inblock
);
1535 err
|= __put_user (r
->ru_oublock
, &ru
->ru_oublock
);
1536 err
|= __put_user (r
->ru_msgsnd
, &ru
->ru_msgsnd
);
1537 err
|= __put_user (r
->ru_msgrcv
, &ru
->ru_msgrcv
);
1538 err
|= __put_user (r
->ru_nsignals
, &ru
->ru_nsignals
);
1539 err
|= __put_user (r
->ru_nvcsw
, &ru
->ru_nvcsw
);
1540 err
|= __put_user (r
->ru_nivcsw
, &ru
->ru_nivcsw
);
1553 unsigned short procs
;
1557 extern asmlinkage
int sys_sysinfo(struct sysinfo
*info
);
1559 asmlinkage
int sys32_sysinfo(struct sysinfo32
*info
)
1563 mm_segment_t old_fs
= get_fs ();
1566 ret
= sys_sysinfo(&s
);
1568 err
= put_user (s
.uptime
, &info
->uptime
);
1569 err
|= __put_user (s
.loads
[0], &info
->loads
[0]);
1570 err
|= __put_user (s
.loads
[1], &info
->loads
[1]);
1571 err
|= __put_user (s
.loads
[2], &info
->loads
[2]);
1572 err
|= __put_user (s
.totalram
, &info
->totalram
);
1573 err
|= __put_user (s
.freeram
, &info
->freeram
);
1574 err
|= __put_user (s
.sharedram
, &info
->sharedram
);
1575 err
|= __put_user (s
.bufferram
, &info
->bufferram
);
1576 err
|= __put_user (s
.totalswap
, &info
->totalswap
);
1577 err
|= __put_user (s
.freeswap
, &info
->freeswap
);
1578 err
|= __put_user (s
.procs
, &info
->procs
);
1584 extern asmlinkage
int sys_sched_rr_get_interval(pid_t pid
, struct timespec
*interval
);
1586 asmlinkage
int sys32_sched_rr_get_interval(compat_pid_t pid
,
1587 struct compat_timespec
*interval
)
1591 mm_segment_t old_fs
= get_fs ();
1594 ret
= sys_sched_rr_get_interval(pid
, &t
);
1596 if (put_compat_timespec(&t
, interval
))
1601 extern asmlinkage
int sys_rt_sigprocmask(int how
, sigset_t
*set
, sigset_t
*oset
, size_t sigsetsize
);
1603 asmlinkage
int sys32_rt_sigprocmask(int how
, compat_sigset_t
*set
, compat_sigset_t
*oset
, compat_size_t sigsetsize
)
1606 compat_sigset_t s32
;
1608 mm_segment_t old_fs
= get_fs();
1611 if (copy_from_user (&s32
, set
, sizeof(compat_sigset_t
)))
1613 switch (_NSIG_WORDS
) {
1614 case 4: s
.sig
[3] = s32
.sig
[6] | (((long)s32
.sig
[7]) << 32);
1615 case 3: s
.sig
[2] = s32
.sig
[4] | (((long)s32
.sig
[5]) << 32);
1616 case 2: s
.sig
[1] = s32
.sig
[2] | (((long)s32
.sig
[3]) << 32);
1617 case 1: s
.sig
[0] = s32
.sig
[0] | (((long)s32
.sig
[1]) << 32);
1621 ret
= sys_rt_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
, sigsetsize
);
1623 if (ret
) return ret
;
1625 switch (_NSIG_WORDS
) {
1626 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
1627 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
1628 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
1629 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
1631 if (copy_to_user (oset
, &s32
, sizeof(compat_sigset_t
)))
1637 extern asmlinkage
int sys_rt_sigpending(sigset_t
*set
, size_t sigsetsize
);
1639 asmlinkage
int sys32_rt_sigpending(compat_sigset_t
*set
, compat_size_t sigsetsize
)
1642 compat_sigset_t s32
;
1644 mm_segment_t old_fs
= get_fs();
1647 ret
= sys_rt_sigpending(&s
, sigsetsize
);
1650 switch (_NSIG_WORDS
) {
1651 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
1652 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
1653 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
1654 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
1656 if (copy_to_user (set
, &s32
, sizeof(compat_sigset_t
)))
1663 copy_siginfo_to_user32(siginfo_t32
*to
, siginfo_t
*from
);
1666 sys32_rt_sigtimedwait(compat_sigset_t
*uthese
, siginfo_t32
*uinfo
,
1667 struct compat_timespec
*uts
, compat_size_t sigsetsize
)
1671 compat_sigset_t these32
;
1676 /* XXX: Don't preclude handling different sized sigset_t's. */
1677 if (sigsetsize
!= sizeof(sigset_t
))
1680 if (copy_from_user (&these32
, uthese
, sizeof(compat_sigset_t
)))
1683 switch (_NSIG_WORDS
) {
1684 case 4: these
.sig
[3] = these32
.sig
[6] | (((long)these32
.sig
[7]) << 32);
1685 case 3: these
.sig
[2] = these32
.sig
[4] | (((long)these32
.sig
[5]) << 32);
1686 case 2: these
.sig
[1] = these32
.sig
[2] | (((long)these32
.sig
[3]) << 32);
1687 case 1: these
.sig
[0] = these32
.sig
[0] | (((long)these32
.sig
[1]) << 32);
1691 * Invert the set of allowed signals to get those we
1694 sigdelsetmask(&these
, sigmask(SIGKILL
)|sigmask(SIGSTOP
));
1698 if (get_compat_timespec(&ts
, uts
))
1700 if (ts
.tv_nsec
>= 1000000000L || ts
.tv_nsec
< 0
1705 spin_lock_irq(¤t
->sighand
->siglock
);
1706 sig
= dequeue_signal(current
, &these
, &info
);
1708 /* None ready -- temporarily unblock those we're interested
1709 in so that we'll be awakened when they arrive. */
1710 current
->real_blocked
= current
->blocked
;
1711 sigandsets(¤t
->blocked
, ¤t
->blocked
, &these
);
1712 recalc_sigpending();
1713 spin_unlock_irq(¤t
->sighand
->siglock
);
1715 timeout
= MAX_SCHEDULE_TIMEOUT
;
1717 timeout
= (timespec_to_jiffies(&ts
)
1718 + (ts
.tv_sec
|| ts
.tv_nsec
));
1720 current
->state
= TASK_INTERRUPTIBLE
;
1721 timeout
= schedule_timeout(timeout
);
1723 spin_lock_irq(¤t
->sighand
->siglock
);
1724 sig
= dequeue_signal(current
, &these
, &info
);
1725 current
->blocked
= current
->real_blocked
;
1726 siginitset(¤t
->real_blocked
, 0);
1727 recalc_sigpending();
1729 spin_unlock_irq(¤t
->sighand
->siglock
);
1734 if (copy_siginfo_to_user32(uinfo
, &info
))
1746 extern asmlinkage
int
1747 sys_rt_sigqueueinfo(int pid
, int sig
, siginfo_t
*uinfo
);
1750 sys32_rt_sigqueueinfo(int pid
, int sig
, siginfo_t32
*uinfo
)
1754 mm_segment_t old_fs
= get_fs();
1756 if (copy_from_user (&info
, uinfo
, 3*sizeof(int)) ||
1757 copy_from_user (info
._sifields
._pad
, uinfo
->_sifields
._pad
, SI_PAD_SIZE
))
1760 ret
= sys_rt_sigqueueinfo(pid
, sig
, &info
);
1765 extern void check_pending(int signum
);
1768 * count32() counts the number of arguments/envelopes
1770 static int count32(u32
* argv
)
1778 error
= get_user(p
,argv
);
1779 if (error
) return error
;
1788 * 'copy_string32()' copies argument/envelope strings from user
1789 * memory to free pages in kernel mem. These are in a format ready
1790 * to be put directly into the top of new user memory.
1792 static int copy_strings32(int argc
, u32
* argv
, struct linux_binprm
*bprm
)
1794 while (argc
-- > 0) {
1799 if (get_user(str
, argv
+ argc
) ||
1801 !(len
= strnlen_user((char *)A(str
), bprm
->p
)))
1813 int offset
, bytes_to_copy
, new, err
;
1815 offset
= pos
% PAGE_SIZE
;
1816 page
= bprm
->page
[pos
/ PAGE_SIZE
];
1819 page
= alloc_page(GFP_USER
);
1820 bprm
->page
[pos
/ PAGE_SIZE
] = page
;
1825 kaddr
= (char *)kmap(page
);
1828 memset(kaddr
, 0, offset
);
1829 bytes_to_copy
= PAGE_SIZE
- offset
;
1830 if (bytes_to_copy
> len
) {
1831 bytes_to_copy
= len
;
1833 memset(kaddr
+offset
+len
, 0,
1834 PAGE_SIZE
-offset
-len
);
1837 err
= copy_from_user(kaddr
+ offset
, (char *)A(str
),
1844 pos
+= bytes_to_copy
;
1845 str
+= bytes_to_copy
;
1846 len
-= bytes_to_copy
;
1853 * sys32_execve() executes a new program.
1856 do_execve32(char * filename
, u32
* argv
, u32
* envp
, struct pt_regs
* regs
)
1858 struct linux_binprm bprm
;
1863 sched_balance_exec();
1865 file
= open_exec(filename
);
1867 retval
= PTR_ERR(file
);
1871 bprm
.p
= PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(void *);
1872 memset(bprm
.page
, 0, MAX_ARG_PAGES
* sizeof(bprm
.page
[0]));
1875 bprm
.filename
= filename
;
1879 bprm
.mm
= mm_alloc();
1884 /* init_new_context is empty for s390x. */
1886 bprm
.argc
= count32(argv
);
1887 if ((retval
= bprm
.argc
) < 0)
1890 bprm
.envc
= count32(envp
);
1891 if ((retval
= bprm
.envc
) < 0)
1894 retval
= security_bprm_alloc(&bprm
);
1898 retval
= prepare_binprm(&bprm
);
1902 retval
= copy_strings_kernel(1, &bprm
.filename
, &bprm
);
1907 retval
= copy_strings32(bprm
.envc
, envp
, &bprm
);
1911 retval
= copy_strings32(bprm
.argc
, argv
, &bprm
);
1915 retval
= search_binary_handler(&bprm
, regs
);
1917 /* execve success */
1918 security_bprm_free(&bprm
);
1923 /* Something went wrong, return the inode and free the argument pages*/
1924 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++) {
1925 struct page
* page
= bprm
.page
[i
];
1931 security_bprm_free(&bprm
);
1938 allow_write_access(bprm
.file
);
1946 * sys32_execve() executes a new program after the asm stub has set
1947 * things up for us. This should basically do what I want it to.
1950 sys32_execve(struct pt_regs regs
)
1955 filename
= getname((char *)A(regs
.orig_gpr2
));
1956 error
= PTR_ERR(filename
);
1957 if (IS_ERR(filename
))
1959 error
= do_execve32(filename
, (u32
*)A(regs
.gprs
[3]), (u32
*)A(regs
.gprs
[4]), ®s
);
1962 current
->ptrace
&= ~PT_DTRACE
;
1963 current
->thread
.fp_regs
.fpc
=0;
1964 __asm__ __volatile__
1975 #ifdef CONFIG_MODULES
1977 extern asmlinkage
int sys_init_module(const char *name_user
, struct module
*mod_user
);
1979 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
1980 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
1982 asmlinkage
int sys32_init_module(const char *name_user
, struct module
*mod_user
)
1984 return sys_init_module(name_user
, mod_user
);
1987 extern asmlinkage
int sys_delete_module(const char *name_user
);
1989 asmlinkage
int sys32_delete_module(const char *name_user
)
1991 return sys_delete_module(name_user
);
1994 struct module_info32
{
2001 #else /* CONFIG_MODULES */
2004 sys32_init_module(const char *name_user
, struct module
*mod_user
)
2010 sys32_delete_module(const char *name_user
)
2015 #endif /* CONFIG_MODULES */
2017 /* Stuff for NFS server syscalls... */
2018 struct nfsctl_svc32
{
2023 struct nfsctl_client32
{
2024 s8 cl32_ident
[NFSCLNT_IDMAX
+1];
2026 struct in_addr cl32_addrlist
[NFSCLNT_ADDRMAX
];
2029 u8 cl32_fhkey
[NFSCLNT_KEYMAX
];
2032 struct nfsctl_export32
{
2033 s8 ex32_client
[NFSCLNT_IDMAX
+1];
2034 s8 ex32_path
[NFS_MAXPATHLEN
+1];
2035 compat_dev_t ex32_dev
;
2036 compat_ino_t ex32_ino
;
2038 compat_uid_t ex32_anon_uid
;
2039 compat_gid_t ex32_anon_gid
;
2042 struct nfsctl_fdparm32
{
2043 struct sockaddr gd32_addr
;
2044 s8 gd32_path
[NFS_MAXPATHLEN
+1];
2048 struct nfsctl_fsparm32
{
2049 struct sockaddr gd32_addr
;
2050 s8 gd32_path
[NFS_MAXPATHLEN
+1];
2054 struct nfsctl_arg32
{
2055 s32 ca32_version
; /* safeguard */
2057 struct nfsctl_svc32 u32_svc
;
2058 struct nfsctl_client32 u32_client
;
2059 struct nfsctl_export32 u32_export
;
2060 struct nfsctl_fdparm32 u32_getfd
;
2061 struct nfsctl_fsparm32 u32_getfs
;
2063 #define ca32_svc u.u32_svc
2064 #define ca32_client u.u32_client
2065 #define ca32_export u.u32_export
2066 #define ca32_getfd u.u32_getfd
2067 #define ca32_getfs u.u32_getfs
2068 #define ca32_authd u.u32_authd
2071 union nfsctl_res32
{
2072 __u8 cr32_getfh
[NFS_FHSIZE
];
2073 struct knfsd_fh cr32_getfs
;
2076 static int nfs_svc32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
2080 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
2081 err
|= __get_user(karg
->ca_svc
.svc_port
, &arg32
->ca32_svc
.svc32_port
);
2082 err
|= __get_user(karg
->ca_svc
.svc_nthreads
, &arg32
->ca32_svc
.svc32_nthreads
);
2086 static int nfs_clnt32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
2090 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
2091 err
|= copy_from_user(&karg
->ca_client
.cl_ident
[0],
2092 &arg32
->ca32_client
.cl32_ident
[0],
2094 err
|= __get_user(karg
->ca_client
.cl_naddr
, &arg32
->ca32_client
.cl32_naddr
);
2095 err
|= copy_from_user(&karg
->ca_client
.cl_addrlist
[0],
2096 &arg32
->ca32_client
.cl32_addrlist
[0],
2097 (sizeof(struct in_addr
) * NFSCLNT_ADDRMAX
));
2098 err
|= __get_user(karg
->ca_client
.cl_fhkeytype
,
2099 &arg32
->ca32_client
.cl32_fhkeytype
);
2100 err
|= __get_user(karg
->ca_client
.cl_fhkeylen
,
2101 &arg32
->ca32_client
.cl32_fhkeylen
);
2102 err
|= copy_from_user(&karg
->ca_client
.cl_fhkey
[0],
2103 &arg32
->ca32_client
.cl32_fhkey
[0],
2108 static int nfs_exp32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
2112 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
2113 err
|= copy_from_user(&karg
->ca_export
.ex_client
[0],
2114 &arg32
->ca32_export
.ex32_client
[0],
2116 err
|= copy_from_user(&karg
->ca_export
.ex_path
[0],
2117 &arg32
->ca32_export
.ex32_path
[0],
2119 err
|= __get_user(karg
->ca_export
.ex_dev
,
2120 &arg32
->ca32_export
.ex32_dev
);
2121 err
|= __get_user(karg
->ca_export
.ex_ino
,
2122 &arg32
->ca32_export
.ex32_ino
);
2123 err
|= __get_user(karg
->ca_export
.ex_flags
,
2124 &arg32
->ca32_export
.ex32_flags
);
2125 err
|= __get_user(karg
->ca_export
.ex_anon_uid
,
2126 &arg32
->ca32_export
.ex32_anon_uid
);
2127 err
|= __get_user(karg
->ca_export
.ex_anon_gid
,
2128 &arg32
->ca32_export
.ex32_anon_gid
);
2129 karg
->ca_export
.ex_anon_uid
= high2lowuid(karg
->ca_export
.ex_anon_uid
);
2130 karg
->ca_export
.ex_anon_gid
= high2lowgid(karg
->ca_export
.ex_anon_gid
);
2134 static int nfs_getfd32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
2138 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
2139 err
|= copy_from_user(&karg
->ca_getfd
.gd_addr
,
2140 &arg32
->ca32_getfd
.gd32_addr
,
2141 (sizeof(struct sockaddr
)));
2142 err
|= copy_from_user(&karg
->ca_getfd
.gd_path
,
2143 &arg32
->ca32_getfd
.gd32_path
,
2144 (NFS_MAXPATHLEN
+1));
2145 err
|= __get_user(karg
->ca_getfd
.gd_version
,
2146 &arg32
->ca32_getfd
.gd32_version
);
2150 static int nfs_getfs32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
2154 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
2155 err
|= copy_from_user(&karg
->ca_getfs
.gd_addr
,
2156 &arg32
->ca32_getfs
.gd32_addr
,
2157 (sizeof(struct sockaddr
)));
2158 err
|= copy_from_user(&karg
->ca_getfs
.gd_path
,
2159 &arg32
->ca32_getfs
.gd32_path
,
2160 (NFS_MAXPATHLEN
+1));
2161 err
|= __get_user(karg
->ca_getfs
.gd_maxlen
,
2162 &arg32
->ca32_getfs
.gd32_maxlen
);
2166 /* This really doesn't need translations, we are only passing
2167 * back a union which contains opaque nfs file handle data.
2169 static int nfs_getfh32_res_trans(union nfsctl_res
*kres
, union nfsctl_res32
*res32
)
2171 return copy_to_user(res32
, kres
, sizeof(*res32
)) ? -EFAULT
: 0;
2175 asmlinkage long sys_ni_syscall(void);
2178 int asmlinkage
sys32_nfsservctl(int cmd
, struct nfsctl_arg32
*arg32
, union nfsctl_res32
*res32
)
2180 struct nfsctl_arg
*karg
= NULL
;
2181 union nfsctl_res
*kres
= NULL
;
2185 karg
= kmalloc(sizeof(*karg
), GFP_USER
);
2189 kres
= kmalloc(sizeof(*kres
), GFP_USER
);
2197 err
= nfs_svc32_trans(karg
, arg32
);
2199 case NFSCTL_ADDCLIENT
:
2200 err
= nfs_clnt32_trans(karg
, arg32
);
2202 case NFSCTL_DELCLIENT
:
2203 err
= nfs_clnt32_trans(karg
, arg32
);
2206 case NFSCTL_UNEXPORT
:
2207 err
= nfs_exp32_trans(karg
, arg32
);
2210 err
= nfs_getfd32_trans(karg
, arg32
);
2213 err
= nfs_getfs32_trans(karg
, arg32
);
2223 err
= sys_nfsservctl(cmd
, karg
, kres
);
2229 if((cmd
== NFSCTL_GETFD
) ||
2230 (cmd
== NFSCTL_GETFS
))
2231 err
= nfs_getfh32_res_trans(kres
, res32
);
2241 /* Translations due to time_t size differences. Which affects all
2242 sorts of things, like timeval and itimerval. */
2244 extern struct timezone sys_tz
;
2246 asmlinkage
int sys32_gettimeofday(struct compat_timeval
*tv
, struct timezone
*tz
)
2250 do_gettimeofday(&ktv
);
2251 if (put_tv32(tv
, &ktv
))
2255 if (copy_to_user(tz
, &sys_tz
, sizeof(sys_tz
)))
2261 static inline long get_ts32(struct timespec
*o
, struct compat_timeval
*i
)
2265 if (!access_ok(VERIFY_READ
, i
, sizeof(*i
)))
2267 if (__get_user(o
->tv_sec
, &i
->tv_sec
))
2269 if (__get_user(usec
, &i
->tv_usec
))
2271 o
->tv_nsec
= usec
* 1000;
2275 asmlinkage
int sys32_settimeofday(struct compat_timeval
*tv
, struct timezone
*tz
)
2277 struct timespec kts
;
2278 struct timezone ktz
;
2281 if (get_ts32(&kts
, tv
))
2285 if (copy_from_user(&ktz
, tz
, sizeof(ktz
)))
2289 return do_sys_settimeofday(tv
? &kts
: NULL
, tz
? &ktz
: NULL
);
2292 asmlinkage
int sys_utimes(char *, struct timeval
*);
2294 asmlinkage
int sys32_utimes(char *filename
, struct compat_timeval
*tvs
)
2297 struct timeval ktvs
[2];
2298 mm_segment_t old_fs
;
2301 kfilename
= getname(filename
);
2302 ret
= PTR_ERR(kfilename
);
2303 if (!IS_ERR(kfilename
)) {
2305 if (get_tv32(&ktvs
[0], tvs
) ||
2306 get_tv32(&ktvs
[1], 1+tvs
))
2312 ret
= sys_utimes(kfilename
, &ktvs
[0]);
2320 /* These are here just in case some old sparc32 binary calls it. */
2321 asmlinkage
int sys32_pause(void)
2323 current
->state
= TASK_INTERRUPTIBLE
;
2325 return -ERESTARTNOHAND
;
2328 extern asmlinkage
int sys_prctl(int option
, unsigned long arg2
, unsigned long arg3
,
2329 unsigned long arg4
, unsigned long arg5
);
2331 asmlinkage
int sys32_prctl(int option
, u32 arg2
, u32 arg3
, u32 arg4
, u32 arg5
)
2333 return sys_prctl(option
,
2334 (unsigned long) arg2
,
2335 (unsigned long) arg3
,
2336 (unsigned long) arg4
,
2337 (unsigned long) arg5
);
2341 extern asmlinkage ssize_t
sys_pread64(unsigned int fd
, char * buf
,
2342 size_t count
, loff_t pos
);
2344 extern asmlinkage ssize_t
sys_pwrite64(unsigned int fd
, const char * buf
,
2345 size_t count
, loff_t pos
);
2347 asmlinkage compat_ssize_t
sys32_pread64(unsigned int fd
, char *ubuf
,
2348 compat_size_t count
, u32 poshi
, u32 poslo
)
2350 if ((compat_ssize_t
) count
< 0)
2352 return sys_pread64(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
2355 asmlinkage compat_ssize_t
sys32_pwrite64(unsigned int fd
, char *ubuf
,
2356 compat_size_t count
, u32 poshi
, u32 poslo
)
2358 if ((compat_ssize_t
) count
< 0)
2360 return sys_pwrite64(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
2363 extern asmlinkage ssize_t
sys_readahead(int fd
, loff_t offset
, size_t count
);
2365 asmlinkage compat_ssize_t
sys32_readahead(int fd
, u32 offhi
, u32 offlo
, s32 count
)
2367 return sys_readahead(fd
, ((loff_t
)AA(offhi
) << 32) | AA(offlo
), count
);
2370 extern asmlinkage ssize_t
sys_sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
);
2372 asmlinkage
int sys32_sendfile(int out_fd
, int in_fd
, compat_off_t
*offset
, s32 count
)
2374 mm_segment_t old_fs
= get_fs();
2378 if (offset
&& get_user(of
, offset
))
2382 ret
= sys_sendfile(out_fd
, in_fd
, offset
? &of
: NULL
, count
);
2385 if (!ret
&& offset
&& put_user(of
, offset
))
2391 extern asmlinkage ssize_t
sys_sendfile64(int out_fd
, int in_fd
,
2392 loff_t
*offset
, size_t count
);
2394 asmlinkage
int sys32_sendfile64(int out_fd
, int in_fd
,
2395 compat_loff_t
*offset
, s32 count
)
2397 mm_segment_t old_fs
= get_fs();
2401 if (offset
&& get_user(lof
, offset
))
2405 ret
= sys_sendfile64(out_fd
, in_fd
, offset
? &lof
: NULL
, count
);
2408 if (offset
&& put_user(lof
, offset
))
2414 /* Handle adjtimex compatibility. */
2418 s32 offset
, freq
, maxerror
, esterror
;
2419 s32 status
, constant
, precision
, tolerance
;
2420 struct compat_timeval time
;
2422 s32 ppsfreq
, jitter
, shift
, stabil
;
2423 s32 jitcnt
, calcnt
, errcnt
, stbcnt
;
2424 s32
:32; s32
:32; s32
:32; s32
:32;
2425 s32
:32; s32
:32; s32
:32; s32
:32;
2426 s32
:32; s32
:32; s32
:32; s32
:32;
2429 extern int do_adjtimex(struct timex
*);
2431 asmlinkage
int sys32_adjtimex(struct timex32
*utp
)
2436 memset(&txc
, 0, sizeof(struct timex
));
2438 if(get_user(txc
.modes
, &utp
->modes
) ||
2439 __get_user(txc
.offset
, &utp
->offset
) ||
2440 __get_user(txc
.freq
, &utp
->freq
) ||
2441 __get_user(txc
.maxerror
, &utp
->maxerror
) ||
2442 __get_user(txc
.esterror
, &utp
->esterror
) ||
2443 __get_user(txc
.status
, &utp
->status
) ||
2444 __get_user(txc
.constant
, &utp
->constant
) ||
2445 __get_user(txc
.precision
, &utp
->precision
) ||
2446 __get_user(txc
.tolerance
, &utp
->tolerance
) ||
2447 __get_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
2448 __get_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
2449 __get_user(txc
.tick
, &utp
->tick
) ||
2450 __get_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
2451 __get_user(txc
.jitter
, &utp
->jitter
) ||
2452 __get_user(txc
.shift
, &utp
->shift
) ||
2453 __get_user(txc
.stabil
, &utp
->stabil
) ||
2454 __get_user(txc
.jitcnt
, &utp
->jitcnt
) ||
2455 __get_user(txc
.calcnt
, &utp
->calcnt
) ||
2456 __get_user(txc
.errcnt
, &utp
->errcnt
) ||
2457 __get_user(txc
.stbcnt
, &utp
->stbcnt
))
2460 ret
= do_adjtimex(&txc
);
2462 if(put_user(txc
.modes
, &utp
->modes
) ||
2463 __put_user(txc
.offset
, &utp
->offset
) ||
2464 __put_user(txc
.freq
, &utp
->freq
) ||
2465 __put_user(txc
.maxerror
, &utp
->maxerror
) ||
2466 __put_user(txc
.esterror
, &utp
->esterror
) ||
2467 __put_user(txc
.status
, &utp
->status
) ||
2468 __put_user(txc
.constant
, &utp
->constant
) ||
2469 __put_user(txc
.precision
, &utp
->precision
) ||
2470 __put_user(txc
.tolerance
, &utp
->tolerance
) ||
2471 __put_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
2472 __put_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
2473 __put_user(txc
.tick
, &utp
->tick
) ||
2474 __put_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
2475 __put_user(txc
.jitter
, &utp
->jitter
) ||
2476 __put_user(txc
.shift
, &utp
->shift
) ||
2477 __put_user(txc
.stabil
, &utp
->stabil
) ||
2478 __put_user(txc
.jitcnt
, &utp
->jitcnt
) ||
2479 __put_user(txc
.calcnt
, &utp
->calcnt
) ||
2480 __put_user(txc
.errcnt
, &utp
->errcnt
) ||
2481 __put_user(txc
.stbcnt
, &utp
->stbcnt
))
2487 extern asmlinkage
long sys_setpriority(int which
, int who
, int niceval
);
2489 asmlinkage
int sys_setpriority32(u32 which
, u32 who
, u32 niceval
)
2491 return sys_setpriority((int) which
,
2496 struct __sysctl_args32
{
2506 extern asmlinkage
long sys32_sysctl(struct __sysctl_args32
*args
)
2508 struct __sysctl_args32 tmp
;
2510 size_t oldlen
, *oldlenp
= NULL
;
2511 unsigned long addr
= (((long)&args
->__unused
[0]) + 7) & ~7;
2513 if (copy_from_user(&tmp
, args
, sizeof(tmp
)))
2516 if (tmp
.oldval
&& tmp
.oldlenp
) {
2517 /* Duh, this is ugly and might not work if sysctl_args
2518 is in read-only memory, but do_sysctl does indirectly
2519 a lot of uaccess in both directions and we'd have to
2520 basically copy the whole sysctl.c here, and
2521 glibc's __sysctl uses rw memory for the structure
2523 if (get_user(oldlen
, (u32
*)A(tmp
.oldlenp
)) ||
2524 put_user(oldlen
, (size_t *)addr
))
2526 oldlenp
= (size_t *)addr
;
2530 error
= do_sysctl((int *)A(tmp
.name
), tmp
.nlen
, (void *)A(tmp
.oldval
),
2531 oldlenp
, (void *)A(tmp
.newval
), tmp
.newlen
);
2535 if (get_user(oldlen
, (size_t *)addr
) ||
2536 put_user(oldlen
, (u32
*)A(tmp
.oldlenp
)))
2539 copy_to_user(args
->__unused
, tmp
.__unused
, sizeof(tmp
.__unused
));
2544 struct stat64_emu31
{
2545 unsigned char __pad0
[6];
2546 unsigned short st_dev
;
2547 unsigned int __pad1
;
2548 #define STAT64_HAS_BROKEN_ST_INO 1
2550 unsigned int st_mode
;
2551 unsigned int st_nlink
;
2554 unsigned char __pad2
[6];
2555 unsigned short st_rdev
;
2556 unsigned int __pad3
;
2559 unsigned char __pad4
[4];
2560 u32 __pad5
; /* future possible st_blocks high bits */
2561 u32 st_blocks
; /* Number 512-byte blocks allocated. */
2567 u32 __pad8
; /* will be high 32 bits of ctime someday */
2568 unsigned long st_ino
;
2572 putstat64 (struct stat64_emu31
*ubuf
, struct stat
*kbuf
)
2574 struct stat64_emu31 tmp
;
2576 memset(&tmp
, 0, sizeof(tmp
));
2578 tmp
.st_dev
= (unsigned short)kbuf
->st_dev
;
2579 tmp
.st_ino
= kbuf
->st_ino
;
2580 tmp
.__st_ino
= (u32
)kbuf
->st_ino
;
2581 tmp
.st_mode
= kbuf
->st_mode
;
2582 tmp
.st_nlink
= (unsigned int)kbuf
->st_nlink
;
2583 tmp
.st_uid
= kbuf
->st_uid
;
2584 tmp
.st_gid
= kbuf
->st_gid
;
2585 tmp
.st_rdev
= (unsigned short)kbuf
->st_rdev
;
2586 tmp
.st_size
= kbuf
->st_size
;
2587 tmp
.st_blksize
= (u32
)kbuf
->st_blksize
;
2588 tmp
.st_blocks
= (u32
)kbuf
->st_blocks
;
2589 tmp
.st_atime
= (u32
)kbuf
->st_atime
;
2590 tmp
.st_mtime
= (u32
)kbuf
->st_mtime
;
2591 tmp
.st_ctime
= (u32
)kbuf
->st_ctime
;
2593 return copy_to_user(ubuf
,&tmp
,sizeof(tmp
)) ? -EFAULT
: 0;
2596 extern asmlinkage
long sys_newstat(char * filename
, struct stat
* statbuf
);
2598 asmlinkage
long sys32_stat64(char * filename
, struct stat64_emu31
* statbuf
, long flags
)
2604 mm_segment_t old_fs
= get_fs();
2606 tmp
= getname(filename
);
2612 ret
= sys_newstat(tmp
, &s
);
2615 if (putstat64 (statbuf
, &s
))
2620 extern asmlinkage
long sys_newlstat(char * filename
, struct stat
* statbuf
);
2622 asmlinkage
long sys32_lstat64(char * filename
, struct stat64_emu31
* statbuf
, long flags
)
2628 mm_segment_t old_fs
= get_fs();
2630 tmp
= getname(filename
);
2636 ret
= sys_newlstat(tmp
, &s
);
2639 if (putstat64 (statbuf
, &s
))
2644 extern asmlinkage
long sys_newfstat(unsigned int fd
, struct stat
* statbuf
);
2646 asmlinkage
long sys32_fstat64(unsigned long fd
, struct stat64_emu31
* statbuf
, long flags
)
2650 mm_segment_t old_fs
= get_fs();
2653 ret
= sys_newfstat(fd
, &s
);
2655 if (putstat64 (statbuf
, &s
))
2661 * Linux/i386 didn't use to be able to handle more than
2662 * 4 system call parameters, so these system calls used a memory
2663 * block for parameter passing..
2666 struct mmap_arg_struct_emu31
{
2675 /* common code for old and new mmaps */
2676 static inline long do_mmap2(
2677 unsigned long addr
, unsigned long len
,
2678 unsigned long prot
, unsigned long flags
,
2679 unsigned long fd
, unsigned long pgoff
)
2681 struct file
* file
= NULL
;
2682 unsigned long error
= -EBADF
;
2684 flags
&= ~(MAP_EXECUTABLE
| MAP_DENYWRITE
);
2685 if (!(flags
& MAP_ANONYMOUS
)) {
2691 down_write(¤t
->mm
->mmap_sem
);
2692 error
= do_mmap_pgoff(file
, addr
, len
, prot
, flags
, pgoff
);
2693 if (!IS_ERR((void *) error
) && error
+ len
>= 0x80000000ULL
) {
2694 /* Result is out of bounds. */
2695 do_munmap(current
->mm
, addr
, len
);
2698 up_write(¤t
->mm
->mmap_sem
);
2707 asmlinkage
unsigned long
2708 old32_mmap(struct mmap_arg_struct_emu31
*arg
)
2710 struct mmap_arg_struct_emu31 a
;
2711 int error
= -EFAULT
;
2713 if (copy_from_user(&a
, arg
, sizeof(a
)))
2717 if (a
.offset
& ~PAGE_MASK
)
2720 error
= do_mmap2(a
.addr
, a
.len
, a
.prot
, a
.flags
, a
.fd
, a
.offset
>> PAGE_SHIFT
);
2726 sys32_mmap2(struct mmap_arg_struct_emu31
*arg
)
2728 struct mmap_arg_struct_emu31 a
;
2729 int error
= -EFAULT
;
2731 if (copy_from_user(&a
, arg
, sizeof(a
)))
2733 error
= do_mmap2(a
.addr
, a
.len
, a
.prot
, a
.flags
, a
.fd
, a
.offset
);
2738 extern asmlinkage
int sys_sched_setaffinity(pid_t pid
, unsigned int len
,
2739 unsigned long *user_mask_ptr
);
2741 asmlinkage
int sys32_sched_setaffinity(compat_pid_t pid
, unsigned int len
,
2744 unsigned long kernel_mask
;
2745 mm_segment_t old_fs
;
2748 if (get_user(kernel_mask
, user_mask_ptr
))
2753 ret
= sys_sched_setaffinity(pid
,
2754 /* XXX Nice api... */
2755 sizeof(kernel_mask
),
2762 extern asmlinkage
int sys_sched_getaffinity(pid_t pid
, unsigned int len
,
2763 unsigned long *user_mask_ptr
);
2765 asmlinkage
int sys32_sched_getaffinity(compat_pid_t pid
, unsigned int len
,
2768 unsigned long kernel_mask
;
2769 mm_segment_t old_fs
;
2774 ret
= sys_sched_getaffinity(pid
,
2775 /* XXX Nice api... */
2776 sizeof(kernel_mask
),
2781 if (put_user(kernel_mask
, user_mask_ptr
))
2788 asmlinkage ssize_t
sys_read(unsigned int fd
, char * buf
, size_t count
);
2790 asmlinkage compat_ssize_t
sys32_read(unsigned int fd
, char * buf
, size_t count
)
2792 if ((compat_ssize_t
) count
< 0)
2795 return sys_read(fd
, buf
, count
);
2798 asmlinkage ssize_t
sys_write(unsigned int fd
, const char * buf
, size_t count
);
2800 asmlinkage compat_ssize_t
sys32_write(unsigned int fd
, char * buf
, size_t count
)
2802 if ((compat_ssize_t
) count
< 0)
2805 return sys_write(fd
, buf
, count
);
2808 asmlinkage
int sys32_clone(struct pt_regs regs
)
2810 unsigned long clone_flags
;
2811 unsigned long newsp
;
2812 struct task_struct
*p
;
2813 int *parent_tidptr
, *child_tidptr
;
2815 clone_flags
= regs
.gprs
[3] & 0xffffffffUL
;
2816 newsp
= regs
.orig_gpr2
& 0x7fffffffUL
;
2817 parent_tidptr
= (int *) (regs
.gprs
[4] & 0x7fffffffUL
);
2818 child_tidptr
= (int *) (regs
.gprs
[5] & 0x7fffffffUL
);
2820 newsp
= regs
.gprs
[15];
2821 p
= do_fork(clone_flags
& ~CLONE_IDLETASK
, newsp
, ®s
, 0,
2822 parent_tidptr
, child_tidptr
);
2823 return IS_ERR(p
) ? PTR_ERR(p
) : p
->pid
;