1 /* $Id: sys_sparc32.c,v 1.152 2000/06/22 17:44:47 davem Exp $
2 * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
7 * These routines maintain argument size conversion between 32bit and 64bit
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/utime.h>
19 #include <linux/resource.h>
20 #include <linux/times.h>
21 #include <linux/utsname.h>
22 #include <linux/timex.h>
23 #include <linux/smp.h>
24 #include <linux/smp_lock.h>
25 #include <linux/sem.h>
26 #include <linux/msg.h>
27 #include <linux/shm.h>
28 #include <linux/malloc.h>
29 #include <linux/uio.h>
30 #include <linux/nfs_fs.h>
31 #include <linux/smb_fs.h>
32 #include <linux/smb_mount.h>
33 #include <linux/ncp_fs.h>
34 #include <linux/quota.h>
35 #include <linux/module.h>
36 #include <linux/sunrpc/svc.h>
37 #include <linux/nfsd/nfsd.h>
38 #include <linux/nfsd/cache.h>
39 #include <linux/nfsd/xdr.h>
40 #include <linux/nfsd/syscall.h>
41 #include <linux/poll.h>
42 #include <linux/personality.h>
43 #include <linux/stat.h>
44 #include <linux/filter.h>
45 #include <linux/highmem.h>
46 #include <linux/highuid.h>
47 #include <linux/mman.h>
49 #include <asm/types.h>
51 #include <asm/uaccess.h>
52 #include <asm/fpumacro.h>
53 #include <asm/semaphore.h>
57 /* Use this to get at 32-bit user passed pointers. */
58 /* Things to consider: the low-level assembly stub does
59 srl x, 0, x for first four arguments, so if you have
60 pointer to something in the first four arguments, just
61 declare it as a pointer, not u32. On the other side,
62 arguments from 5th onwards should be declared as u32
63 for pointers, and need AA() around each usage.
64 A() macro should be used for places where you e.g.
65 have some internal variable u32 and just want to get
66 rid of a compiler warning. AA() has to be used in
67 places where you want to convert a function argument
68 to 32bit pointer or when you e.g. access pt_regs
69 structure and want to consider 32bit registers only.
72 #define A(__x) ((unsigned long)(__x))
74 ({ unsigned long __ret; \
75 __asm__ ("srl %0, 0, %0" \
81 extern asmlinkage
long sys_chown(const char *, uid_t
,gid_t
);
82 extern asmlinkage
long sys_lchown(const char *, uid_t
,gid_t
);
83 extern asmlinkage
long sys_fchown(unsigned int, uid_t
,gid_t
);
84 extern asmlinkage
long sys_setregid(gid_t
, gid_t
);
85 extern asmlinkage
long sys_setgid(gid_t
);
86 extern asmlinkage
long sys_setreuid(uid_t
, uid_t
);
87 extern asmlinkage
long sys_setuid(uid_t
);
88 extern asmlinkage
long sys_setresuid(uid_t
, uid_t
, uid_t
);
89 extern asmlinkage
long sys_setresgid(gid_t
, gid_t
, gid_t
);
90 extern asmlinkage
long sys_setfsuid(uid_t
);
91 extern asmlinkage
long sys_setfsgid(gid_t
);
93 /* For this source file, we want overflow handling. */
101 #undef NEW_TO_OLD_UID
102 #undef NEW_TO_OLD_GID
103 #undef SET_OLDSTAT_UID
104 #undef SET_OLDSTAT_GID
108 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
109 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
110 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
111 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
112 #define SET_UID16(var, uid) var = high2lowuid(uid)
113 #define SET_GID16(var, gid) var = high2lowgid(gid)
114 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
115 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
116 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
117 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
118 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
119 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
121 asmlinkage
long sys32_chown16(const char * filename
, u16 user
, u16 group
)
123 return sys_chown(filename
, low2highuid(user
), low2highgid(group
));
126 asmlinkage
long sys32_lchown16(const char * filename
, u16 user
, u16 group
)
128 return sys_lchown(filename
, low2highuid(user
), low2highgid(group
));
131 asmlinkage
long sys32_fchown16(unsigned int fd
, u16 user
, u16 group
)
133 return sys_fchown(fd
, low2highuid(user
), low2highgid(group
));
136 asmlinkage
long sys32_setregid16(u16 rgid
, u16 egid
)
138 return sys_setregid(low2highgid(rgid
), low2highgid(egid
));
141 asmlinkage
long sys32_setgid16(u16 gid
)
143 return sys_setgid((gid_t
)gid
);
146 asmlinkage
long sys32_setreuid16(u16 ruid
, u16 euid
)
148 return sys_setreuid(low2highuid(ruid
), low2highuid(euid
));
151 asmlinkage
long sys32_setuid16(u16 uid
)
153 return sys_setuid((uid_t
)uid
);
156 asmlinkage
long sys32_setresuid16(u16 ruid
, u16 euid
, u16 suid
)
158 return sys_setresuid(low2highuid(ruid
), low2highuid(euid
),
162 asmlinkage
long sys32_getresuid16(u16
*ruid
, u16
*euid
, u16
*suid
)
166 if (!(retval
= put_user(high2lowuid(current
->uid
), ruid
)) &&
167 !(retval
= put_user(high2lowuid(current
->euid
), euid
)))
168 retval
= put_user(high2lowuid(current
->suid
), suid
);
173 asmlinkage
long sys32_setresgid16(u16 rgid
, u16 egid
, u16 sgid
)
175 return sys_setresgid(low2highgid(rgid
), low2highgid(egid
),
179 asmlinkage
long sys32_getresgid16(u16
*rgid
, u16
*egid
, u16
*sgid
)
183 if (!(retval
= put_user(high2lowgid(current
->gid
), rgid
)) &&
184 !(retval
= put_user(high2lowgid(current
->egid
), egid
)))
185 retval
= put_user(high2lowgid(current
->sgid
), sgid
);
190 asmlinkage
long sys32_setfsuid16(u16 uid
)
192 return sys_setfsuid((uid_t
)uid
);
195 asmlinkage
long sys32_setfsgid16(u16 gid
)
197 return sys_setfsgid((gid_t
)gid
);
200 asmlinkage
long sys32_getgroups16(int gidsetsize
, u16
*grouplist
)
207 i
= current
->ngroups
;
212 groups
[j
] = current
->groups
[j
];
213 if (copy_to_user(grouplist
, groups
, sizeof(u16
)*i
))
219 asmlinkage
long sys32_setgroups16(int gidsetsize
, u16
*grouplist
)
224 if (!capable(CAP_SETGID
))
226 if ((unsigned) gidsetsize
> NGROUPS
)
228 if (copy_from_user(groups
, grouplist
, gidsetsize
* sizeof(u16
)))
230 for (i
= 0 ; i
< gidsetsize
; i
++)
231 current
->groups
[i
] = (gid_t
)groups
[i
];
232 current
->ngroups
= gidsetsize
;
236 asmlinkage
long sys32_getuid16(void)
238 return high2lowuid(current
->uid
);
241 asmlinkage
long sys32_geteuid16(void)
243 return high2lowuid(current
->euid
);
246 asmlinkage
long sys32_getgid16(void)
248 return high2lowgid(current
->gid
);
251 asmlinkage
long sys32_getegid16(void)
253 return high2lowgid(current
->egid
);
256 /* In order to reduce some races, while at the same time doing additional
257 * checking and hopefully speeding things up, we copy filenames to the
258 * kernel data space before using them..
260 * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
262 static inline int do_getname32(const char *filename
, char *page
)
266 /* 32bit pointer will be always far below TASK_SIZE :)) */
267 retval
= strncpy_from_user((char *)page
, (char *)filename
, PAGE_SIZE
);
269 if (retval
< PAGE_SIZE
)
271 return -ENAMETOOLONG
;
277 char * getname32(const char *filename
)
281 result
= ERR_PTR(-ENOMEM
);
282 tmp
= (char *)__get_free_page(GFP_KERNEL
);
284 int retval
= do_getname32(filename
, tmp
);
289 result
= ERR_PTR(retval
);
295 /* 32-bit timeval and related flotsam. */
304 struct timeval32 it_interval
;
305 struct timeval32 it_value
;
308 static inline long get_tv32(struct timeval
*o
, struct timeval32
*i
)
310 return (!access_ok(VERIFY_READ
, tv32
, sizeof(*tv32
)) ||
311 (__get_user(o
->tv_sec
, &i
->tv_sec
) |
312 __get_user(o
->tv_usec
, &i
->tv_usec
)));
315 static inline long put_tv32(struct timeval32
*o
, struct timeval
*i
)
317 return (!access_ok(VERIFY_WRITE
, o
, sizeof(*o
)) ||
318 (__put_user(i
->tv_sec
, &o
->tv_sec
) |
319 __put_user(i
->tv_usec
, &o
->tv_usec
)));
322 static inline long get_it32(struct itimerval
*o
, struct itimerval32
*i
)
324 return (!access_ok(VERIFY_READ
, i32
, sizeof(*i32
)) ||
325 (__get_user(o
->it_interval
.tv_sec
, &i
->it_interval
.tv_sec
) |
326 __get_user(o
->it_interval
.tv_usec
, &i
->it_interval
.tv_usec
) |
327 __get_user(o
->it_value
.tv_sec
, &i
->it_value
.tv_sec
) |
328 __get_user(o
->it_value
.tv_usec
, &i
->it_value
.tv_usec
)));
331 static inline long put_it32(struct itimerval32
*o
, struct itimerval
*i
)
333 return (!access_ok(VERIFY_WRITE
, i32
, sizeof(*i32
)) ||
334 (__put_user(i
->it_interval
.tv_sec
, &o
->it_interval
.tv_sec
) |
335 __put_user(i
->it_interval
.tv_usec
, &o
->it_interval
.tv_usec
) |
336 __put_user(i
->it_value
.tv_sec
, &o
->it_value
.tv_sec
) |
337 __put_user(i
->it_value
.tv_usec
, &o
->it_value
.tv_usec
)));
340 extern asmlinkage
int sys_ioperm(unsigned long from
, unsigned long num
, int on
);
342 asmlinkage
int sys32_ioperm(u32 from
, u32 num
, int on
)
344 return sys_ioperm((unsigned long)from
, (unsigned long)num
, on
);
347 struct msgbuf32
{ s32 mtype
; char mtext
[1]; };
352 __kernel_uid_t32 uid
;
353 __kernel_gid_t32 gid
;
354 __kernel_uid_t32 cuid
;
355 __kernel_gid_t32 cgid
;
356 __kernel_mode_t32 mode
;
361 struct ipc_perm32 sem_perm
; /* permissions .. see ipc.h */
362 __kernel_time_t32 sem_otime
; /* last semop time */
363 __kernel_time_t32 sem_ctime
; /* last change time */
364 u32 sem_base
; /* ptr to first semaphore in array */
365 u32 sem_pending
; /* pending operations to be processed */
366 u32 sem_pending_last
; /* last pending operation */
367 u32 undo
; /* undo requests on this array */
368 unsigned short sem_nsems
; /* no. of semaphores in array */
371 struct semid64_ds32
{
372 struct ipc64_perm sem_perm
; /* this structure is the same on sparc32 and sparc64 */
374 __kernel_time_t32 sem_otime
;
376 __kernel_time_t32 sem_ctime
;
384 struct ipc_perm32 msg_perm
;
387 __kernel_time_t32 msg_stime
;
388 __kernel_time_t32 msg_rtime
;
389 __kernel_time_t32 msg_ctime
;
392 unsigned short msg_cbytes
;
393 unsigned short msg_qnum
;
394 unsigned short msg_qbytes
;
395 __kernel_ipc_pid_t32 msg_lspid
;
396 __kernel_ipc_pid_t32 msg_lrpid
;
399 struct msqid64_ds32
{
400 struct ipc64_perm msg_perm
;
402 __kernel_time_t32 msg_stime
;
404 __kernel_time_t32 msg_rtime
;
406 __kernel_time_t32 msg_ctime
;
407 unsigned int msg_cbytes
;
408 unsigned int msg_qnum
;
409 unsigned int msg_qbytes
;
410 __kernel_pid_t32 msg_lspid
;
411 __kernel_pid_t32 msg_lrpid
;
412 unsigned int __unused1
;
413 unsigned int __unused2
;
418 struct ipc_perm32 shm_perm
;
420 __kernel_time_t32 shm_atime
;
421 __kernel_time_t32 shm_dtime
;
422 __kernel_time_t32 shm_ctime
;
423 __kernel_ipc_pid_t32 shm_cpid
;
424 __kernel_ipc_pid_t32 shm_lpid
;
425 unsigned short shm_nattch
;
428 struct shmid64_ds32
{
429 struct ipc64_perm shm_perm
;
431 __kernel_time_t32 shm_atime
;
433 __kernel_time_t32 shm_dtime
;
435 __kernel_time_t32 shm_ctime
;
436 __kernel_size_t32 shm_segsz
;
437 __kernel_pid_t32 shm_cpid
;
438 __kernel_pid_t32 shm_lpid
;
439 unsigned int shm_nattch
;
440 unsigned int __unused1
;
441 unsigned int __unused2
;
446 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
448 * This is really horribly ugly.
450 #define IPCOP_MASK(__x) (1UL << (__x))
451 static int do_sys32_semctl(int first
, int second
, int third
, void *uptr
)
460 if (get_user (pad
, (u32
*)uptr
))
463 fourth
.val
= (int)pad
;
465 fourth
.__pad
= (void *)A(pad
);
466 if (IPCOP_MASK (third
) &
467 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SEM_INFO
) | IPCOP_MASK (GETVAL
) |
468 IPCOP_MASK (GETPID
) | IPCOP_MASK (GETNCNT
) | IPCOP_MASK (GETZCNT
) |
469 IPCOP_MASK (GETALL
) | IPCOP_MASK (SETALL
) | IPCOP_MASK (IPC_RMID
))) {
470 err
= sys_semctl (first
, second
, third
, fourth
);
471 } else if (third
& IPC_64
) {
473 struct semid64_ds32
*usp
= (struct semid64_ds32
*)A(pad
);
475 int need_back_translation
;
477 if (third
== (IPC_SET
|IPC_64
)) {
478 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
479 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
480 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
485 need_back_translation
=
486 (IPCOP_MASK (third
) &
487 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
488 if (need_back_translation
)
492 err
= sys_semctl (first
, second
, third
, fourth
);
494 if (need_back_translation
) {
495 int err2
= copy_to_user (&usp
->sem_perm
, &s
.sem_perm
, sizeof(struct ipc64_perm
) + 2*sizeof(time_t));
496 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
497 if (err2
) err
= -EFAULT
;
501 struct semid_ds32
*usp
= (struct semid_ds32
*)A(pad
);
503 int need_back_translation
;
505 if (third
== IPC_SET
) {
506 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
507 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
508 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
513 need_back_translation
=
514 (IPCOP_MASK (third
) &
515 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
516 if (need_back_translation
)
520 err
= sys_semctl (first
, second
, third
, fourth
);
522 if (need_back_translation
) {
523 int err2
= put_user (s
.sem_perm
.key
, &usp
->sem_perm
.key
);
524 err2
|= __put_user (high2lowuid(s
.sem_perm
.uid
), &usp
->sem_perm
.uid
);
525 err2
|= __put_user (high2lowgid(s
.sem_perm
.gid
), &usp
->sem_perm
.gid
);
526 err2
|= __put_user (high2lowuid(s
.sem_perm
.cuid
), &usp
->sem_perm
.cuid
);
527 err2
|= __put_user (high2lowgid(s
.sem_perm
.cgid
), &usp
->sem_perm
.cgid
);
528 err2
|= __put_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
529 err2
|= __put_user (s
.sem_perm
.seq
, &usp
->sem_perm
.seq
);
530 err2
|= __put_user (s
.sem_otime
, &usp
->sem_otime
);
531 err2
|= __put_user (s
.sem_ctime
, &usp
->sem_ctime
);
532 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
533 if (err2
) err
= -EFAULT
;
540 static int do_sys32_msgsnd (int first
, int second
, int third
, void *uptr
)
542 struct msgbuf
*p
= kmalloc (second
+ sizeof (struct msgbuf
) + 4, GFP_USER
);
543 struct msgbuf32
*up
= (struct msgbuf32
*)uptr
;
549 err
= get_user (p
->mtype
, &up
->mtype
);
550 err
|= __copy_from_user (p
->mtext
, &up
->mtext
, second
);
555 err
= sys_msgsnd (first
, p
, second
, third
);
562 static int do_sys32_msgrcv (int first
, int second
, int msgtyp
, int third
,
563 int version
, void *uptr
)
571 struct ipc_kludge
*uipck
= (struct ipc_kludge
*)uptr
;
572 struct ipc_kludge ipck
;
578 if (copy_from_user (&ipck
, uipck
, sizeof (struct ipc_kludge
)))
580 uptr
= (void *)A(ipck
.msgp
);
581 msgtyp
= ipck
.msgtyp
;
584 p
= kmalloc (second
+ sizeof (struct msgbuf
) + 4, GFP_USER
);
589 err
= sys_msgrcv (first
, p
, second
+ 4, msgtyp
, third
);
593 up
= (struct msgbuf32
*)uptr
;
594 if (put_user (p
->mtype
, &up
->mtype
) ||
595 __copy_to_user (&up
->mtext
, p
->mtext
, err
))
603 static int do_sys32_msgctl (int first
, int second
, void *uptr
)
607 if (IPCOP_MASK (second
) &
608 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (MSG_INFO
) |
609 IPCOP_MASK (IPC_RMID
))) {
610 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)uptr
);
611 } else if (second
& IPC_64
) {
613 struct msqid64_ds32
*up
= (struct msqid64_ds32
*)uptr
;
616 if (second
== (IPC_SET
|IPC_64
)) {
617 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
618 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
619 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
620 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
626 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)&m
);
628 if (IPCOP_MASK (second
) &
629 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
630 int err2
= copy_to_user(&up
->msg_perm
, &m
.msg_perm
, sizeof(struct ipc64_perm
) + 3*sizeof(time_t));
631 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
632 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
633 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
634 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
635 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
641 struct msqid_ds32
*up
= (struct msqid_ds32
*)uptr
;
644 if (second
== IPC_SET
) {
645 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
646 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
647 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
648 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
654 err
= sys_msgctl (first
, second
, &m
);
656 if (IPCOP_MASK (second
) &
657 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
658 int err2
= put_user (m
.msg_perm
.key
, &up
->msg_perm
.key
);
659 err2
|= __put_user (high2lowuid(m
.msg_perm
.uid
), &up
->msg_perm
.uid
);
660 err2
|= __put_user (high2lowgid(m
.msg_perm
.gid
), &up
->msg_perm
.gid
);
661 err2
|= __put_user (high2lowuid(m
.msg_perm
.cuid
), &up
->msg_perm
.cuid
);
662 err2
|= __put_user (high2lowgid(m
.msg_perm
.cgid
), &up
->msg_perm
.cgid
);
663 err2
|= __put_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
664 err2
|= __put_user (m
.msg_perm
.seq
, &up
->msg_perm
.seq
);
665 err2
|= __put_user (m
.msg_stime
, &up
->msg_stime
);
666 err2
|= __put_user (m
.msg_rtime
, &up
->msg_rtime
);
667 err2
|= __put_user (m
.msg_ctime
, &up
->msg_ctime
);
668 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
669 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
670 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
671 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
672 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
682 static int do_sys32_shmat (int first
, int second
, int third
, int version
, void *uptr
)
685 u32
*uaddr
= (u32
*)A((u32
)third
);
690 err
= sys_shmat (first
, uptr
, second
, &raddr
);
693 err
= put_user (raddr
, uaddr
);
698 static int do_sys32_shmctl (int first
, int second
, void *uptr
)
702 if (IPCOP_MASK (second
) &
703 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SHM_LOCK
) | IPCOP_MASK (SHM_UNLOCK
) |
704 IPCOP_MASK (IPC_RMID
))) {
705 if (second
== (IPC_INFO
|IPC_64
))
706 second
= IPC_INFO
; /* So that we don't have to translate it */
707 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)uptr
);
708 } else if ((second
& IPC_64
) && second
!= (SHM_INFO
|IPC_64
)) {
710 struct shmid64_ds32
*up
= (struct shmid64_ds32
*)uptr
;
713 if (second
== (IPC_SET
|IPC_64
)) {
714 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
715 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
716 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
722 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)&s
);
727 /* Mask it even in this case so it becomes a CSE. */
728 if (IPCOP_MASK (second
) &
729 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
730 int err2
= copy_to_user (&up
->shm_perm
, &s
.shm_perm
, sizeof(struct ipc64_perm
) + 3*sizeof(time_t));
731 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
732 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
733 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
734 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
740 struct shmid_ds32
*up
= (struct shmid_ds32
*)uptr
;
744 if (second
== IPC_SET
) {
745 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
746 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
747 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
753 err
= sys_shmctl (first
, second
, &s
);
758 /* Mask it even in this case so it becomes a CSE. */
759 if (second
== SHM_INFO
) {
762 u32 shm_tot
, shm_rss
, shm_swp
;
763 u32 swap_attempts
, swap_successes
;
764 } *uip
= (struct shm_info32
*)uptr
;
765 struct shm_info
*kp
= (struct shm_info
*)&s
;
766 int err2
= put_user (kp
->used_ids
, &uip
->used_ids
);
767 err2
|= __put_user (kp
->shm_tot
, &uip
->shm_tot
);
768 err2
|= __put_user (kp
->shm_rss
, &uip
->shm_rss
);
769 err2
|= __put_user (kp
->shm_swp
, &uip
->shm_swp
);
770 err2
|= __put_user (kp
->swap_attempts
, &uip
->swap_attempts
);
771 err2
|= __put_user (kp
->swap_successes
, &uip
->swap_successes
);
774 } else if (IPCOP_MASK (second
) &
775 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
776 int err2
= put_user (s
.shm_perm
.key
, &up
->shm_perm
.key
);
777 err2
|= __put_user (high2lowuid(s
.shm_perm
.uid
), &up
->shm_perm
.uid
);
778 err2
|= __put_user (high2lowuid(s
.shm_perm
.gid
), &up
->shm_perm
.gid
);
779 err2
|= __put_user (high2lowuid(s
.shm_perm
.cuid
), &up
->shm_perm
.cuid
);
780 err2
|= __put_user (high2lowuid(s
.shm_perm
.cgid
), &up
->shm_perm
.cgid
);
781 err2
|= __put_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
782 err2
|= __put_user (s
.shm_perm
.seq
, &up
->shm_perm
.seq
);
783 err2
|= __put_user (s
.shm_atime
, &up
->shm_atime
);
784 err2
|= __put_user (s
.shm_dtime
, &up
->shm_dtime
);
785 err2
|= __put_user (s
.shm_ctime
, &up
->shm_ctime
);
786 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
787 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
788 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
789 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
798 asmlinkage
int sys32_ipc (u32 call
, int first
, int second
, int third
, u32 ptr
, u32 fifth
)
803 version
= call
>> 16; /* hack for backward compatibility */
809 /* struct sembuf is the same on 32 and 64bit :)) */
810 err
= sys_semop (first
, (struct sembuf
*)AA(ptr
), second
);
813 err
= sys_semget (first
, second
, third
);
816 err
= do_sys32_semctl (first
, second
, third
, (void *)AA(ptr
));
825 err
= do_sys32_msgsnd (first
, second
, third
, (void *)AA(ptr
));
828 err
= do_sys32_msgrcv (first
, second
, fifth
, third
,
829 version
, (void *)AA(ptr
));
832 err
= sys_msgget ((key_t
) first
, second
);
835 err
= do_sys32_msgctl (first
, second
, (void *)AA(ptr
));
844 err
= do_sys32_shmat (first
, second
, third
,
845 version
, (void *)AA(ptr
));
848 err
= sys_shmdt ((char *)AA(ptr
));
851 err
= sys_shmget (first
, second
, third
);
854 err
= do_sys32_shmctl (first
, second
, (void *)AA(ptr
));
868 static inline int get_flock(struct flock
*kfl
, struct flock32
*ufl
)
872 err
= get_user(kfl
->l_type
, &ufl
->l_type
);
873 err
|= __get_user(kfl
->l_whence
, &ufl
->l_whence
);
874 err
|= __get_user(kfl
->l_start
, &ufl
->l_start
);
875 err
|= __get_user(kfl
->l_len
, &ufl
->l_len
);
876 err
|= __get_user(kfl
->l_pid
, &ufl
->l_pid
);
880 static inline int put_flock(struct flock
*kfl
, struct flock32
*ufl
)
884 err
= __put_user(kfl
->l_type
, &ufl
->l_type
);
885 err
|= __put_user(kfl
->l_whence
, &ufl
->l_whence
);
886 err
|= __put_user(kfl
->l_start
, &ufl
->l_start
);
887 err
|= __put_user(kfl
->l_len
, &ufl
->l_len
);
888 err
|= __put_user(kfl
->l_pid
, &ufl
->l_pid
);
892 extern asmlinkage
long sys_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
);
894 asmlinkage
long sys32_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
905 if(get_flock(&f
, (struct flock32
*)arg
))
907 old_fs
= get_fs(); set_fs (KERNEL_DS
);
908 ret
= sys_fcntl(fd
, cmd
, (unsigned long)&f
);
910 if(put_flock(&f
, (struct flock32
*)arg
))
915 return sys_fcntl(fd
, cmd
, (unsigned long)arg
);
920 __u32 dqb_bhardlimit
;
921 __u32 dqb_bsoftlimit
;
923 __u32 dqb_ihardlimit
;
924 __u32 dqb_isoftlimit
;
926 __kernel_time_t32 dqb_btime
;
927 __kernel_time_t32 dqb_itime
;
930 extern asmlinkage
int sys_quotactl(int cmd
, const char *special
, int id
, caddr_t addr
);
932 asmlinkage
int sys32_quotactl(int cmd
, const char *special
, int id
, unsigned long addr
)
934 int cmds
= cmd
>> SUBCMDSHIFT
;
946 if (copy_from_user (&d
, (struct dqblk32
*)addr
,
947 sizeof (struct dqblk32
)))
949 d
.dqb_itime
= ((struct dqblk32
*)&d
)->dqb_itime
;
950 d
.dqb_btime
= ((struct dqblk32
*)&d
)->dqb_btime
;
953 return sys_quotactl(cmd
, special
,
956 spec
= getname32 (special
);
958 if (IS_ERR(spec
)) return err
;
961 err
= sys_quotactl(cmd
, (const char *)spec
, id
, (caddr_t
)&d
);
964 if (cmds
== Q_GETQUOTA
) {
965 __kernel_time_t b
= d
.dqb_btime
, i
= d
.dqb_itime
;
966 ((struct dqblk32
*)&d
)->dqb_itime
= i
;
967 ((struct dqblk32
*)&d
)->dqb_btime
= b
;
968 if (copy_to_user ((struct dqblk32
*)addr
, &d
,
969 sizeof (struct dqblk32
)))
975 static inline int put_statfs (struct statfs32
*ubuf
, struct statfs
*kbuf
)
979 err
= put_user (kbuf
->f_type
, &ubuf
->f_type
);
980 err
|= __put_user (kbuf
->f_bsize
, &ubuf
->f_bsize
);
981 err
|= __put_user (kbuf
->f_blocks
, &ubuf
->f_blocks
);
982 err
|= __put_user (kbuf
->f_bfree
, &ubuf
->f_bfree
);
983 err
|= __put_user (kbuf
->f_bavail
, &ubuf
->f_bavail
);
984 err
|= __put_user (kbuf
->f_files
, &ubuf
->f_files
);
985 err
|= __put_user (kbuf
->f_ffree
, &ubuf
->f_ffree
);
986 err
|= __put_user (kbuf
->f_namelen
, &ubuf
->f_namelen
);
987 err
|= __put_user (kbuf
->f_fsid
.val
[0], &ubuf
->f_fsid
.val
[0]);
988 err
|= __put_user (kbuf
->f_fsid
.val
[1], &ubuf
->f_fsid
.val
[1]);
992 extern asmlinkage
int sys_statfs(const char * path
, struct statfs
* buf
);
994 asmlinkage
int sys32_statfs(const char * path
, struct statfs32
*buf
)
998 mm_segment_t old_fs
= get_fs();
1001 pth
= getname32 (path
);
1005 ret
= sys_statfs((const char *)pth
, &s
);
1008 if (put_statfs(buf
, &s
))
1014 extern asmlinkage
int sys_fstatfs(unsigned int fd
, struct statfs
* buf
);
1016 asmlinkage
int sys32_fstatfs(unsigned int fd
, struct statfs32
*buf
)
1020 mm_segment_t old_fs
= get_fs();
1023 ret
= sys_fstatfs(fd
, &s
);
1025 if (put_statfs(buf
, &s
))
1030 extern asmlinkage
long sys_truncate(const char * path
, unsigned long length
);
1031 extern asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
);
1033 asmlinkage
int sys32_truncate64(const char * path
, unsigned long high
, unsigned long low
)
1038 return sys_truncate(path
, (high
<< 32) | low
);
1041 asmlinkage
int sys32_ftruncate64(unsigned int fd
, unsigned long high
, unsigned long low
)
1046 return sys_ftruncate(fd
, (high
<< 32) | low
);
1049 extern asmlinkage
int sys_utime(char * filename
, struct utimbuf
* times
);
1052 __kernel_time_t32 actime
, modtime
;
1055 asmlinkage
int sys32_utime(char * filename
, struct utimbuf32
*times
)
1058 mm_segment_t old_fs
;
1063 return sys_utime(filename
, NULL
);
1064 if (get_user (t
.actime
, ×
->actime
) ||
1065 __get_user (t
.modtime
, ×
->modtime
))
1067 filenam
= getname32 (filename
);
1068 ret
= PTR_ERR(filenam
);
1069 if (!IS_ERR(filenam
)) {
1072 ret
= sys_utime(filenam
, &t
);
1079 struct iovec32
{ u32 iov_base
; __kernel_size_t32 iov_len
; };
1081 typedef ssize_t (*IO_fn_t
)(struct file
*, char *, size_t, loff_t
*);
1083 static long do_readv_writev32(int type
, struct file
*file
,
1084 const struct iovec32
*vector
, u32 count
)
1086 unsigned long tot_len
;
1087 struct iovec iovstack
[UIO_FASTIOV
];
1088 struct iovec
*iov
=iovstack
, *ivp
;
1089 struct inode
*inode
;
1093 /* First get the "struct iovec" from user memory and
1094 * verify all the pointers
1098 if(verify_area(VERIFY_READ
, vector
, sizeof(struct iovec32
)*count
))
1100 if (count
> UIO_MAXIOV
)
1102 if (count
> UIO_FASTIOV
) {
1103 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
1115 __get_user(len
, &vector
->iov_len
);
1116 __get_user(buf
, &vector
->iov_base
);
1118 ivp
->iov_base
= (void *)A(buf
);
1119 ivp
->iov_len
= (__kernel_size_t
) len
;
1125 inode
= file
->f_dentry
->d_inode
;
1126 /* VERIFY_WRITE actually means a read, as we write to user space */
1127 retval
= locks_verify_area((type
== VERIFY_WRITE
1128 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
1129 inode
, file
, file
->f_pos
, tot_len
);
1131 if (iov
!= iovstack
)
1136 /* Then do the actual IO. Note that sockets need to be handled
1137 * specially as they have atomicity guarantees and can handle
1140 if (inode
->i_sock
) {
1142 err
= sock_readv_writev(type
, inode
, file
, iov
, count
, tot_len
);
1143 if (iov
!= iovstack
)
1149 if (iov
!= iovstack
)
1153 /* VERIFY_WRITE actually means a read, as we write to user space */
1154 fn
= file
->f_op
->read
;
1155 if (type
== VERIFY_READ
)
1156 fn
= (IO_fn_t
) file
->f_op
->write
;
1162 base
= ivp
->iov_base
;
1166 nr
= fn(file
, base
, len
, &file
->f_pos
);
1177 if (iov
!= iovstack
)
1182 asmlinkage
long sys32_readv(int fd
, struct iovec32
*vector
, u32 count
)
1193 if (file
->f_op
&& file
->f_op
->read
&& (file
->f_mode
& FMODE_READ
))
1194 ret
= do_readv_writev32(VERIFY_WRITE
, file
, vector
, count
);
1202 asmlinkage
long sys32_writev(int fd
, struct iovec32
*vector
, u32 count
)
1212 if (file
->f_op
&& file
->f_op
->write
&& (file
->f_mode
& FMODE_WRITE
))
1213 ret
= do_readv_writev32(VERIFY_READ
, file
, vector
, count
);
1221 /* readdir & getdents */
1223 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1224 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1226 struct old_linux_dirent32
{
1229 unsigned short d_namlen
;
1233 struct readdir_callback32
{
1234 struct old_linux_dirent32
* dirent
;
1238 static int fillonedir(void * __buf
, const char * name
, int namlen
,
1239 off_t offset
, ino_t ino
)
1241 struct readdir_callback32
* buf
= (struct readdir_callback32
*) __buf
;
1242 struct old_linux_dirent32
* dirent
;
1247 dirent
= buf
->dirent
;
1248 put_user(ino
, &dirent
->d_ino
);
1249 put_user(offset
, &dirent
->d_offset
);
1250 put_user(namlen
, &dirent
->d_namlen
);
1251 copy_to_user(dirent
->d_name
, name
, namlen
);
1252 put_user(0, dirent
->d_name
+ namlen
);
1256 asmlinkage
int old32_readdir(unsigned int fd
, struct old_linux_dirent32
*dirent
, unsigned int count
)
1260 struct readdir_callback32 buf
;
1267 buf
.dirent
= dirent
;
1270 error
= vfs_readdir(file
, fillonedir
, &buf
);
1282 struct linux_dirent32
{
1285 unsigned short d_reclen
;
1289 struct getdents_callback32
{
1290 struct linux_dirent32
* current_dir
;
1291 struct linux_dirent32
* previous
;
1296 static int filldir(void * __buf
, const char * name
, int namlen
, off_t offset
, ino_t ino
)
1298 struct linux_dirent32
* dirent
;
1299 struct getdents_callback32
* buf
= (struct getdents_callback32
*) __buf
;
1300 int reclen
= ROUND_UP(NAME_OFFSET(dirent
) + namlen
+ 1);
1302 buf
->error
= -EINVAL
; /* only used if we fail.. */
1303 if (reclen
> buf
->count
)
1305 dirent
= buf
->previous
;
1307 put_user(offset
, &dirent
->d_off
);
1308 dirent
= buf
->current_dir
;
1309 buf
->previous
= dirent
;
1310 put_user(ino
, &dirent
->d_ino
);
1311 put_user(reclen
, &dirent
->d_reclen
);
1312 copy_to_user(dirent
->d_name
, name
, namlen
);
1313 put_user(0, dirent
->d_name
+ namlen
);
1314 ((char *) dirent
) += reclen
;
1315 buf
->current_dir
= dirent
;
1316 buf
->count
-= reclen
;
1320 asmlinkage
int sys32_getdents(unsigned int fd
, struct linux_dirent32
*dirent
, unsigned int count
)
1323 struct linux_dirent32
* lastdirent
;
1324 struct getdents_callback32 buf
;
1331 buf
.current_dir
= dirent
;
1332 buf
.previous
= NULL
;
1337 error
= vfs_readdir(file
, filldir
, &buf
);
1340 lastdirent
= buf
.previous
;
1343 put_user(file
->f_pos
, &lastdirent
->d_off
);
1344 error
= count
- buf
.count
;
1353 /* end of readdir & getdents */
1356 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1357 * 64-bit unsigned longs.
1361 get_fd_set32(unsigned long n
, unsigned long *fdset
, u32
*ufdset
)
1366 if (verify_area(VERIFY_WRITE
, ufdset
, n
*sizeof(u32
)))
1373 __get_user(l
, ufdset
);
1374 __get_user(h
, ufdset
+1);
1376 *fdset
++ = h
<< 32 | l
;
1380 __get_user(*fdset
, ufdset
);
1382 /* Tricky, must clear full unsigned long in the
1383 * kernel fdset at the end, this makes sure that
1386 memset(fdset
, 0, ((n
+ 1) & ~1)*sizeof(u32
));
1392 set_fd_set32(unsigned long n
, u32
*ufdset
, unsigned long *fdset
)
1405 __put_user(l
, ufdset
);
1406 __put_user(h
, ufdset
+1);
1411 __put_user(*fdset
, ufdset
);
1414 #define MAX_SELECT_SECONDS \
1415 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1417 asmlinkage
int sys32_select(int n
, u32
*inp
, u32
*outp
, u32
*exp
, u32 tvp_x
)
1420 struct timeval32
*tvp
= (struct timeval32
*)AA(tvp_x
);
1426 timeout
= MAX_SCHEDULE_TIMEOUT
;
1430 if ((ret
= verify_area(VERIFY_READ
, tvp
, sizeof(*tvp
)))
1431 || (ret
= __get_user(sec
, &tvp
->tv_sec
))
1432 || (ret
= __get_user(usec
, &tvp
->tv_usec
)))
1436 if(sec
< 0 || usec
< 0)
1439 if ((unsigned long) sec
< MAX_SELECT_SECONDS
) {
1440 timeout
= (usec
+ 1000000/HZ
- 1) / (1000000/HZ
);
1441 timeout
+= sec
* (unsigned long) HZ
;
1448 if (n
> current
->files
->max_fdset
)
1449 n
= current
->files
->max_fdset
;
1452 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1453 * since we used fdset we need to allocate memory in units of
1457 size
= FDS_BYTES(n
);
1458 bits
= kmalloc(6 * size
, GFP_KERNEL
);
1461 fds
.in
= (unsigned long *) bits
;
1462 fds
.out
= (unsigned long *) (bits
+ size
);
1463 fds
.ex
= (unsigned long *) (bits
+ 2*size
);
1464 fds
.res_in
= (unsigned long *) (bits
+ 3*size
);
1465 fds
.res_out
= (unsigned long *) (bits
+ 4*size
);
1466 fds
.res_ex
= (unsigned long *) (bits
+ 5*size
);
1468 nn
= (n
+ 8*sizeof(u32
) - 1) / (8*sizeof(u32
));
1469 if ((ret
= get_fd_set32(nn
, fds
.in
, inp
)) ||
1470 (ret
= get_fd_set32(nn
, fds
.out
, outp
)) ||
1471 (ret
= get_fd_set32(nn
, fds
.ex
, exp
)))
1473 zero_fd_set(n
, fds
.res_in
);
1474 zero_fd_set(n
, fds
.res_out
);
1475 zero_fd_set(n
, fds
.res_ex
);
1477 ret
= do_select(n
, &fds
, &timeout
);
1479 if (tvp
&& !(current
->personality
& STICKY_TIMEOUTS
)) {
1480 time_t sec
= 0, usec
= 0;
1483 usec
= timeout
% HZ
;
1484 usec
*= (1000000/HZ
);
1486 put_user(sec
, &tvp
->tv_sec
);
1487 put_user(usec
, &tvp
->tv_usec
);
1493 ret
= -ERESTARTNOHAND
;
1494 if (signal_pending(current
))
1499 set_fd_set32(nn
, inp
, fds
.res_in
);
1500 set_fd_set32(nn
, outp
, fds
.res_out
);
1501 set_fd_set32(nn
, exp
, fds
.res_ex
);
1509 static int cp_new_stat32(struct inode
*inode
, struct stat32
*statbuf
)
1511 unsigned long ino
, blksize
, blocks
;
1518 time_t atime
, mtime
, ctime
;
1521 /* Stream the loads of inode data into the load buffer,
1522 * then we push it all into the store buffer below. This
1523 * should give optimal cache performance.
1527 mode
= inode
->i_mode
;
1528 nlink
= inode
->i_nlink
;
1531 rdev
= inode
->i_rdev
;
1532 size
= inode
->i_size
;
1533 atime
= inode
->i_atime
;
1534 mtime
= inode
->i_mtime
;
1535 ctime
= inode
->i_ctime
;
1536 blksize
= inode
->i_blksize
;
1537 blocks
= inode
->i_blocks
;
1539 err
= put_user(kdev_t_to_nr(dev
), &statbuf
->st_dev
);
1540 err
|= put_user(ino
, &statbuf
->st_ino
);
1541 err
|= put_user(mode
, &statbuf
->st_mode
);
1542 err
|= put_user(nlink
, &statbuf
->st_nlink
);
1543 err
|= put_user(high2lowuid(uid
), &statbuf
->st_uid
);
1544 err
|= put_user(high2lowgid(gid
), &statbuf
->st_gid
);
1545 err
|= put_user(kdev_t_to_nr(rdev
), &statbuf
->st_rdev
);
1546 err
|= put_user(size
, &statbuf
->st_size
);
1547 err
|= put_user(atime
, &statbuf
->st_atime
);
1548 err
|= put_user(0, &statbuf
->__unused1
);
1549 err
|= put_user(mtime
, &statbuf
->st_mtime
);
1550 err
|= put_user(0, &statbuf
->__unused2
);
1551 err
|= put_user(ctime
, &statbuf
->st_ctime
);
1552 err
|= put_user(0, &statbuf
->__unused3
);
1554 err
|= put_user(blksize
, &statbuf
->st_blksize
);
1555 err
|= put_user(blocks
, &statbuf
->st_blocks
);
1557 unsigned int tmp_blocks
;
1560 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
1561 tmp_blocks
= (size
+ BLOCK_SIZE
- 1) / BLOCK_SIZE
;
1562 if (tmp_blocks
> D_B
) {
1563 unsigned int indirect
;
1565 indirect
= (tmp_blocks
- D_B
+ I_B
- 1) / I_B
;
1566 tmp_blocks
+= indirect
;
1568 indirect
= (indirect
- 1 + I_B
- 1) / I_B
;
1569 tmp_blocks
+= indirect
;
1574 err
|= put_user(BLOCK_SIZE
, &statbuf
->st_blksize
);
1575 err
|= put_user((BLOCK_SIZE
/ 512) * tmp_blocks
, &statbuf
->st_blocks
);
1579 err
|= put_user(0, &statbuf
->__unused4
[0]);
1580 err
|= put_user(0, &statbuf
->__unused4
[1]);
1585 asmlinkage
int sys32_newstat(char * filename
, struct stat32
*statbuf
)
1587 struct nameidata nd
;
1591 error
= user_path_walk(filename
, &nd
);
1593 struct inode
*inode
= nd
.dentry
->d_inode
;
1596 inode
->i_op
->revalidate
)
1597 error
= inode
->i_op
->revalidate(nd
.dentry
);
1601 error
= cp_new_stat32(inode
, statbuf
);
1609 asmlinkage
int sys32_newlstat(char * filename
, struct stat32
*statbuf
)
1611 struct nameidata nd
;
1615 error
= user_path_walk_link(filename
, &nd
);
1617 struct inode
*inode
= nd
.dentry
->d_inode
;
1620 inode
->i_op
->revalidate
)
1621 error
= inode
->i_op
->revalidate(nd
.dentry
);
1625 error
= cp_new_stat32(inode
, statbuf
);
1633 asmlinkage
int sys32_newfstat(unsigned int fd
, struct stat32
*statbuf
)
1641 struct dentry
*dentry
= f
->f_dentry
;
1642 struct inode
*inode
= dentry
->d_inode
;
1645 inode
->i_op
->revalidate
)
1646 err
= inode
->i_op
->revalidate(dentry
);
1650 err
= cp_new_stat32(inode
, statbuf
);
1658 extern asmlinkage
int sys_sysfs(int option
, unsigned long arg1
, unsigned long arg2
);
1660 asmlinkage
int sys32_sysfs(int option
, u32 arg1
, u32 arg2
)
1662 return sys_sysfs(option
, arg1
, arg2
);
1665 struct ncp_mount_data32
{
1667 unsigned int ncp_fd
;
1668 __kernel_uid_t32 mounted_uid
;
1669 __kernel_pid_t32 wdog_pid
;
1670 unsigned char mounted_vol
[NCP_VOLNAME_LEN
+ 1];
1671 unsigned int time_out
;
1672 unsigned int retry_count
;
1674 __kernel_uid_t32 uid
;
1675 __kernel_gid_t32 gid
;
1676 __kernel_mode_t32 file_mode
;
1677 __kernel_mode_t32 dir_mode
;
1680 static void *do_ncp_super_data_conv(void *raw_data
)
1682 struct ncp_mount_data
*n
= (struct ncp_mount_data
*)raw_data
;
1683 struct ncp_mount_data32
*n32
= (struct ncp_mount_data32
*)raw_data
;
1685 n
->dir_mode
= n32
->dir_mode
;
1686 n
->file_mode
= n32
->file_mode
;
1687 n
->gid
= low2highgid(n32
->gid
);
1688 n
->uid
= low2highuid(n32
->uid
);
1689 memmove (n
->mounted_vol
, n32
->mounted_vol
, (sizeof (n32
->mounted_vol
) + 3 * sizeof (unsigned int)));
1690 n
->wdog_pid
= n32
->wdog_pid
;
1691 n
->mounted_uid
= low2highuid(n32
->mounted_uid
);
1695 struct smb_mount_data32
{
1697 __kernel_uid_t32 mounted_uid
;
1698 __kernel_uid_t32 uid
;
1699 __kernel_gid_t32 gid
;
1700 __kernel_mode_t32 file_mode
;
1701 __kernel_mode_t32 dir_mode
;
1704 static void *do_smb_super_data_conv(void *raw_data
)
1706 struct smb_mount_data
*s
= (struct smb_mount_data
*)raw_data
;
1707 struct smb_mount_data32
*s32
= (struct smb_mount_data32
*)raw_data
;
1709 s
->version
= s32
->version
;
1710 s
->mounted_uid
= low2highuid(s32
->mounted_uid
);
1711 s
->uid
= low2highuid(s32
->uid
);
1712 s
->gid
= low2highgid(s32
->gid
);
1713 s
->file_mode
= s32
->file_mode
;
1714 s
->dir_mode
= s32
->dir_mode
;
1718 static int copy_mount_stuff_to_kernel(const void *user
, unsigned long *kernel
)
1722 struct vm_area_struct
*vma
;
1727 vma
= find_vma(current
->mm
, (unsigned long)user
);
1728 if(!vma
|| (unsigned long)user
< vma
->vm_start
)
1730 if(!(vma
->vm_flags
& VM_READ
))
1732 i
= vma
->vm_end
- (unsigned long) user
;
1733 if(PAGE_SIZE
<= (unsigned long) i
)
1735 if(!(page
= __get_free_page(GFP_KERNEL
)))
1737 if(copy_from_user((void *) page
, user
, i
)) {
1745 #define SMBFS_NAME "smbfs"
1746 #define NCPFS_NAME "ncpfs"
1748 asmlinkage
int sys32_mount(char *dev_name
, char *dir_name
, char *type
, unsigned long new_flags
, u32 data
)
1750 unsigned long type_page
= 0;
1751 unsigned long data_page
= 0;
1752 unsigned long dev_page
= 0;
1753 unsigned long dir_page
= 0;
1754 int err
, is_smb
, is_ncp
;
1756 is_smb
= is_ncp
= 0;
1759 err
= copy_mount_stuff_to_kernel((const void *)type
, &type_page
);
1768 is_smb
= !strcmp((char *)type_page
, SMBFS_NAME
);
1769 is_ncp
= !strcmp((char *)type_page
, NCPFS_NAME
);
1771 err
= copy_mount_stuff_to_kernel((const void *)AA(data
), &data_page
);
1775 err
= copy_mount_stuff_to_kernel(dev_name
, &dev_page
);
1779 err
= copy_mount_stuff_to_kernel(dir_name
, &dir_page
);
1783 if (!is_smb
&& !is_ncp
) {
1784 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1785 (char*)type_page
, new_flags
, (char*)data_page
);
1788 do_ncp_super_data_conv((void *)data_page
);
1790 do_smb_super_data_conv((void *)data_page
);
1792 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1793 (char*)type_page
, new_flags
, (char*)data_page
);
1795 free_page(dir_page
);
1798 free_page(dev_page
);
1801 free_page(data_page
);
1804 free_page(type_page
);
1812 struct timeval32 ru_utime
;
1813 struct timeval32 ru_stime
;
1830 static int put_rusage (struct rusage32
*ru
, struct rusage
*r
)
1834 err
= put_user (r
->ru_utime
.tv_sec
, &ru
->ru_utime
.tv_sec
);
1835 err
|= __put_user (r
->ru_utime
.tv_usec
, &ru
->ru_utime
.tv_usec
);
1836 err
|= __put_user (r
->ru_stime
.tv_sec
, &ru
->ru_stime
.tv_sec
);
1837 err
|= __put_user (r
->ru_stime
.tv_usec
, &ru
->ru_stime
.tv_usec
);
1838 err
|= __put_user (r
->ru_maxrss
, &ru
->ru_maxrss
);
1839 err
|= __put_user (r
->ru_ixrss
, &ru
->ru_ixrss
);
1840 err
|= __put_user (r
->ru_idrss
, &ru
->ru_idrss
);
1841 err
|= __put_user (r
->ru_isrss
, &ru
->ru_isrss
);
1842 err
|= __put_user (r
->ru_minflt
, &ru
->ru_minflt
);
1843 err
|= __put_user (r
->ru_majflt
, &ru
->ru_majflt
);
1844 err
|= __put_user (r
->ru_nswap
, &ru
->ru_nswap
);
1845 err
|= __put_user (r
->ru_inblock
, &ru
->ru_inblock
);
1846 err
|= __put_user (r
->ru_oublock
, &ru
->ru_oublock
);
1847 err
|= __put_user (r
->ru_msgsnd
, &ru
->ru_msgsnd
);
1848 err
|= __put_user (r
->ru_msgrcv
, &ru
->ru_msgrcv
);
1849 err
|= __put_user (r
->ru_nsignals
, &ru
->ru_nsignals
);
1850 err
|= __put_user (r
->ru_nvcsw
, &ru
->ru_nvcsw
);
1851 err
|= __put_user (r
->ru_nivcsw
, &ru
->ru_nivcsw
);
1855 extern asmlinkage
int sys_wait4(pid_t pid
,unsigned int * stat_addr
,
1856 int options
, struct rusage
* ru
);
1858 asmlinkage
int sys32_wait4(__kernel_pid_t32 pid
, unsigned int *stat_addr
, int options
, struct rusage32
*ru
)
1861 return sys_wait4(pid
, stat_addr
, options
, NULL
);
1865 unsigned int status
;
1866 mm_segment_t old_fs
= get_fs();
1869 ret
= sys_wait4(pid
, stat_addr
? &status
: NULL
, options
, &r
);
1871 if (put_rusage (ru
, &r
)) return -EFAULT
;
1872 if (stat_addr
&& put_user (status
, stat_addr
))
1887 unsigned short procs
;
1891 extern asmlinkage
int sys_sysinfo(struct sysinfo
*info
);
1893 asmlinkage
int sys32_sysinfo(struct sysinfo32
*info
)
1897 mm_segment_t old_fs
= get_fs ();
1900 ret
= sys_sysinfo(&s
);
1902 err
= put_user (s
.uptime
, &info
->uptime
);
1903 err
|= __put_user (s
.loads
[0], &info
->loads
[0]);
1904 err
|= __put_user (s
.loads
[1], &info
->loads
[1]);
1905 err
|= __put_user (s
.loads
[2], &info
->loads
[2]);
1906 err
|= __put_user (s
.totalram
, &info
->totalram
);
1907 err
|= __put_user (s
.freeram
, &info
->freeram
);
1908 err
|= __put_user (s
.sharedram
, &info
->sharedram
);
1909 err
|= __put_user (s
.bufferram
, &info
->bufferram
);
1910 err
|= __put_user (s
.totalswap
, &info
->totalswap
);
1911 err
|= __put_user (s
.freeswap
, &info
->freeswap
);
1912 err
|= __put_user (s
.procs
, &info
->procs
);
1923 extern asmlinkage
int sys_sched_rr_get_interval(pid_t pid
, struct timespec
*interval
);
1925 asmlinkage
int sys32_sched_rr_get_interval(__kernel_pid_t32 pid
, struct timespec32
*interval
)
1929 mm_segment_t old_fs
= get_fs ();
1932 ret
= sys_sched_rr_get_interval(pid
, &t
);
1934 if (put_user (t
.tv_sec
, &interval
->tv_sec
) ||
1935 __put_user (t
.tv_nsec
, &interval
->tv_nsec
))
1940 extern asmlinkage
int sys_nanosleep(struct timespec
*rqtp
, struct timespec
*rmtp
);
1942 asmlinkage
int sys32_nanosleep(struct timespec32
*rqtp
, struct timespec32
*rmtp
)
1946 mm_segment_t old_fs
= get_fs ();
1948 if (get_user (t
.tv_sec
, &rqtp
->tv_sec
) ||
1949 __get_user (t
.tv_nsec
, &rqtp
->tv_nsec
))
1952 ret
= sys_nanosleep(&t
, rmtp
? &t
: NULL
);
1954 if (rmtp
&& ret
== -EINTR
) {
1955 if (__put_user (t
.tv_sec
, &rmtp
->tv_sec
) ||
1956 __put_user (t
.tv_nsec
, &rmtp
->tv_nsec
))
1962 extern asmlinkage
int sys_sigprocmask(int how
, old_sigset_t
*set
, old_sigset_t
*oset
);
1964 asmlinkage
int sys32_sigprocmask(int how
, old_sigset_t32
*set
, old_sigset_t32
*oset
)
1968 mm_segment_t old_fs
= get_fs();
1970 if (set
&& get_user (s
, set
)) return -EFAULT
;
1972 ret
= sys_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
);
1974 if (ret
) return ret
;
1975 if (oset
&& put_user (s
, oset
)) return -EFAULT
;
1979 extern asmlinkage
int sys_rt_sigprocmask(int how
, sigset_t
*set
, sigset_t
*oset
, size_t sigsetsize
);
1981 asmlinkage
int sys32_rt_sigprocmask(int how
, sigset_t32
*set
, sigset_t32
*oset
, __kernel_size_t32 sigsetsize
)
1986 mm_segment_t old_fs
= get_fs();
1989 if (copy_from_user (&s32
, set
, sizeof(sigset_t32
)))
1991 switch (_NSIG_WORDS
) {
1992 case 4: s
.sig
[3] = s32
.sig
[6] | (((long)s32
.sig
[7]) << 32);
1993 case 3: s
.sig
[2] = s32
.sig
[4] | (((long)s32
.sig
[5]) << 32);
1994 case 2: s
.sig
[1] = s32
.sig
[2] | (((long)s32
.sig
[3]) << 32);
1995 case 1: s
.sig
[0] = s32
.sig
[0] | (((long)s32
.sig
[1]) << 32);
1999 ret
= sys_rt_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
, sigsetsize
);
2001 if (ret
) return ret
;
2003 switch (_NSIG_WORDS
) {
2004 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
2005 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
2006 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
2007 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
2009 if (copy_to_user (oset
, &s32
, sizeof(sigset_t32
)))
2015 extern asmlinkage
int sys_sigpending(old_sigset_t
*set
);
2017 asmlinkage
int sys32_sigpending(old_sigset_t32
*set
)
2021 mm_segment_t old_fs
= get_fs();
2024 ret
= sys_sigpending(&s
);
2026 if (put_user (s
, set
)) return -EFAULT
;
2030 extern asmlinkage
int sys_rt_sigpending(sigset_t
*set
, size_t sigsetsize
);
2032 asmlinkage
int sys32_rt_sigpending(sigset_t32
*set
, __kernel_size_t32 sigsetsize
)
2037 mm_segment_t old_fs
= get_fs();
2040 ret
= sys_rt_sigpending(&s
, sigsetsize
);
2043 switch (_NSIG_WORDS
) {
2044 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
2045 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
2046 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
2047 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
2049 if (copy_to_user (set
, &s32
, sizeof(sigset_t32
)))
2056 sys32_rt_sigtimedwait(sigset_t32
*uthese
, siginfo_t32
*uinfo
,
2057 struct timespec32
*uts
, __kernel_size_t32 sigsetsize
)
2066 /* XXX: Don't preclude handling different sized sigset_t's. */
2067 if (sigsetsize
!= sizeof(sigset_t
))
2070 if (copy_from_user (&these32
, uthese
, sizeof(sigset_t32
)))
2073 switch (_NSIG_WORDS
) {
2074 case 4: these
.sig
[3] = these32
.sig
[6] | (((long)these32
.sig
[7]) << 32);
2075 case 3: these
.sig
[2] = these32
.sig
[4] | (((long)these32
.sig
[5]) << 32);
2076 case 2: these
.sig
[1] = these32
.sig
[2] | (((long)these32
.sig
[3]) << 32);
2077 case 1: these
.sig
[0] = these32
.sig
[0] | (((long)these32
.sig
[1]) << 32);
2081 * Invert the set of allowed signals to get those we
2084 sigdelsetmask(&these
, sigmask(SIGKILL
)|sigmask(SIGSTOP
));
2088 if (get_user (ts
.tv_sec
, &uts
->tv_sec
) ||
2089 get_user (ts
.tv_nsec
, &uts
->tv_nsec
))
2091 if (ts
.tv_nsec
>= 1000000000L || ts
.tv_nsec
< 0
2096 spin_lock_irq(¤t
->sigmask_lock
);
2097 sig
= dequeue_signal(&these
, &info
);
2099 /* None ready -- temporarily unblock those we're interested
2100 in so that we'll be awakened when they arrive. */
2101 sigset_t oldblocked
= current
->blocked
;
2102 sigandsets(¤t
->blocked
, ¤t
->blocked
, &these
);
2103 recalc_sigpending(current
);
2104 spin_unlock_irq(¤t
->sigmask_lock
);
2106 timeout
= MAX_SCHEDULE_TIMEOUT
;
2108 timeout
= (timespec_to_jiffies(&ts
)
2109 + (ts
.tv_sec
|| ts
.tv_nsec
));
2111 current
->state
= TASK_INTERRUPTIBLE
;
2112 timeout
= schedule_timeout(timeout
);
2114 spin_lock_irq(¤t
->sigmask_lock
);
2115 sig
= dequeue_signal(&these
, &info
);
2116 current
->blocked
= oldblocked
;
2117 recalc_sigpending(current
);
2119 spin_unlock_irq(¤t
->sigmask_lock
);
2124 if (copy_siginfo_to_user32(uinfo
, &info
))
2136 extern asmlinkage
int
2137 sys_rt_sigqueueinfo(int pid
, int sig
, siginfo_t
*uinfo
);
2140 sys32_rt_sigqueueinfo(int pid
, int sig
, siginfo_t32
*uinfo
)
2144 mm_segment_t old_fs
= get_fs();
2146 if (copy_from_user (&info
, uinfo
, 3*sizeof(int)) ||
2147 copy_from_user (info
._sifields
._pad
, uinfo
->_sifields
._pad
, SI_PAD_SIZE
))
2150 ret
= sys_rt_sigqueueinfo(pid
, sig
, &info
);
2156 __kernel_clock_t32 tms_utime
;
2157 __kernel_clock_t32 tms_stime
;
2158 __kernel_clock_t32 tms_cutime
;
2159 __kernel_clock_t32 tms_cstime
;
2162 extern asmlinkage
long sys_times(struct tms
* tbuf
);
2164 asmlinkage
long sys32_times(struct tms32
*tbuf
)
2168 mm_segment_t old_fs
= get_fs ();
2172 ret
= sys_times(tbuf
? &t
: NULL
);
2175 err
= put_user (t
.tms_utime
, &tbuf
->tms_utime
);
2176 err
|= __put_user (t
.tms_stime
, &tbuf
->tms_stime
);
2177 err
|= __put_user (t
.tms_cutime
, &tbuf
->tms_cutime
);
2178 err
|= __put_user (t
.tms_cstime
, &tbuf
->tms_cstime
);
2185 #define RLIM_INFINITY32 0x7fffffff
2186 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2193 extern asmlinkage
int sys_getrlimit(unsigned int resource
, struct rlimit
*rlim
);
2195 asmlinkage
int sys32_getrlimit(unsigned int resource
, struct rlimit32
*rlim
)
2199 mm_segment_t old_fs
= get_fs ();
2202 ret
= sys_getrlimit(resource
, &r
);
2205 ret
= put_user (RESOURCE32(r
.rlim_cur
), &rlim
->rlim_cur
);
2206 ret
|= __put_user (RESOURCE32(r
.rlim_max
), &rlim
->rlim_max
);
2211 extern asmlinkage
int sys_setrlimit(unsigned int resource
, struct rlimit
*rlim
);
2213 asmlinkage
int sys32_setrlimit(unsigned int resource
, struct rlimit32
*rlim
)
2217 mm_segment_t old_fs
= get_fs ();
2219 if (resource
>= RLIM_NLIMITS
) return -EINVAL
;
2220 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
2221 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
2223 if (r
.rlim_cur
== RLIM_INFINITY32
)
2224 r
.rlim_cur
= RLIM_INFINITY
;
2225 if (r
.rlim_max
== RLIM_INFINITY32
)
2226 r
.rlim_max
= RLIM_INFINITY
;
2228 ret
= sys_setrlimit(resource
, &r
);
2233 extern asmlinkage
int sys_getrusage(int who
, struct rusage
*ru
);
2235 asmlinkage
int sys32_getrusage(int who
, struct rusage32
*ru
)
2239 mm_segment_t old_fs
= get_fs();
2242 ret
= sys_getrusage(who
, &r
);
2244 if (put_rusage (ru
, &r
)) return -EFAULT
;
2248 /* XXX This really belongs in some header file... -DaveM */
2249 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2250 16 for IP, 16 for IPX,
2252 about 80 for AX.25 */
2254 /* XXX These as well... */
2255 extern __inline__
struct socket
*socki_lookup(struct inode
*inode
)
2257 return &inode
->u
.socket_i
;
2260 extern __inline__
struct socket
*sockfd_lookup(int fd
, int *err
)
2263 struct inode
*inode
;
2265 if (!(file
= fget(fd
)))
2271 inode
= file
->f_dentry
->d_inode
;
2272 if (!inode
|| !inode
->i_sock
|| !socki_lookup(inode
))
2279 return socki_lookup(inode
);
2282 extern __inline__
void sockfd_put(struct socket
*sock
)
2291 __kernel_size_t32 msg_iovlen
;
2293 __kernel_size_t32 msg_controllen
;
2298 __kernel_size_t32 cmsg_len
;
2304 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2305 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2307 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2309 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2310 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2311 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2313 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2314 (struct cmsghdr32 *)(ctl) : \
2315 (struct cmsghdr32 *)NULL)
2316 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2318 __inline__
struct cmsghdr32
*__cmsg32_nxthdr(void *__ctl
, __kernel_size_t __size
,
2319 struct cmsghdr32
*__cmsg
, int __cmsg_len
)
2321 struct cmsghdr32
* __ptr
;
2323 __ptr
= (struct cmsghdr32
*)(((unsigned char *) __cmsg
) +
2324 CMSG32_ALIGN(__cmsg_len
));
2325 if ((unsigned long)((char*)(__ptr
+1) - (char *) __ctl
) > __size
)
2331 __inline__
struct cmsghdr32
*cmsg32_nxthdr (struct msghdr
*__msg
,
2332 struct cmsghdr32
*__cmsg
,
2335 return __cmsg32_nxthdr(__msg
->msg_control
, __msg
->msg_controllen
,
2336 __cmsg
, __cmsg_len
);
2339 static inline int iov_from_user32_to_kern(struct iovec
*kiov
,
2340 struct iovec32
*uiov32
,
2348 if(get_user(len
, &uiov32
->iov_len
) ||
2349 get_user(buf
, &uiov32
->iov_base
)) {
2354 kiov
->iov_base
= (void *)A(buf
);
2355 kiov
->iov_len
= (__kernel_size_t
) len
;
2363 static inline int msghdr_from_user32_to_kern(struct msghdr
*kmsg
,
2364 struct msghdr32
*umsg
)
2366 u32 tmp1
, tmp2
, tmp3
;
2369 err
= get_user(tmp1
, &umsg
->msg_name
);
2370 err
|= __get_user(tmp2
, &umsg
->msg_iov
);
2371 err
|= __get_user(tmp3
, &umsg
->msg_control
);
2375 kmsg
->msg_name
= (void *)A(tmp1
);
2376 kmsg
->msg_iov
= (struct iovec
*)A(tmp2
);
2377 kmsg
->msg_control
= (void *)A(tmp3
);
2379 err
= get_user(kmsg
->msg_namelen
, &umsg
->msg_namelen
);
2380 err
|= get_user(kmsg
->msg_iovlen
, &umsg
->msg_iovlen
);
2381 err
|= get_user(kmsg
->msg_controllen
, &umsg
->msg_controllen
);
2382 err
|= get_user(kmsg
->msg_flags
, &umsg
->msg_flags
);
2387 /* I've named the args so it is easy to tell whose space the pointers are in. */
2388 static int verify_iovec32(struct msghdr
*kern_msg
, struct iovec
*kern_iov
,
2389 char *kern_address
, int mode
)
2393 if(kern_msg
->msg_namelen
) {
2394 if(mode
==VERIFY_READ
) {
2395 int err
= move_addr_to_kernel(kern_msg
->msg_name
,
2396 kern_msg
->msg_namelen
,
2401 kern_msg
->msg_name
= kern_address
;
2403 kern_msg
->msg_name
= NULL
;
2405 if(kern_msg
->msg_iovlen
> UIO_FASTIOV
) {
2406 kern_iov
= kmalloc(kern_msg
->msg_iovlen
* sizeof(struct iovec
),
2412 tot_len
= iov_from_user32_to_kern(kern_iov
,
2413 (struct iovec32
*)kern_msg
->msg_iov
,
2414 kern_msg
->msg_iovlen
);
2416 kern_msg
->msg_iov
= kern_iov
;
2417 else if(kern_msg
->msg_iovlen
> UIO_FASTIOV
)
2423 /* There is a lot of hair here because the alignment rules (and
2424 * thus placement) of cmsg headers and length are different for
2425 * 32-bit apps. -DaveM
2427 static int cmsghdr_from_user32_to_kern(struct msghdr
*kmsg
,
2428 unsigned char *stackbuf
, int stackbuf_size
)
2430 struct cmsghdr32
*ucmsg
;
2431 struct cmsghdr
*kcmsg
, *kcmsg_base
;
2432 __kernel_size_t32 ucmlen
;
2433 __kernel_size_t kcmlen
, tmp
;
2436 kcmsg_base
= kcmsg
= (struct cmsghdr
*)stackbuf
;
2437 ucmsg
= CMSG32_FIRSTHDR(kmsg
);
2438 while(ucmsg
!= NULL
) {
2439 if(get_user(ucmlen
, &ucmsg
->cmsg_len
))
2443 if(CMSG32_ALIGN(ucmlen
) <
2444 CMSG32_ALIGN(sizeof(struct cmsghdr32
)))
2446 if((unsigned long)(((char *)ucmsg
- (char *)kmsg
->msg_control
)
2447 + ucmlen
) > kmsg
->msg_controllen
)
2450 tmp
= ((ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
))) +
2451 CMSG_ALIGN(sizeof(struct cmsghdr
)));
2453 ucmsg
= CMSG32_NXTHDR(kmsg
, ucmsg
, ucmlen
);
2458 /* The kcmlen holds the 64-bit version of the control length.
2459 * It may not be modified as we do not stick it into the kmsg
2460 * until we have successfully copied over all of the data
2463 if(kcmlen
> stackbuf_size
)
2464 kcmsg_base
= kcmsg
= kmalloc(kcmlen
, GFP_KERNEL
);
2468 /* Now copy them over neatly. */
2469 memset(kcmsg
, 0, kcmlen
);
2470 ucmsg
= CMSG32_FIRSTHDR(kmsg
);
2471 while(ucmsg
!= NULL
) {
2472 __get_user(ucmlen
, &ucmsg
->cmsg_len
);
2473 tmp
= ((ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
))) +
2474 CMSG_ALIGN(sizeof(struct cmsghdr
)));
2475 kcmsg
->cmsg_len
= tmp
;
2476 __get_user(kcmsg
->cmsg_level
, &ucmsg
->cmsg_level
);
2477 __get_user(kcmsg
->cmsg_type
, &ucmsg
->cmsg_type
);
2479 /* Copy over the data. */
2480 if(copy_from_user(CMSG_DATA(kcmsg
),
2482 (ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
)))))
2483 goto out_free_efault
;
2486 kcmsg
= (struct cmsghdr
*)((char *)kcmsg
+ CMSG_ALIGN(tmp
));
2487 ucmsg
= CMSG32_NXTHDR(kmsg
, ucmsg
, ucmlen
);
2490 /* Ok, looks like we made it. Hook it up and return success. */
2491 kmsg
->msg_control
= kcmsg_base
;
2492 kmsg
->msg_controllen
= kcmlen
;
2496 if(kcmsg_base
!= (struct cmsghdr
*)stackbuf
)
2501 static void put_cmsg32(struct msghdr
*kmsg
, int level
, int type
,
2502 int len
, void *data
)
2504 struct cmsghdr32
*cm
= (struct cmsghdr32
*) kmsg
->msg_control
;
2505 struct cmsghdr32 cmhdr
;
2506 int cmlen
= CMSG32_LEN(len
);
2508 if(cm
== NULL
|| kmsg
->msg_controllen
< sizeof(*cm
)) {
2509 kmsg
->msg_flags
|= MSG_CTRUNC
;
2513 if(kmsg
->msg_controllen
< cmlen
) {
2514 kmsg
->msg_flags
|= MSG_CTRUNC
;
2515 cmlen
= kmsg
->msg_controllen
;
2517 cmhdr
.cmsg_level
= level
;
2518 cmhdr
.cmsg_type
= type
;
2519 cmhdr
.cmsg_len
= cmlen
;
2521 if(copy_to_user(cm
, &cmhdr
, sizeof cmhdr
))
2523 if(copy_to_user(CMSG32_DATA(cm
), data
, cmlen
- sizeof(struct cmsghdr32
)))
2525 cmlen
= CMSG32_SPACE(len
);
2526 kmsg
->msg_control
+= cmlen
;
2527 kmsg
->msg_controllen
-= cmlen
;
2530 static void scm_detach_fds32(struct msghdr
*kmsg
, struct scm_cookie
*scm
)
2532 struct cmsghdr32
*cm
= (struct cmsghdr32
*) kmsg
->msg_control
;
2533 int fdmax
= (kmsg
->msg_controllen
- sizeof(struct cmsghdr32
)) / sizeof(int);
2534 int fdnum
= scm
->fp
->count
;
2535 struct file
**fp
= scm
->fp
->fp
;
2542 for (i
= 0, cmfptr
= (int *) CMSG32_DATA(cm
); i
< fdmax
; i
++, cmfptr
++) {
2544 err
= get_unused_fd();
2548 err
= put_user(new_fd
, cmfptr
);
2550 put_unused_fd(new_fd
);
2553 /* Bump the usage count and install the file. */
2555 fd_install(new_fd
, fp
[i
]);
2559 int cmlen
= CMSG32_LEN(i
* sizeof(int));
2561 err
= put_user(SOL_SOCKET
, &cm
->cmsg_level
);
2563 err
= put_user(SCM_RIGHTS
, &cm
->cmsg_type
);
2565 err
= put_user(cmlen
, &cm
->cmsg_len
);
2567 cmlen
= CMSG32_SPACE(i
* sizeof(int));
2568 kmsg
->msg_control
+= cmlen
;
2569 kmsg
->msg_controllen
-= cmlen
;
2573 kmsg
->msg_flags
|= MSG_CTRUNC
;
2576 * All of the files that fit in the message have had their
2577 * usage counts incremented, so we just free the list.
2582 /* In these cases we (currently) can just copy to data over verbatim
2583 * because all CMSGs created by the kernel have well defined types which
2584 * have the same layout in both the 32-bit and 64-bit API. One must add
2585 * some special cased conversions here if we start sending control messages
2586 * with incompatible types.
2588 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2589 * we do our work. The remaining cases are:
2591 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2592 * IP_TTL int 32-bit clean
2593 * IP_TOS __u8 32-bit clean
2594 * IP_RECVOPTS variable length 32-bit clean
2595 * IP_RETOPTS variable length 32-bit clean
2596 * (these last two are clean because the types are defined
2597 * by the IPv4 protocol)
2598 * IP_RECVERR struct sock_extended_err +
2599 * struct sockaddr_in 32-bit clean
2600 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2601 * struct sockaddr_in6 32-bit clean
2602 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2603 * IPV6_HOPLIMIT int 32-bit clean
2604 * IPV6_FLOWINFO u32 32-bit clean
2605 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2606 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2607 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2608 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2610 static void cmsg32_recvmsg_fixup(struct msghdr
*kmsg
, unsigned long orig_cmsg_uptr
)
2612 unsigned char *workbuf
, *wp
;
2613 unsigned long bufsz
, space_avail
;
2614 struct cmsghdr
*ucmsg
;
2616 bufsz
= ((unsigned long)kmsg
->msg_control
) - orig_cmsg_uptr
;
2617 space_avail
= kmsg
->msg_controllen
+ bufsz
;
2618 wp
= workbuf
= kmalloc(bufsz
, GFP_KERNEL
);
2622 /* To make this more sane we assume the kernel sends back properly
2623 * formatted control messages. Because of how the kernel will truncate
2624 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2626 ucmsg
= (struct cmsghdr
*) orig_cmsg_uptr
;
2627 while(((unsigned long)ucmsg
) <=
2628 (((unsigned long)kmsg
->msg_control
) - sizeof(struct cmsghdr
))) {
2629 struct cmsghdr32
*kcmsg32
= (struct cmsghdr32
*) wp
;
2632 /* UCMSG is the 64-bit format CMSG entry in user-space.
2633 * KCMSG32 is within the kernel space temporary buffer
2634 * we use to convert into a 32-bit style CMSG.
2636 __get_user(kcmsg32
->cmsg_len
, &ucmsg
->cmsg_len
);
2637 __get_user(kcmsg32
->cmsg_level
, &ucmsg
->cmsg_level
);
2638 __get_user(kcmsg32
->cmsg_type
, &ucmsg
->cmsg_type
);
2640 clen64
= kcmsg32
->cmsg_len
;
2641 copy_from_user(CMSG32_DATA(kcmsg32
), CMSG_DATA(ucmsg
),
2642 clen64
- CMSG_ALIGN(sizeof(*ucmsg
)));
2643 clen32
= ((clen64
- CMSG_ALIGN(sizeof(*ucmsg
))) +
2644 CMSG32_ALIGN(sizeof(struct cmsghdr32
)));
2645 kcmsg32
->cmsg_len
= clen32
;
2647 ucmsg
= (struct cmsghdr
*) (((char *)ucmsg
) + CMSG_ALIGN(clen64
));
2648 wp
= (((char *)kcmsg32
) + CMSG32_ALIGN(clen32
));
2651 /* Copy back fixed up data, and adjust pointers. */
2652 bufsz
= (wp
- workbuf
);
2653 copy_to_user((void *)orig_cmsg_uptr
, workbuf
, bufsz
);
2655 kmsg
->msg_control
= (struct cmsghdr
*)
2656 (((char *)orig_cmsg_uptr
) + bufsz
);
2657 kmsg
->msg_controllen
= space_avail
- bufsz
;
2663 /* If we leave the 64-bit format CMSG chunks in there,
2664 * the application could get confused and crash. So to
2665 * ensure greater recovery, we report no CMSGs.
2667 kmsg
->msg_controllen
+= bufsz
;
2668 kmsg
->msg_control
= (void *) orig_cmsg_uptr
;
2671 asmlinkage
int sys32_sendmsg(int fd
, struct msghdr32
*user_msg
, unsigned user_flags
)
2673 struct socket
*sock
;
2674 char address
[MAX_SOCK_ADDR
];
2675 struct iovec iov
[UIO_FASTIOV
];
2676 unsigned char ctl
[sizeof(struct cmsghdr
) + 20];
2677 unsigned char *ctl_buf
= ctl
;
2678 struct msghdr kern_msg
;
2681 if(msghdr_from_user32_to_kern(&kern_msg
, user_msg
))
2683 if(kern_msg
.msg_iovlen
> UIO_MAXIOV
)
2685 err
= verify_iovec32(&kern_msg
, iov
, address
, VERIFY_READ
);
2690 if(kern_msg
.msg_controllen
) {
2691 err
= cmsghdr_from_user32_to_kern(&kern_msg
, ctl
, sizeof(ctl
));
2694 ctl_buf
= kern_msg
.msg_control
;
2696 kern_msg
.msg_flags
= user_flags
;
2699 sock
= sockfd_lookup(fd
, &err
);
2701 if (sock
->file
->f_flags
& O_NONBLOCK
)
2702 kern_msg
.msg_flags
|= MSG_DONTWAIT
;
2703 err
= sock_sendmsg(sock
, &kern_msg
, total_len
);
2708 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2712 if(kern_msg
.msg_iov
!= iov
)
2713 kfree(kern_msg
.msg_iov
);
2718 asmlinkage
int sys32_recvmsg(int fd
, struct msghdr32
*user_msg
, unsigned int user_flags
)
2720 struct iovec iovstack
[UIO_FASTIOV
];
2721 struct msghdr kern_msg
;
2722 char addr
[MAX_SOCK_ADDR
];
2723 struct socket
*sock
;
2724 struct iovec
*iov
= iovstack
;
2725 struct sockaddr
*uaddr
;
2727 unsigned long cmsg_ptr
;
2728 int err
, total_len
, len
= 0;
2730 if(msghdr_from_user32_to_kern(&kern_msg
, user_msg
))
2732 if(kern_msg
.msg_iovlen
> UIO_MAXIOV
)
2735 uaddr
= kern_msg
.msg_name
;
2736 uaddr_len
= &user_msg
->msg_namelen
;
2737 err
= verify_iovec32(&kern_msg
, iov
, addr
, VERIFY_WRITE
);
2742 cmsg_ptr
= (unsigned long) kern_msg
.msg_control
;
2743 kern_msg
.msg_flags
= 0;
2746 sock
= sockfd_lookup(fd
, &err
);
2748 struct scm_cookie scm
;
2750 if (sock
->file
->f_flags
& O_NONBLOCK
)
2751 user_flags
|= MSG_DONTWAIT
;
2752 memset(&scm
, 0, sizeof(scm
));
2753 err
= sock
->ops
->recvmsg(sock
, &kern_msg
, total_len
,
2757 if(!kern_msg
.msg_control
) {
2758 if(sock
->passcred
|| scm
.fp
)
2759 kern_msg
.msg_flags
|= MSG_CTRUNC
;
2761 __scm_destroy(&scm
);
2763 /* If recvmsg processing itself placed some
2764 * control messages into user space, it's is
2765 * using 64-bit CMSG processing, so we need
2766 * to fix it up before we tack on more stuff.
2768 if((unsigned long) kern_msg
.msg_control
!= cmsg_ptr
)
2769 cmsg32_recvmsg_fixup(&kern_msg
, cmsg_ptr
);
2773 put_cmsg32(&kern_msg
,
2774 SOL_SOCKET
, SCM_CREDENTIALS
,
2775 sizeof(scm
.creds
), &scm
.creds
);
2777 scm_detach_fds32(&kern_msg
, &scm
);
2784 if(uaddr
!= NULL
&& err
>= 0)
2785 err
= move_addr_to_user(addr
, kern_msg
.msg_namelen
, uaddr
, uaddr_len
);
2786 if(cmsg_ptr
!= 0 && err
>= 0) {
2787 unsigned long ucmsg_ptr
= ((unsigned long)kern_msg
.msg_control
);
2788 __kernel_size_t32 uclen
= (__kernel_size_t32
) (ucmsg_ptr
- cmsg_ptr
);
2789 err
|= __put_user(uclen
, &user_msg
->msg_controllen
);
2792 err
= __put_user(kern_msg
.msg_flags
, &user_msg
->msg_flags
);
2793 if(kern_msg
.msg_iov
!= iov
)
2794 kfree(kern_msg
.msg_iov
);
2801 extern asmlinkage
int sys_setsockopt(int fd
, int level
, int optname
,
2802 char *optval
, int optlen
);
2804 asmlinkage
int sys32_setsockopt(int fd
, int level
, int optname
,
2805 char *optval
, int optlen
)
2807 if (optname
== SO_ATTACH_FILTER
) {
2808 struct sock_fprog32
{
2811 } *fprog32
= (struct sock_fprog32
*)optval
;
2812 struct sock_fprog kfprog
;
2813 struct sock_filter
*kfilter
;
2815 mm_segment_t old_fs
;
2819 if (get_user(kfprog
.len
, &fprog32
->len
) ||
2820 __get_user(uptr
, &fprog32
->filter
))
2822 kfprog
.filter
= (struct sock_filter
*)A(uptr
);
2823 fsize
= kfprog
.len
* sizeof(struct sock_filter
);
2824 kfilter
= (struct sock_filter
*)kmalloc(fsize
, GFP_KERNEL
);
2825 if (kfilter
== NULL
)
2827 if (copy_from_user(kfilter
, kfprog
.filter
, fsize
)) {
2831 kfprog
.filter
= kfilter
;
2834 ret
= sys_setsockopt(fd
, level
, optname
,
2835 (char *)&kfprog
, sizeof(kfprog
));
2840 return sys_setsockopt(fd
, level
, optname
, optval
, optlen
);
2843 extern void check_pending(int signum
);
2845 asmlinkage
int sys32_sigaction (int sig
, struct old_sigaction32
*act
, struct old_sigaction32
*oact
)
2847 struct k_sigaction new_ka
, old_ka
;
2851 current
->thread
.flags
|= SPARC_FLAG_NEWSIGNALS
;
2856 old_sigset_t32 mask
;
2858 ret
= get_user((long)new_ka
.sa
.sa_handler
, &act
->sa_handler
);
2859 ret
|= __get_user((long)new_ka
.sa
.sa_restorer
, &act
->sa_restorer
);
2860 ret
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
2861 ret
|= __get_user(mask
, &act
->sa_mask
);
2864 new_ka
.ka_restorer
= NULL
;
2865 siginitset(&new_ka
.sa
.sa_mask
, mask
);
2868 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
2871 ret
= put_user((long)old_ka
.sa
.sa_handler
, &oact
->sa_handler
);
2872 ret
|= __put_user((long)old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
);
2873 ret
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
2874 ret
|= __put_user(old_ka
.sa
.sa_mask
.sig
[0], &oact
->sa_mask
);
2881 sys32_rt_sigaction(int sig
, struct sigaction32
*act
, struct sigaction32
*oact
,
2882 void *restorer
, __kernel_size_t32 sigsetsize
)
2884 struct k_sigaction new_ka
, old_ka
;
2888 /* XXX: Don't preclude handling different sized sigset_t's. */
2889 if (sigsetsize
!= sizeof(sigset_t32
))
2892 /* All tasks which use RT signals (effectively) use
2893 * new style signals.
2895 current
->thread
.flags
|= SPARC_FLAG_NEWSIGNALS
;
2898 new_ka
.ka_restorer
= restorer
;
2899 ret
= get_user((long)new_ka
.sa
.sa_handler
, &act
->sa_handler
);
2900 ret
|= __copy_from_user(&set32
, &act
->sa_mask
, sizeof(sigset_t32
));
2901 switch (_NSIG_WORDS
) {
2902 case 4: new_ka
.sa
.sa_mask
.sig
[3] = set32
.sig
[6] | (((long)set32
.sig
[7]) << 32);
2903 case 3: new_ka
.sa
.sa_mask
.sig
[2] = set32
.sig
[4] | (((long)set32
.sig
[5]) << 32);
2904 case 2: new_ka
.sa
.sa_mask
.sig
[1] = set32
.sig
[2] | (((long)set32
.sig
[3]) << 32);
2905 case 1: new_ka
.sa
.sa_mask
.sig
[0] = set32
.sig
[0] | (((long)set32
.sig
[1]) << 32);
2907 ret
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
2908 ret
|= __get_user((long)new_ka
.sa
.sa_restorer
, &act
->sa_restorer
);
2913 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
2916 switch (_NSIG_WORDS
) {
2917 case 4: set32
.sig
[7] = (old_ka
.sa
.sa_mask
.sig
[3] >> 32); set32
.sig
[6] = old_ka
.sa
.sa_mask
.sig
[3];
2918 case 3: set32
.sig
[5] = (old_ka
.sa
.sa_mask
.sig
[2] >> 32); set32
.sig
[4] = old_ka
.sa
.sa_mask
.sig
[2];
2919 case 2: set32
.sig
[3] = (old_ka
.sa
.sa_mask
.sig
[1] >> 32); set32
.sig
[2] = old_ka
.sa
.sa_mask
.sig
[1];
2920 case 1: set32
.sig
[1] = (old_ka
.sa
.sa_mask
.sig
[0] >> 32); set32
.sig
[0] = old_ka
.sa
.sa_mask
.sig
[0];
2922 ret
= put_user((long)old_ka
.sa
.sa_handler
, &oact
->sa_handler
);
2923 ret
|= __copy_to_user(&oact
->sa_mask
, &set32
, sizeof(sigset_t32
));
2924 ret
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
2925 ret
|= __put_user((long)old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
);
2933 * count32() counts the number of arguments/envelopes
2935 static int count32(u32
* argv
)
2943 error
= get_user(p
,argv
);
2944 if (error
) return error
;
2953 * 'copy_string32()' copies argument/envelope strings from user
2954 * memory to free pages in kernel mem. These are in a format ready
2955 * to be put directly into the top of new user memory.
2957 static int copy_strings32(int argc
, u32
* argv
, struct linux_binprm
*bprm
)
2959 while (argc
-- > 0) {
2964 if (get_user(str
, argv
+ argc
) ||
2966 !(len
= strnlen_user((char *)A(str
), bprm
->p
)))
2978 int offset
, bytes_to_copy
, new, err
;
2980 offset
= pos
% PAGE_SIZE
;
2981 page
= bprm
->page
[pos
/ PAGE_SIZE
];
2984 page
= alloc_page(GFP_USER
);
2985 bprm
->page
[pos
/ PAGE_SIZE
] = page
;
2990 kaddr
= (char *)kmap(page
);
2993 memset(kaddr
, 0, offset
);
2994 bytes_to_copy
= PAGE_SIZE
- offset
;
2995 if (bytes_to_copy
> len
) {
2996 bytes_to_copy
= len
;
2998 memset(kaddr
+offset
+len
, 0,
2999 PAGE_SIZE
-offset
-len
);
3002 err
= copy_from_user(kaddr
+ offset
, (char *)A(str
),
3004 flush_page_to_ram(page
);
3005 kunmap((unsigned long)kaddr
);
3010 pos
+= bytes_to_copy
;
3011 str
+= bytes_to_copy
;
3012 len
-= bytes_to_copy
;
3019 * sys32_execve() executes a new program.
3022 do_execve32(char * filename
, u32
* argv
, u32
* envp
, struct pt_regs
* regs
)
3024 struct linux_binprm bprm
;
3029 bprm
.p
= PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(void *);
3030 memset(bprm
.page
, 0, MAX_ARG_PAGES
* sizeof(bprm
.page
[0]));
3033 file
= open_exec(filename
);
3036 retval
= PTR_ERR(file
);
3041 bprm
.filename
= filename
;
3045 if ((bprm
.argc
= count32(argv
)) < 0) {
3049 if ((bprm
.envc
= count32(envp
)) < 0) {
3054 retval
= prepare_binprm(&bprm
);
3058 retval
= copy_strings_kernel(1, &bprm
.filename
, &bprm
);
3063 retval
= copy_strings32(bprm
.envc
, envp
, &bprm
);
3067 retval
= copy_strings32(bprm
.argc
, argv
, &bprm
);
3071 retval
= search_binary_handler(&bprm
, regs
);
3073 /* execve success */
3077 /* Something went wrong, return the inode and free the argument pages*/
3081 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++)
3083 __free_page(bprm
.page
[i
]);
3089 * sparc32_execve() executes a new program after the asm stub has set
3090 * things up for us. This should basically do what I want it to.
3092 asmlinkage
int sparc32_execve(struct pt_regs
*regs
)
3094 int error
, base
= 0;
3097 /* User register window flush is done by entry.S */
3099 /* Check for indirect call. */
3100 if((u32
)regs
->u_regs
[UREG_G1
] == 0)
3103 filename
= getname32((char *)AA(regs
->u_regs
[base
+ UREG_I0
]));
3104 error
= PTR_ERR(filename
);
3105 if(IS_ERR(filename
))
3107 error
= do_execve32(filename
,
3108 (u32
*)AA((u32
)regs
->u_regs
[base
+ UREG_I1
]),
3109 (u32
*)AA((u32
)regs
->u_regs
[base
+ UREG_I2
]), regs
);
3114 current
->thread
.xfsr
[0] = 0;
3115 current
->thread
.fpsaved
[0] = 0;
3116 regs
->tstate
&= ~TSTATE_PEF
;
3122 #ifdef CONFIG_MODULES
3124 extern asmlinkage
unsigned long sys_create_module(const char *name_user
, size_t size
);
3126 asmlinkage
unsigned long sys32_create_module(const char *name_user
, __kernel_size_t32 size
)
3128 return sys_create_module(name_user
, (size_t)size
);
3131 extern asmlinkage
int sys_init_module(const char *name_user
, struct module
*mod_user
);
3133 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3134 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3136 asmlinkage
int sys32_init_module(const char *name_user
, struct module
*mod_user
)
3138 return sys_init_module(name_user
, mod_user
);
3141 extern asmlinkage
int sys_delete_module(const char *name_user
);
3143 asmlinkage
int sys32_delete_module(const char *name_user
)
3145 return sys_delete_module(name_user
);
3148 struct module_info32
{
3155 /* Query various bits about modules. */
3158 get_mod_name(const char *user_name
, char **buf
)
3163 if ((unsigned long)user_name
>= TASK_SIZE
3164 && !segment_eq(get_fs (), KERNEL_DS
))
3167 page
= __get_free_page(GFP_KERNEL
);
3171 retval
= strncpy_from_user((char *)page
, user_name
, PAGE_SIZE
);
3173 if (retval
< PAGE_SIZE
) {
3174 *buf
= (char *)page
;
3177 retval
= -ENAMETOOLONG
;
3186 put_mod_name(char *buf
)
3188 free_page((unsigned long)buf
);
3191 static __inline__
struct module
*find_module(const char *name
)
3195 for (mod
= module_list
; mod
; mod
= mod
->next
) {
3196 if (mod
->flags
& MOD_DELETED
)
3198 if (!strcmp(mod
->name
, name
))
3206 qm_modules(char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3209 size_t nmod
, space
, len
;
3213 for (mod
= module_list
; mod
->next
!= NULL
; mod
= mod
->next
, ++nmod
) {
3214 len
= strlen(mod
->name
)+1;
3216 goto calc_space_needed
;
3217 if (copy_to_user(buf
, mod
->name
, len
))
3224 if (put_user(nmod
, ret
))
3231 while ((mod
= mod
->next
)->next
!= NULL
)
3232 space
+= strlen(mod
->name
)+1;
3234 if (put_user(space
, ret
))
3241 qm_deps(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3243 size_t i
, space
, len
;
3245 if (mod
->next
== NULL
)
3247 if (!MOD_CAN_QUERY(mod
))
3248 return put_user(0, ret
);
3251 for (i
= 0; i
< mod
->ndeps
; ++i
) {
3252 const char *dep_name
= mod
->deps
[i
].dep
->name
;
3254 len
= strlen(dep_name
)+1;
3256 goto calc_space_needed
;
3257 if (copy_to_user(buf
, dep_name
, len
))
3264 return put_user(i
, ret
);
3268 while (++i
< mod
->ndeps
)
3269 space
+= strlen(mod
->deps
[i
].dep
->name
)+1;
3271 if (put_user(space
, ret
))
3278 qm_refs(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3280 size_t nrefs
, space
, len
;
3281 struct module_ref
*ref
;
3283 if (mod
->next
== NULL
)
3285 if (!MOD_CAN_QUERY(mod
))
3286 if (put_user(0, ret
))
3292 for (nrefs
= 0, ref
= mod
->refs
; ref
; ++nrefs
, ref
= ref
->next_ref
) {
3293 const char *ref_name
= ref
->ref
->name
;
3295 len
= strlen(ref_name
)+1;
3297 goto calc_space_needed
;
3298 if (copy_to_user(buf
, ref_name
, len
))
3305 if (put_user(nrefs
, ret
))
3312 while ((ref
= ref
->next_ref
) != NULL
)
3313 space
+= strlen(ref
->ref
->name
)+1;
3315 if (put_user(space
, ret
))
3322 qm_symbols(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3324 size_t i
, space
, len
;
3325 struct module_symbol
*s
;
3329 if (!MOD_CAN_QUERY(mod
))
3330 if (put_user(0, ret
))
3335 space
= mod
->nsyms
* 2*sizeof(u32
);
3340 if (space
> bufsize
)
3341 goto calc_space_needed
;
3343 if (!access_ok(VERIFY_WRITE
, buf
, space
))
3347 vals
= (unsigned *)buf
;
3348 strings
= buf
+space
;
3350 for (; i
< mod
->nsyms
; ++i
, ++s
, vals
+= 2) {
3351 len
= strlen(s
->name
)+1;
3353 goto calc_space_needed
;
3355 if (copy_to_user(strings
, s
->name
, len
)
3356 || __put_user(s
->value
, vals
+0)
3357 || __put_user(space
, vals
+1))
3365 if (put_user(i
, ret
))
3371 for (; i
< mod
->nsyms
; ++i
, ++s
)
3372 space
+= strlen(s
->name
)+1;
3374 if (put_user(space
, ret
))
3381 qm_info(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3385 if (mod
->next
== NULL
)
3388 if (sizeof(struct module_info32
) <= bufsize
) {
3389 struct module_info32 info
;
3390 info
.addr
= (unsigned long)mod
;
3391 info
.size
= mod
->size
;
3392 info
.flags
= mod
->flags
;
3394 ((mod_member_present(mod
, can_unload
)
3396 ? -1 : atomic_read(&mod
->uc
.usecount
));
3398 if (copy_to_user(buf
, &info
, sizeof(struct module_info32
)))
3403 if (put_user(sizeof(struct module_info32
), ret
))
3409 asmlinkage
int sys32_query_module(char *name_user
, int which
, char *buf
, __kernel_size_t32 bufsize
, u32 ret
)
3415 if (name_user
== 0) {
3416 /* This finds "kernel_module" which is not exported. */
3417 for(mod
= module_list
; mod
->next
!= NULL
; mod
= mod
->next
)
3423 if ((namelen
= get_mod_name(name_user
, &name
)) < 0) {
3429 /* This finds "kernel_module" which is not exported. */
3430 for(mod
= module_list
; mod
->next
!= NULL
; mod
= mod
->next
)
3432 } else if ((mod
= find_module(name
)) == NULL
) {
3445 err
= qm_modules(buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3448 err
= qm_deps(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3451 err
= qm_refs(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3454 err
= qm_symbols(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3457 err
= qm_info(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3468 struct kernel_sym32
{
3473 extern asmlinkage
int sys_get_kernel_syms(struct kernel_sym
*table
);
3475 asmlinkage
int sys32_get_kernel_syms(struct kernel_sym32
*table
)
3478 struct kernel_sym
*tbl
;
3479 mm_segment_t old_fs
;
3481 len
= sys_get_kernel_syms(NULL
);
3482 if (!table
) return len
;
3483 tbl
= kmalloc (len
* sizeof (struct kernel_sym
), GFP_KERNEL
);
3484 if (!tbl
) return -ENOMEM
;
3487 sys_get_kernel_syms(tbl
);
3489 for (i
= 0; i
< len
; i
++, table
+= sizeof (struct kernel_sym32
)) {
3490 if (put_user (tbl
[i
].value
, &table
->value
) ||
3491 copy_to_user (table
->name
, tbl
[i
].name
, 60))
3498 #else /* CONFIG_MODULES */
3500 asmlinkage
unsigned long
3501 sys32_create_module(const char *name_user
, size_t size
)
3507 sys32_init_module(const char *name_user
, struct module
*mod_user
)
3513 sys32_delete_module(const char *name_user
)
3519 sys32_query_module(const char *name_user
, int which
, char *buf
, size_t bufsize
,
3522 /* Let the program know about the new interface. Not that
3523 it'll do them much good. */
3531 sys32_get_kernel_syms(struct kernel_sym
*table
)
3536 #endif /* CONFIG_MODULES */
3538 /* Stuff for NFS server syscalls... */
3539 struct nfsctl_svc32
{
3544 struct nfsctl_client32
{
3545 s8 cl32_ident
[NFSCLNT_IDMAX
+1];
3547 struct in_addr cl32_addrlist
[NFSCLNT_ADDRMAX
];
3550 u8 cl32_fhkey
[NFSCLNT_KEYMAX
];
3553 struct nfsctl_export32
{
3554 s8 ex32_client
[NFSCLNT_IDMAX
+1];
3555 s8 ex32_path
[NFS_MAXPATHLEN
+1];
3556 __kernel_dev_t32 ex32_dev
;
3557 __kernel_ino_t32 ex32_ino
;
3559 __kernel_uid_t32 ex32_anon_uid
;
3560 __kernel_gid_t32 ex32_anon_gid
;
3563 struct nfsctl_uidmap32
{
3564 u32 ug32_ident
; /* char * */
3565 __kernel_uid_t32 ug32_uidbase
;
3567 u32 ug32_udimap
; /* uid_t * */
3568 __kernel_uid_t32 ug32_gidbase
;
3570 u32 ug32_gdimap
; /* gid_t * */
3573 struct nfsctl_fhparm32
{
3574 struct sockaddr gf32_addr
;
3575 __kernel_dev_t32 gf32_dev
;
3576 __kernel_ino_t32 gf32_ino
;
3580 struct nfsctl_fdparm32
{
3581 struct sockaddr gd32_addr
;
3582 s8 gd32_path
[NFS_MAXPATHLEN
+1];
3586 struct nfsctl_fsparm32
{
3587 struct sockaddr gd32_addr
;
3588 s8 gd32_path
[NFS_MAXPATHLEN
+1];
3592 struct nfsctl_arg32
{
3593 s32 ca32_version
; /* safeguard */
3595 struct nfsctl_svc32 u32_svc
;
3596 struct nfsctl_client32 u32_client
;
3597 struct nfsctl_export32 u32_export
;
3598 struct nfsctl_uidmap32 u32_umap
;
3599 struct nfsctl_fhparm32 u32_getfh
;
3600 struct nfsctl_fdparm32 u32_getfd
;
3601 struct nfsctl_fsparm32 u32_getfs
;
3603 #define ca32_svc u.u32_svc
3604 #define ca32_client u.u32_client
3605 #define ca32_export u.u32_export
3606 #define ca32_umap u.u32_umap
3607 #define ca32_getfh u.u32_getfh
3608 #define ca32_getfd u.u32_getfd
3609 #define ca32_getfs u.u32_getfs
3610 #define ca32_authd u.u32_authd
3613 union nfsctl_res32
{
3614 __u8 cr32_getfh
[NFS_FHSIZE
];
3615 struct knfsd_fh cr32_getfs
;
3618 static int nfs_svc32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3622 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3623 err
|= __get_user(karg
->ca_svc
.svc_port
, &arg32
->ca32_svc
.svc32_port
);
3624 err
|= __get_user(karg
->ca_svc
.svc_nthreads
, &arg32
->ca32_svc
.svc32_nthreads
);
3628 static int nfs_clnt32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3632 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3633 err
|= copy_from_user(&karg
->ca_client
.cl_ident
[0],
3634 &arg32
->ca32_client
.cl32_ident
[0],
3636 err
|= __get_user(karg
->ca_client
.cl_naddr
, &arg32
->ca32_client
.cl32_naddr
);
3637 err
|= copy_from_user(&karg
->ca_client
.cl_addrlist
[0],
3638 &arg32
->ca32_client
.cl32_addrlist
[0],
3639 (sizeof(struct in_addr
) * NFSCLNT_ADDRMAX
));
3640 err
|= __get_user(karg
->ca_client
.cl_fhkeytype
,
3641 &arg32
->ca32_client
.cl32_fhkeytype
);
3642 err
|= __get_user(karg
->ca_client
.cl_fhkeylen
,
3643 &arg32
->ca32_client
.cl32_fhkeylen
);
3644 err
|= copy_from_user(&karg
->ca_client
.cl_fhkey
[0],
3645 &arg32
->ca32_client
.cl32_fhkey
[0],
3650 static int nfs_exp32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3654 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3655 err
|= copy_from_user(&karg
->ca_export
.ex_client
[0],
3656 &arg32
->ca32_export
.ex32_client
[0],
3658 err
|= copy_from_user(&karg
->ca_export
.ex_path
[0],
3659 &arg32
->ca32_export
.ex32_path
[0],
3661 err
|= __get_user(karg
->ca_export
.ex_dev
,
3662 &arg32
->ca32_export
.ex32_dev
);
3663 err
|= __get_user(karg
->ca_export
.ex_ino
,
3664 &arg32
->ca32_export
.ex32_ino
);
3665 err
|= __get_user(karg
->ca_export
.ex_flags
,
3666 &arg32
->ca32_export
.ex32_flags
);
3667 err
|= __get_user(karg
->ca_export
.ex_anon_uid
,
3668 &arg32
->ca32_export
.ex32_anon_uid
);
3669 err
|= __get_user(karg
->ca_export
.ex_anon_gid
,
3670 &arg32
->ca32_export
.ex32_anon_gid
);
3671 karg
->ca_export
.ex_anon_uid
= high2lowuid(karg
->ca_export
.ex_anon_uid
);
3672 karg
->ca_export
.ex_anon_gid
= high2lowgid(karg
->ca_export
.ex_anon_gid
);
3676 static int nfs_uud32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3682 memset(karg
, 0, sizeof(*karg
));
3683 if(__get_user(karg
->ca_version
, &arg32
->ca32_version
))
3685 karg
->ca_umap
.ug_ident
= (char *)get_free_page(GFP_USER
);
3686 if(!karg
->ca_umap
.ug_ident
)
3688 err
= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_ident
);
3689 if(strncpy_from_user(karg
->ca_umap
.ug_ident
,
3690 (char *)A(uaddr
), PAGE_SIZE
) <= 0)
3692 err
|= __get_user(karg
->ca_umap
.ug_uidbase
,
3693 &arg32
->ca32_umap
.ug32_uidbase
);
3694 err
|= __get_user(karg
->ca_umap
.ug_uidlen
,
3695 &arg32
->ca32_umap
.ug32_uidlen
);
3696 err
|= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_udimap
);
3699 karg
->ca_umap
.ug_udimap
= kmalloc((sizeof(uid_t
) * karg
->ca_umap
.ug_uidlen
),
3701 if(!karg
->ca_umap
.ug_udimap
)
3703 for(i
= 0; i
< karg
->ca_umap
.ug_uidlen
; i
++)
3704 err
|= __get_user(karg
->ca_umap
.ug_udimap
[i
],
3705 &(((__kernel_uid_t32
*)A(uaddr
))[i
]));
3706 err
|= __get_user(karg
->ca_umap
.ug_gidbase
,
3707 &arg32
->ca32_umap
.ug32_gidbase
);
3708 err
|= __get_user(karg
->ca_umap
.ug_uidlen
,
3709 &arg32
->ca32_umap
.ug32_gidlen
);
3710 err
|= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_gdimap
);
3713 karg
->ca_umap
.ug_gdimap
= kmalloc((sizeof(gid_t
) * karg
->ca_umap
.ug_uidlen
),
3715 if(!karg
->ca_umap
.ug_gdimap
)
3717 for(i
= 0; i
< karg
->ca_umap
.ug_gidlen
; i
++)
3718 err
|= __get_user(karg
->ca_umap
.ug_gdimap
[i
],
3719 &(((__kernel_gid_t32
*)A(uaddr
))[i
]));
3724 static int nfs_getfh32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3728 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3729 err
|= copy_from_user(&karg
->ca_getfh
.gf_addr
,
3730 &arg32
->ca32_getfh
.gf32_addr
,
3731 (sizeof(struct sockaddr
)));
3732 err
|= __get_user(karg
->ca_getfh
.gf_dev
,
3733 &arg32
->ca32_getfh
.gf32_dev
);
3734 err
|= __get_user(karg
->ca_getfh
.gf_ino
,
3735 &arg32
->ca32_getfh
.gf32_ino
);
3736 err
|= __get_user(karg
->ca_getfh
.gf_version
,
3737 &arg32
->ca32_getfh
.gf32_version
);
3741 static int nfs_getfd32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3745 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3746 err
|= copy_from_user(&karg
->ca_getfd
.gd_addr
,
3747 &arg32
->ca32_getfd
.gd32_addr
,
3748 (sizeof(struct sockaddr
)));
3749 err
|= copy_from_user(&karg
->ca_getfd
.gd_path
,
3750 &arg32
->ca32_getfd
.gd32_path
,
3751 (NFS_MAXPATHLEN
+1));
3752 err
|= __get_user(karg
->ca_getfd
.gd_version
,
3753 &arg32
->ca32_getfd
.gd32_version
);
3757 static int nfs_getfs32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3761 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3762 err
|= copy_from_user(&karg
->ca_getfs
.gd_addr
,
3763 &arg32
->ca32_getfs
.gd32_addr
,
3764 (sizeof(struct sockaddr
)));
3765 err
|= copy_from_user(&karg
->ca_getfs
.gd_path
,
3766 &arg32
->ca32_getfs
.gd32_path
,
3767 (NFS_MAXPATHLEN
+1));
3768 err
|= __get_user(karg
->ca_getfs
.gd_maxlen
,
3769 &arg32
->ca32_getfs
.gd32_maxlen
);
3773 /* This really doesn't need translations, we are only passing
3774 * back a union which contains opaque nfs file handle data.
3776 static int nfs_getfh32_res_trans(union nfsctl_res
*kres
, union nfsctl_res32
*res32
)
3778 return copy_to_user(res32
, kres
, sizeof(*res32
));
3781 int asmlinkage
sys32_nfsservctl(int cmd
, struct nfsctl_arg32
*arg32
, union nfsctl_res32
*res32
)
3783 struct nfsctl_arg
*karg
= NULL
;
3784 union nfsctl_res
*kres
= NULL
;
3788 karg
= kmalloc(sizeof(*karg
), GFP_USER
);
3792 kres
= kmalloc(sizeof(*kres
), GFP_USER
);
3800 err
= nfs_svc32_trans(karg
, arg32
);
3802 case NFSCTL_ADDCLIENT
:
3803 err
= nfs_clnt32_trans(karg
, arg32
);
3805 case NFSCTL_DELCLIENT
:
3806 err
= nfs_clnt32_trans(karg
, arg32
);
3809 case NFSCTL_UNEXPORT
:
3810 err
= nfs_exp32_trans(karg
, arg32
);
3812 /* This one is unimplemented, be we're ready for it. */
3813 case NFSCTL_UGIDUPDATE
:
3814 err
= nfs_uud32_trans(karg
, arg32
);
3817 err
= nfs_getfh32_trans(karg
, arg32
);
3820 err
= nfs_getfd32_trans(karg
, arg32
);
3823 err
= nfs_getfs32_trans(karg
, arg32
);
3833 err
= sys_nfsservctl(cmd
, karg
, kres
);
3839 if((cmd
== NFSCTL_GETFH
) ||
3840 (cmd
== NFSCTL_GETFD
) ||
3841 (cmd
== NFSCTL_GETFS
))
3842 err
= nfs_getfh32_res_trans(kres
, res32
);
3846 if(cmd
== NFSCTL_UGIDUPDATE
) {
3847 if(karg
->ca_umap
.ug_ident
)
3848 kfree(karg
->ca_umap
.ug_ident
);
3849 if(karg
->ca_umap
.ug_udimap
)
3850 kfree(karg
->ca_umap
.ug_udimap
);
3851 if(karg
->ca_umap
.ug_gdimap
)
3852 kfree(karg
->ca_umap
.ug_gdimap
);
3861 /* Translations due to time_t size differences. Which affects all
3862 sorts of things, like timeval and itimerval. */
3864 extern struct timezone sys_tz
;
3865 extern int do_sys_settimeofday(struct timeval
*tv
, struct timezone
*tz
);
3867 asmlinkage
int sys32_gettimeofday(struct timeval32
*tv
, struct timezone
*tz
)
3871 do_gettimeofday(&ktv
);
3872 if (put_tv32(tv
, &ktv
))
3876 if (copy_to_user(tz
, &sys_tz
, sizeof(sys_tz
)))
3882 asmlinkage
int sys32_settimeofday(struct timeval32
*tv
, struct timezone
*tz
)
3885 struct timezone ktz
;
3888 if (get_tv32(&ktv
, tv
))
3892 if (copy_from_user(&ktz
, tz
, sizeof(ktz
)))
3896 return do_sys_settimeofday(tv
? &ktv
: NULL
, tz
? &ktz
: NULL
);
3899 extern int do_getitimer(int which
, struct itimerval
*value
);
3901 asmlinkage
int sys32_getitimer(int which
, struct itimerval32
*it
)
3903 struct itimerval kit
;
3906 error
= do_getitimer(which
, &kit
);
3907 if (!error
&& put_it32(it
, &kit
))
3913 extern int do_setitimer(int which
, struct itimerval
*, struct itimerval
*);
3915 asmlinkage
int sys32_setitimer(int which
, struct itimerval32
*in
, struct itimerval32
*out
)
3917 struct itimerval kin
, kout
;
3921 if (get_it32(&kin
, in
))
3924 memset(&kin
, 0, sizeof(kin
));
3926 error
= do_setitimer(which
, &kin
, out
? &kout
: NULL
);
3929 if (put_it32(out
, &kout
))
3936 asmlinkage
int sys_utimes(char *, struct timeval
*);
3938 asmlinkage
int sys32_utimes(char *filename
, struct timeval32
*tvs
)
3941 struct timeval ktvs
[2];
3942 mm_segment_t old_fs
;
3945 kfilename
= getname32(filename
);
3946 ret
= PTR_ERR(kfilename
);
3947 if (!IS_ERR(kfilename
)) {
3949 if (get_tv32(&ktvs
[0], tvs
) ||
3950 get_tv32(&ktvs
[1], 1+tvs
))
3956 ret
= sys_utimes(kfilename
, &ktvs
[0]);
3964 /* These are here just in case some old sparc32 binary calls it. */
3965 asmlinkage
int sys32_pause(void)
3967 current
->state
= TASK_INTERRUPTIBLE
;
3969 return -ERESTARTNOHAND
;
3972 /* PCI config space poking. */
3973 extern asmlinkage
int sys_pciconfig_read(unsigned long bus
,
3977 unsigned char *buf
);
3979 extern asmlinkage
int sys_pciconfig_write(unsigned long bus
,
3983 unsigned char *buf
);
3985 asmlinkage
int sys32_pciconfig_read(u32 bus
, u32 dfn
, u32 off
, u32 len
, u32 ubuf
)
3987 return sys_pciconfig_read((unsigned long) bus
,
3988 (unsigned long) dfn
,
3989 (unsigned long) off
,
3990 (unsigned long) len
,
3991 (unsigned char *)AA(ubuf
));
3994 asmlinkage
int sys32_pciconfig_write(u32 bus
, u32 dfn
, u32 off
, u32 len
, u32 ubuf
)
3996 return sys_pciconfig_write((unsigned long) bus
,
3997 (unsigned long) dfn
,
3998 (unsigned long) off
,
3999 (unsigned long) len
,
4000 (unsigned char *)AA(ubuf
));
4003 extern asmlinkage
int sys_prctl(int option
, unsigned long arg2
, unsigned long arg3
,
4004 unsigned long arg4
, unsigned long arg5
);
4006 asmlinkage
int sys32_prctl(int option
, u32 arg2
, u32 arg3
, u32 arg4
, u32 arg5
)
4008 return sys_prctl(option
,
4009 (unsigned long) arg2
,
4010 (unsigned long) arg3
,
4011 (unsigned long) arg4
,
4012 (unsigned long) arg5
);
4016 extern asmlinkage ssize_t
sys_pread(unsigned int fd
, char * buf
,
4017 size_t count
, loff_t pos
);
4019 extern asmlinkage ssize_t
sys_pwrite(unsigned int fd
, const char * buf
,
4020 size_t count
, loff_t pos
);
4022 typedef __kernel_ssize_t32 ssize_t32
;
4024 asmlinkage ssize_t32
sys32_pread(unsigned int fd
, char *ubuf
,
4025 __kernel_size_t32 count
, u32 poshi
, u32 poslo
)
4027 return sys_pread(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
4030 asmlinkage ssize_t32
sys32_pwrite(unsigned int fd
, char *ubuf
,
4031 __kernel_size_t32 count
, u32 poshi
, u32 poslo
)
4033 return sys_pwrite(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
4037 extern asmlinkage ssize_t
sys_sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
);
4039 asmlinkage
int sys32_sendfile(int out_fd
, int in_fd
, __kernel_off_t32
*offset
, s32 count
)
4041 mm_segment_t old_fs
= get_fs();
4045 if (offset
&& get_user(of
, offset
))
4049 ret
= sys_sendfile(out_fd
, in_fd
, offset
? &of
: NULL
, count
);
4052 if (!ret
&& offset
&& put_user(of
, offset
))
4058 /* Handle adjtimex compatability. */
4062 s32 offset
, freq
, maxerror
, esterror
;
4063 s32 status
, constant
, precision
, tolerance
;
4064 struct timeval32 time
;
4066 s32 ppsfreq
, jitter
, shift
, stabil
;
4067 s32 jitcnt
, calcnt
, errcnt
, stbcnt
;
4068 s32
:32; s32
:32; s32
:32; s32
:32;
4069 s32
:32; s32
:32; s32
:32; s32
:32;
4070 s32
:32; s32
:32; s32
:32; s32
:32;
4073 extern int do_adjtimex(struct timex
*);
4075 asmlinkage
int sys32_adjtimex(struct timex32
*utp
)
4080 memset(&txc
, 0, sizeof(struct timex
));
4082 if(get_user(txc
.modes
, &utp
->modes
) ||
4083 __get_user(txc
.offset
, &utp
->offset
) ||
4084 __get_user(txc
.freq
, &utp
->freq
) ||
4085 __get_user(txc
.maxerror
, &utp
->maxerror
) ||
4086 __get_user(txc
.esterror
, &utp
->esterror
) ||
4087 __get_user(txc
.status
, &utp
->status
) ||
4088 __get_user(txc
.constant
, &utp
->constant
) ||
4089 __get_user(txc
.precision
, &utp
->precision
) ||
4090 __get_user(txc
.tolerance
, &utp
->tolerance
) ||
4091 __get_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
4092 __get_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
4093 __get_user(txc
.tick
, &utp
->tick
) ||
4094 __get_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
4095 __get_user(txc
.jitter
, &utp
->jitter
) ||
4096 __get_user(txc
.shift
, &utp
->shift
) ||
4097 __get_user(txc
.stabil
, &utp
->stabil
) ||
4098 __get_user(txc
.jitcnt
, &utp
->jitcnt
) ||
4099 __get_user(txc
.calcnt
, &utp
->calcnt
) ||
4100 __get_user(txc
.errcnt
, &utp
->errcnt
) ||
4101 __get_user(txc
.stbcnt
, &utp
->stbcnt
))
4104 ret
= do_adjtimex(&txc
);
4106 if(put_user(txc
.modes
, &utp
->modes
) ||
4107 __put_user(txc
.offset
, &utp
->offset
) ||
4108 __put_user(txc
.freq
, &utp
->freq
) ||
4109 __put_user(txc
.maxerror
, &utp
->maxerror
) ||
4110 __put_user(txc
.esterror
, &utp
->esterror
) ||
4111 __put_user(txc
.status
, &utp
->status
) ||
4112 __put_user(txc
.constant
, &utp
->constant
) ||
4113 __put_user(txc
.precision
, &utp
->precision
) ||
4114 __put_user(txc
.tolerance
, &utp
->tolerance
) ||
4115 __put_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
4116 __put_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
4117 __put_user(txc
.tick
, &utp
->tick
) ||
4118 __put_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
4119 __put_user(txc
.jitter
, &utp
->jitter
) ||
4120 __put_user(txc
.shift
, &utp
->shift
) ||
4121 __put_user(txc
.stabil
, &utp
->stabil
) ||
4122 __put_user(txc
.jitcnt
, &utp
->jitcnt
) ||
4123 __put_user(txc
.calcnt
, &utp
->calcnt
) ||
4124 __put_user(txc
.errcnt
, &utp
->errcnt
) ||
4125 __put_user(txc
.stbcnt
, &utp
->stbcnt
))
4131 /* This is just a version for 32-bit applications which does
4132 * not force O_LARGEFILE on.
4135 asmlinkage
long sparc32_open(const char * filename
, int flags
, int mode
)
4140 tmp
= getname(filename
);
4143 fd
= get_unused_fd();
4147 f
= filp_open(tmp
, flags
, mode
);
4165 extern unsigned long do_mremap(unsigned long addr
,
4166 unsigned long old_len
, unsigned long new_len
,
4167 unsigned long flags
, unsigned long new_addr
);
4169 asmlinkage
unsigned long sys32_mremap(unsigned long addr
,
4170 unsigned long old_len
, unsigned long new_len
,
4171 unsigned long flags
, u32 __new_addr
)
4173 unsigned long ret
= -EINVAL
;
4174 unsigned long new_addr
= AA(__new_addr
);
4176 if (old_len
> 0xf0000000UL
|| new_len
> 0xf0000000UL
)
4178 if (addr
> 0xf0000000UL
- old_len
)
4180 down(¤t
->mm
->mmap_sem
);
4181 if (flags
& MREMAP_FIXED
) {
4182 if (new_addr
> 0xf0000000UL
- new_len
)
4184 } else if (addr
> 0xf0000000UL
- new_len
) {
4186 if (!(flags
& MREMAP_MAYMOVE
))
4188 new_addr
= get_unmapped_area (addr
, new_len
);
4191 flags
|= MREMAP_FIXED
;
4193 ret
= do_mremap(addr
, old_len
, new_len
, flags
, new_addr
);
4195 up(¤t
->mm
->mmap_sem
);