1 /* $Id: sys_sparc32.c,v 1.162 2000/08/16 15:33:30 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>
48 #include <linux/ipv6.h>
50 #include <linux/icmpv6.h>
52 #include <asm/types.h>
54 #include <asm/uaccess.h>
55 #include <asm/fpumacro.h>
56 #include <asm/semaphore.h>
60 /* Use this to get at 32-bit user passed pointers. */
61 /* Things to consider: the low-level assembly stub does
62 srl x, 0, x for first four arguments, so if you have
63 pointer to something in the first four arguments, just
64 declare it as a pointer, not u32. On the other side,
65 arguments from 5th onwards should be declared as u32
66 for pointers, and need AA() around each usage.
67 A() macro should be used for places where you e.g.
68 have some internal variable u32 and just want to get
69 rid of a compiler warning. AA() has to be used in
70 places where you want to convert a function argument
71 to 32bit pointer or when you e.g. access pt_regs
72 structure and want to consider 32bit registers only.
75 #define A(__x) ((unsigned long)(__x))
77 ({ unsigned long __ret; \
78 __asm__ ("srl %0, 0, %0" \
84 extern asmlinkage
long sys_chown(const char *, uid_t
,gid_t
);
85 extern asmlinkage
long sys_lchown(const char *, uid_t
,gid_t
);
86 extern asmlinkage
long sys_fchown(unsigned int, uid_t
,gid_t
);
87 extern asmlinkage
long sys_setregid(gid_t
, gid_t
);
88 extern asmlinkage
long sys_setgid(gid_t
);
89 extern asmlinkage
long sys_setreuid(uid_t
, uid_t
);
90 extern asmlinkage
long sys_setuid(uid_t
);
91 extern asmlinkage
long sys_setresuid(uid_t
, uid_t
, uid_t
);
92 extern asmlinkage
long sys_setresgid(gid_t
, gid_t
, gid_t
);
93 extern asmlinkage
long sys_setfsuid(uid_t
);
94 extern asmlinkage
long sys_setfsgid(gid_t
);
96 /* For this source file, we want overflow handling. */
104 #undef NEW_TO_OLD_UID
105 #undef NEW_TO_OLD_GID
106 #undef SET_OLDSTAT_UID
107 #undef SET_OLDSTAT_GID
111 #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
112 #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
113 #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
114 #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
115 #define SET_UID16(var, uid) var = high2lowuid(uid)
116 #define SET_GID16(var, gid) var = high2lowgid(gid)
117 #define NEW_TO_OLD_UID(uid) high2lowuid(uid)
118 #define NEW_TO_OLD_GID(gid) high2lowgid(gid)
119 #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
120 #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
121 #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
122 #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
124 asmlinkage
long sys32_chown16(const char * filename
, u16 user
, u16 group
)
126 return sys_chown(filename
, low2highuid(user
), low2highgid(group
));
129 asmlinkage
long sys32_lchown16(const char * filename
, u16 user
, u16 group
)
131 return sys_lchown(filename
, low2highuid(user
), low2highgid(group
));
134 asmlinkage
long sys32_fchown16(unsigned int fd
, u16 user
, u16 group
)
136 return sys_fchown(fd
, low2highuid(user
), low2highgid(group
));
139 asmlinkage
long sys32_setregid16(u16 rgid
, u16 egid
)
141 return sys_setregid(low2highgid(rgid
), low2highgid(egid
));
144 asmlinkage
long sys32_setgid16(u16 gid
)
146 return sys_setgid((gid_t
)gid
);
149 asmlinkage
long sys32_setreuid16(u16 ruid
, u16 euid
)
151 return sys_setreuid(low2highuid(ruid
), low2highuid(euid
));
154 asmlinkage
long sys32_setuid16(u16 uid
)
156 return sys_setuid((uid_t
)uid
);
159 asmlinkage
long sys32_setresuid16(u16 ruid
, u16 euid
, u16 suid
)
161 return sys_setresuid(low2highuid(ruid
), low2highuid(euid
),
165 asmlinkage
long sys32_getresuid16(u16
*ruid
, u16
*euid
, u16
*suid
)
169 if (!(retval
= put_user(high2lowuid(current
->uid
), ruid
)) &&
170 !(retval
= put_user(high2lowuid(current
->euid
), euid
)))
171 retval
= put_user(high2lowuid(current
->suid
), suid
);
176 asmlinkage
long sys32_setresgid16(u16 rgid
, u16 egid
, u16 sgid
)
178 return sys_setresgid(low2highgid(rgid
), low2highgid(egid
),
182 asmlinkage
long sys32_getresgid16(u16
*rgid
, u16
*egid
, u16
*sgid
)
186 if (!(retval
= put_user(high2lowgid(current
->gid
), rgid
)) &&
187 !(retval
= put_user(high2lowgid(current
->egid
), egid
)))
188 retval
= put_user(high2lowgid(current
->sgid
), sgid
);
193 asmlinkage
long sys32_setfsuid16(u16 uid
)
195 return sys_setfsuid((uid_t
)uid
);
198 asmlinkage
long sys32_setfsgid16(u16 gid
)
200 return sys_setfsgid((gid_t
)gid
);
203 asmlinkage
long sys32_getgroups16(int gidsetsize
, u16
*grouplist
)
210 i
= current
->ngroups
;
215 groups
[j
] = current
->groups
[j
];
216 if (copy_to_user(grouplist
, groups
, sizeof(u16
)*i
))
222 asmlinkage
long sys32_setgroups16(int gidsetsize
, u16
*grouplist
)
227 if (!capable(CAP_SETGID
))
229 if ((unsigned) gidsetsize
> NGROUPS
)
231 if (copy_from_user(groups
, grouplist
, gidsetsize
* sizeof(u16
)))
233 for (i
= 0 ; i
< gidsetsize
; i
++)
234 current
->groups
[i
] = (gid_t
)groups
[i
];
235 current
->ngroups
= gidsetsize
;
239 asmlinkage
long sys32_getuid16(void)
241 return high2lowuid(current
->uid
);
244 asmlinkage
long sys32_geteuid16(void)
246 return high2lowuid(current
->euid
);
249 asmlinkage
long sys32_getgid16(void)
251 return high2lowgid(current
->gid
);
254 asmlinkage
long sys32_getegid16(void)
256 return high2lowgid(current
->egid
);
259 /* 32-bit timeval and related flotsam. */
268 struct timeval32 it_interval
;
269 struct timeval32 it_value
;
272 static inline long get_tv32(struct timeval
*o
, struct timeval32
*i
)
274 return (!access_ok(VERIFY_READ
, tv32
, sizeof(*tv32
)) ||
275 (__get_user(o
->tv_sec
, &i
->tv_sec
) |
276 __get_user(o
->tv_usec
, &i
->tv_usec
)));
279 static inline long put_tv32(struct timeval32
*o
, struct timeval
*i
)
281 return (!access_ok(VERIFY_WRITE
, o
, sizeof(*o
)) ||
282 (__put_user(i
->tv_sec
, &o
->tv_sec
) |
283 __put_user(i
->tv_usec
, &o
->tv_usec
)));
286 static inline long get_it32(struct itimerval
*o
, struct itimerval32
*i
)
288 return (!access_ok(VERIFY_READ
, i32
, sizeof(*i32
)) ||
289 (__get_user(o
->it_interval
.tv_sec
, &i
->it_interval
.tv_sec
) |
290 __get_user(o
->it_interval
.tv_usec
, &i
->it_interval
.tv_usec
) |
291 __get_user(o
->it_value
.tv_sec
, &i
->it_value
.tv_sec
) |
292 __get_user(o
->it_value
.tv_usec
, &i
->it_value
.tv_usec
)));
295 static inline long put_it32(struct itimerval32
*o
, struct itimerval
*i
)
297 return (!access_ok(VERIFY_WRITE
, i32
, sizeof(*i32
)) ||
298 (__put_user(i
->it_interval
.tv_sec
, &o
->it_interval
.tv_sec
) |
299 __put_user(i
->it_interval
.tv_usec
, &o
->it_interval
.tv_usec
) |
300 __put_user(i
->it_value
.tv_sec
, &o
->it_value
.tv_sec
) |
301 __put_user(i
->it_value
.tv_usec
, &o
->it_value
.tv_usec
)));
304 extern asmlinkage
int sys_ioperm(unsigned long from
, unsigned long num
, int on
);
306 asmlinkage
int sys32_ioperm(u32 from
, u32 num
, int on
)
308 return sys_ioperm((unsigned long)from
, (unsigned long)num
, on
);
311 struct msgbuf32
{ s32 mtype
; char mtext
[1]; };
316 __kernel_uid_t32 uid
;
317 __kernel_gid_t32 gid
;
318 __kernel_uid_t32 cuid
;
319 __kernel_gid_t32 cgid
;
320 __kernel_mode_t32 mode
;
325 struct ipc_perm32 sem_perm
; /* permissions .. see ipc.h */
326 __kernel_time_t32 sem_otime
; /* last semop time */
327 __kernel_time_t32 sem_ctime
; /* last change time */
328 u32 sem_base
; /* ptr to first semaphore in array */
329 u32 sem_pending
; /* pending operations to be processed */
330 u32 sem_pending_last
; /* last pending operation */
331 u32 undo
; /* undo requests on this array */
332 unsigned short sem_nsems
; /* no. of semaphores in array */
335 struct semid64_ds32
{
336 struct ipc64_perm sem_perm
; /* this structure is the same on sparc32 and sparc64 */
338 __kernel_time_t32 sem_otime
;
340 __kernel_time_t32 sem_ctime
;
348 struct ipc_perm32 msg_perm
;
351 __kernel_time_t32 msg_stime
;
352 __kernel_time_t32 msg_rtime
;
353 __kernel_time_t32 msg_ctime
;
356 unsigned short msg_cbytes
;
357 unsigned short msg_qnum
;
358 unsigned short msg_qbytes
;
359 __kernel_ipc_pid_t32 msg_lspid
;
360 __kernel_ipc_pid_t32 msg_lrpid
;
363 struct msqid64_ds32
{
364 struct ipc64_perm msg_perm
;
366 __kernel_time_t32 msg_stime
;
368 __kernel_time_t32 msg_rtime
;
370 __kernel_time_t32 msg_ctime
;
371 unsigned int msg_cbytes
;
372 unsigned int msg_qnum
;
373 unsigned int msg_qbytes
;
374 __kernel_pid_t32 msg_lspid
;
375 __kernel_pid_t32 msg_lrpid
;
376 unsigned int __unused1
;
377 unsigned int __unused2
;
382 struct ipc_perm32 shm_perm
;
384 __kernel_time_t32 shm_atime
;
385 __kernel_time_t32 shm_dtime
;
386 __kernel_time_t32 shm_ctime
;
387 __kernel_ipc_pid_t32 shm_cpid
;
388 __kernel_ipc_pid_t32 shm_lpid
;
389 unsigned short shm_nattch
;
392 struct shmid64_ds32
{
393 struct ipc64_perm shm_perm
;
395 __kernel_time_t32 shm_atime
;
397 __kernel_time_t32 shm_dtime
;
399 __kernel_time_t32 shm_ctime
;
400 __kernel_size_t32 shm_segsz
;
401 __kernel_pid_t32 shm_cpid
;
402 __kernel_pid_t32 shm_lpid
;
403 unsigned int shm_nattch
;
404 unsigned int __unused1
;
405 unsigned int __unused2
;
410 * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
412 * This is really horribly ugly.
414 #define IPCOP_MASK(__x) (1UL << (__x))
415 static int do_sys32_semctl(int first
, int second
, int third
, void *uptr
)
424 if (get_user (pad
, (u32
*)uptr
))
427 fourth
.val
= (int)pad
;
429 fourth
.__pad
= (void *)A(pad
);
430 if (IPCOP_MASK (third
) &
431 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SEM_INFO
) | IPCOP_MASK (GETVAL
) |
432 IPCOP_MASK (GETPID
) | IPCOP_MASK (GETNCNT
) | IPCOP_MASK (GETZCNT
) |
433 IPCOP_MASK (GETALL
) | IPCOP_MASK (SETALL
) | IPCOP_MASK (IPC_RMID
))) {
434 err
= sys_semctl (first
, second
, third
, fourth
);
435 } else if (third
& IPC_64
) {
437 struct semid64_ds32
*usp
= (struct semid64_ds32
*)A(pad
);
439 int need_back_translation
;
441 if (third
== (IPC_SET
|IPC_64
)) {
442 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
443 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
444 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
449 need_back_translation
=
450 (IPCOP_MASK (third
) &
451 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
452 if (need_back_translation
)
456 err
= sys_semctl (first
, second
, third
, fourth
);
458 if (need_back_translation
) {
459 int err2
= copy_to_user (&usp
->sem_perm
, &s
.sem_perm
, sizeof(struct ipc64_perm
) + 2*sizeof(time_t));
460 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
461 if (err2
) err
= -EFAULT
;
465 struct semid_ds32
*usp
= (struct semid_ds32
*)A(pad
);
467 int need_back_translation
;
469 if (third
== IPC_SET
) {
470 err
= get_user (s
.sem_perm
.uid
, &usp
->sem_perm
.uid
);
471 err
|= __get_user (s
.sem_perm
.gid
, &usp
->sem_perm
.gid
);
472 err
|= __get_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
477 need_back_translation
=
478 (IPCOP_MASK (third
) &
479 (IPCOP_MASK (SEM_STAT
) | IPCOP_MASK (IPC_STAT
))) != 0;
480 if (need_back_translation
)
484 err
= sys_semctl (first
, second
, third
, fourth
);
486 if (need_back_translation
) {
487 int err2
= put_user (s
.sem_perm
.key
, &usp
->sem_perm
.key
);
488 err2
|= __put_user (high2lowuid(s
.sem_perm
.uid
), &usp
->sem_perm
.uid
);
489 err2
|= __put_user (high2lowgid(s
.sem_perm
.gid
), &usp
->sem_perm
.gid
);
490 err2
|= __put_user (high2lowuid(s
.sem_perm
.cuid
), &usp
->sem_perm
.cuid
);
491 err2
|= __put_user (high2lowgid(s
.sem_perm
.cgid
), &usp
->sem_perm
.cgid
);
492 err2
|= __put_user (s
.sem_perm
.mode
, &usp
->sem_perm
.mode
);
493 err2
|= __put_user (s
.sem_perm
.seq
, &usp
->sem_perm
.seq
);
494 err2
|= __put_user (s
.sem_otime
, &usp
->sem_otime
);
495 err2
|= __put_user (s
.sem_ctime
, &usp
->sem_ctime
);
496 err2
|= __put_user (s
.sem_nsems
, &usp
->sem_nsems
);
497 if (err2
) err
= -EFAULT
;
504 static int do_sys32_msgsnd (int first
, int second
, int third
, void *uptr
)
506 struct msgbuf
*p
= kmalloc (second
+ sizeof (struct msgbuf
) + 4, GFP_USER
);
507 struct msgbuf32
*up
= (struct msgbuf32
*)uptr
;
513 err
= get_user (p
->mtype
, &up
->mtype
);
514 err
|= __copy_from_user (p
->mtext
, &up
->mtext
, second
);
519 err
= sys_msgsnd (first
, p
, second
, third
);
526 static int do_sys32_msgrcv (int first
, int second
, int msgtyp
, int third
,
527 int version
, void *uptr
)
535 struct ipc_kludge
*uipck
= (struct ipc_kludge
*)uptr
;
536 struct ipc_kludge ipck
;
542 if (copy_from_user (&ipck
, uipck
, sizeof (struct ipc_kludge
)))
544 uptr
= (void *)A(ipck
.msgp
);
545 msgtyp
= ipck
.msgtyp
;
548 p
= kmalloc (second
+ sizeof (struct msgbuf
) + 4, GFP_USER
);
553 err
= sys_msgrcv (first
, p
, second
+ 4, msgtyp
, third
);
557 up
= (struct msgbuf32
*)uptr
;
558 if (put_user (p
->mtype
, &up
->mtype
) ||
559 __copy_to_user (&up
->mtext
, p
->mtext
, err
))
567 static int do_sys32_msgctl (int first
, int second
, void *uptr
)
571 if (IPCOP_MASK (second
) &
572 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (MSG_INFO
) |
573 IPCOP_MASK (IPC_RMID
))) {
574 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)uptr
);
575 } else if (second
& IPC_64
) {
577 struct msqid64_ds32
*up
= (struct msqid64_ds32
*)uptr
;
580 if (second
== (IPC_SET
|IPC_64
)) {
581 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
582 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
583 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
584 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
590 err
= sys_msgctl (first
, second
, (struct msqid_ds
*)&m
);
592 if (IPCOP_MASK (second
) &
593 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
594 int err2
= copy_to_user(&up
->msg_perm
, &m
.msg_perm
, sizeof(struct ipc64_perm
) + 3*sizeof(time_t));
595 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
596 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
597 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
598 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
599 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
605 struct msqid_ds32
*up
= (struct msqid_ds32
*)uptr
;
608 if (second
== IPC_SET
) {
609 err
= get_user (m
.msg_perm
.uid
, &up
->msg_perm
.uid
);
610 err
|= __get_user (m
.msg_perm
.gid
, &up
->msg_perm
.gid
);
611 err
|= __get_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
612 err
|= __get_user (m
.msg_qbytes
, &up
->msg_qbytes
);
618 err
= sys_msgctl (first
, second
, &m
);
620 if (IPCOP_MASK (second
) &
621 (IPCOP_MASK (MSG_STAT
) | IPCOP_MASK (IPC_STAT
))) {
622 int err2
= put_user (m
.msg_perm
.key
, &up
->msg_perm
.key
);
623 err2
|= __put_user (high2lowuid(m
.msg_perm
.uid
), &up
->msg_perm
.uid
);
624 err2
|= __put_user (high2lowgid(m
.msg_perm
.gid
), &up
->msg_perm
.gid
);
625 err2
|= __put_user (high2lowuid(m
.msg_perm
.cuid
), &up
->msg_perm
.cuid
);
626 err2
|= __put_user (high2lowgid(m
.msg_perm
.cgid
), &up
->msg_perm
.cgid
);
627 err2
|= __put_user (m
.msg_perm
.mode
, &up
->msg_perm
.mode
);
628 err2
|= __put_user (m
.msg_perm
.seq
, &up
->msg_perm
.seq
);
629 err2
|= __put_user (m
.msg_stime
, &up
->msg_stime
);
630 err2
|= __put_user (m
.msg_rtime
, &up
->msg_rtime
);
631 err2
|= __put_user (m
.msg_ctime
, &up
->msg_ctime
);
632 err2
|= __put_user (m
.msg_cbytes
, &up
->msg_cbytes
);
633 err2
|= __put_user (m
.msg_qnum
, &up
->msg_qnum
);
634 err2
|= __put_user (m
.msg_qbytes
, &up
->msg_qbytes
);
635 err2
|= __put_user (m
.msg_lspid
, &up
->msg_lspid
);
636 err2
|= __put_user (m
.msg_lrpid
, &up
->msg_lrpid
);
646 static int do_sys32_shmat (int first
, int second
, int third
, int version
, void *uptr
)
649 u32
*uaddr
= (u32
*)A((u32
)third
);
654 err
= sys_shmat (first
, uptr
, second
, &raddr
);
657 err
= put_user (raddr
, uaddr
);
662 static int do_sys32_shmctl (int first
, int second
, void *uptr
)
666 if (IPCOP_MASK (second
) &
667 (IPCOP_MASK (IPC_INFO
) | IPCOP_MASK (SHM_LOCK
) | IPCOP_MASK (SHM_UNLOCK
) |
668 IPCOP_MASK (IPC_RMID
))) {
669 if (second
== (IPC_INFO
|IPC_64
))
670 second
= IPC_INFO
; /* So that we don't have to translate it */
671 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)uptr
);
672 } else if ((second
& IPC_64
) && second
!= (SHM_INFO
|IPC_64
)) {
674 struct shmid64_ds32
*up
= (struct shmid64_ds32
*)uptr
;
677 if (second
== (IPC_SET
|IPC_64
)) {
678 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
679 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
680 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
686 err
= sys_shmctl (first
, second
, (struct shmid_ds
*)&s
);
691 /* Mask it even in this case so it becomes a CSE. */
692 if (IPCOP_MASK (second
) &
693 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
694 int err2
= copy_to_user (&up
->shm_perm
, &s
.shm_perm
, sizeof(struct ipc64_perm
) + 3*sizeof(time_t));
695 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
696 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
697 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
698 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
704 struct shmid_ds32
*up
= (struct shmid_ds32
*)uptr
;
708 if (second
== IPC_SET
) {
709 err
= get_user (s
.shm_perm
.uid
, &up
->shm_perm
.uid
);
710 err
|= __get_user (s
.shm_perm
.gid
, &up
->shm_perm
.gid
);
711 err
|= __get_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
717 err
= sys_shmctl (first
, second
, &s
);
722 /* Mask it even in this case so it becomes a CSE. */
723 if (second
== SHM_INFO
) {
726 u32 shm_tot
, shm_rss
, shm_swp
;
727 u32 swap_attempts
, swap_successes
;
728 } *uip
= (struct shm_info32
*)uptr
;
729 struct shm_info
*kp
= (struct shm_info
*)&s
;
730 int err2
= put_user (kp
->used_ids
, &uip
->used_ids
);
731 err2
|= __put_user (kp
->shm_tot
, &uip
->shm_tot
);
732 err2
|= __put_user (kp
->shm_rss
, &uip
->shm_rss
);
733 err2
|= __put_user (kp
->shm_swp
, &uip
->shm_swp
);
734 err2
|= __put_user (kp
->swap_attempts
, &uip
->swap_attempts
);
735 err2
|= __put_user (kp
->swap_successes
, &uip
->swap_successes
);
738 } else if (IPCOP_MASK (second
) &
739 (IPCOP_MASK (SHM_STAT
) | IPCOP_MASK (IPC_STAT
))) {
740 int err2
= put_user (s
.shm_perm
.key
, &up
->shm_perm
.key
);
741 err2
|= __put_user (high2lowuid(s
.shm_perm
.uid
), &up
->shm_perm
.uid
);
742 err2
|= __put_user (high2lowuid(s
.shm_perm
.gid
), &up
->shm_perm
.gid
);
743 err2
|= __put_user (high2lowuid(s
.shm_perm
.cuid
), &up
->shm_perm
.cuid
);
744 err2
|= __put_user (high2lowuid(s
.shm_perm
.cgid
), &up
->shm_perm
.cgid
);
745 err2
|= __put_user (s
.shm_perm
.mode
, &up
->shm_perm
.mode
);
746 err2
|= __put_user (s
.shm_perm
.seq
, &up
->shm_perm
.seq
);
747 err2
|= __put_user (s
.shm_atime
, &up
->shm_atime
);
748 err2
|= __put_user (s
.shm_dtime
, &up
->shm_dtime
);
749 err2
|= __put_user (s
.shm_ctime
, &up
->shm_ctime
);
750 err2
|= __put_user (s
.shm_segsz
, &up
->shm_segsz
);
751 err2
|= __put_user (s
.shm_nattch
, &up
->shm_nattch
);
752 err2
|= __put_user (s
.shm_cpid
, &up
->shm_cpid
);
753 err2
|= __put_user (s
.shm_lpid
, &up
->shm_lpid
);
762 asmlinkage
int sys32_ipc (u32 call
, int first
, int second
, int third
, u32 ptr
, u32 fifth
)
766 version
= call
>> 16; /* hack for backward compatibility */
772 /* struct sembuf is the same on 32 and 64bit :)) */
773 err
= sys_semop (first
, (struct sembuf
*)AA(ptr
), second
);
776 err
= sys_semget (first
, second
, third
);
779 err
= do_sys32_semctl (first
, second
, third
, (void *)AA(ptr
));
788 err
= do_sys32_msgsnd (first
, second
, third
, (void *)AA(ptr
));
791 err
= do_sys32_msgrcv (first
, second
, fifth
, third
,
792 version
, (void *)AA(ptr
));
795 err
= sys_msgget ((key_t
) first
, second
);
798 err
= do_sys32_msgctl (first
, second
, (void *)AA(ptr
));
807 err
= do_sys32_shmat (first
, second
, third
,
808 version
, (void *)AA(ptr
));
811 err
= sys_shmdt ((char *)AA(ptr
));
814 err
= sys_shmget (first
, second
, third
);
817 err
= do_sys32_shmctl (first
, second
, (void *)AA(ptr
));
830 static inline int get_flock(struct flock
*kfl
, struct flock32
*ufl
)
834 err
= get_user(kfl
->l_type
, &ufl
->l_type
);
835 err
|= __get_user(kfl
->l_whence
, &ufl
->l_whence
);
836 err
|= __get_user(kfl
->l_start
, &ufl
->l_start
);
837 err
|= __get_user(kfl
->l_len
, &ufl
->l_len
);
838 err
|= __get_user(kfl
->l_pid
, &ufl
->l_pid
);
842 static inline int put_flock(struct flock
*kfl
, struct flock32
*ufl
)
846 err
= __put_user(kfl
->l_type
, &ufl
->l_type
);
847 err
|= __put_user(kfl
->l_whence
, &ufl
->l_whence
);
848 err
|= __put_user(kfl
->l_start
, &ufl
->l_start
);
849 err
|= __put_user(kfl
->l_len
, &ufl
->l_len
);
850 err
|= __put_user(kfl
->l_pid
, &ufl
->l_pid
);
854 extern asmlinkage
long sys_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
);
856 asmlinkage
long sys32_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
867 if(get_flock(&f
, (struct flock32
*)arg
))
869 old_fs
= get_fs(); set_fs (KERNEL_DS
);
870 ret
= sys_fcntl(fd
, cmd
, (unsigned long)&f
);
873 if (f
.l_start
>= 0x7fffffffUL
||
874 f
.l_len
>= 0x7fffffffUL
||
875 f
.l_start
+ f
.l_len
>= 0x7fffffffUL
)
877 if(put_flock(&f
, (struct flock32
*)arg
))
882 return sys_fcntl(fd
, cmd
, (unsigned long)arg
);
886 asmlinkage
long sys32_fcntl64(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
888 if (cmd
>= F_GETLK64
&& cmd
<= F_SETLKW64
)
889 return sys_fcntl(fd
, cmd
+ F_GETLK
- F_GETLK64
, arg
);
890 return sys32_fcntl(fd
, cmd
, arg
);
894 __u32 dqb_bhardlimit
;
895 __u32 dqb_bsoftlimit
;
897 __u32 dqb_ihardlimit
;
898 __u32 dqb_isoftlimit
;
900 __kernel_time_t32 dqb_btime
;
901 __kernel_time_t32 dqb_itime
;
904 extern asmlinkage
int sys_quotactl(int cmd
, const char *special
, int id
, caddr_t addr
);
906 asmlinkage
int sys32_quotactl(int cmd
, const char *special
, int id
, unsigned long addr
)
908 int cmds
= cmd
>> SUBCMDSHIFT
;
920 if (copy_from_user (&d
, (struct dqblk32
*)addr
,
921 sizeof (struct dqblk32
)))
923 d
.dqb_itime
= ((struct dqblk32
*)&d
)->dqb_itime
;
924 d
.dqb_btime
= ((struct dqblk32
*)&d
)->dqb_btime
;
927 return sys_quotactl(cmd
, special
,
930 spec
= getname (special
);
932 if (IS_ERR(spec
)) return err
;
935 err
= sys_quotactl(cmd
, (const char *)spec
, id
, (caddr_t
)&d
);
938 if (cmds
== Q_GETQUOTA
) {
939 __kernel_time_t b
= d
.dqb_btime
, i
= d
.dqb_itime
;
940 ((struct dqblk32
*)&d
)->dqb_itime
= i
;
941 ((struct dqblk32
*)&d
)->dqb_btime
= b
;
942 if (copy_to_user ((struct dqblk32
*)addr
, &d
,
943 sizeof (struct dqblk32
)))
949 static inline int put_statfs (struct statfs32
*ubuf
, struct statfs
*kbuf
)
953 err
= put_user (kbuf
->f_type
, &ubuf
->f_type
);
954 err
|= __put_user (kbuf
->f_bsize
, &ubuf
->f_bsize
);
955 err
|= __put_user (kbuf
->f_blocks
, &ubuf
->f_blocks
);
956 err
|= __put_user (kbuf
->f_bfree
, &ubuf
->f_bfree
);
957 err
|= __put_user (kbuf
->f_bavail
, &ubuf
->f_bavail
);
958 err
|= __put_user (kbuf
->f_files
, &ubuf
->f_files
);
959 err
|= __put_user (kbuf
->f_ffree
, &ubuf
->f_ffree
);
960 err
|= __put_user (kbuf
->f_namelen
, &ubuf
->f_namelen
);
961 err
|= __put_user (kbuf
->f_fsid
.val
[0], &ubuf
->f_fsid
.val
[0]);
962 err
|= __put_user (kbuf
->f_fsid
.val
[1], &ubuf
->f_fsid
.val
[1]);
966 extern asmlinkage
int sys_statfs(const char * path
, struct statfs
* buf
);
968 asmlinkage
int sys32_statfs(const char * path
, struct statfs32
*buf
)
972 mm_segment_t old_fs
= get_fs();
975 pth
= getname (path
);
979 ret
= sys_statfs((const char *)pth
, &s
);
982 if (put_statfs(buf
, &s
))
988 extern asmlinkage
int sys_fstatfs(unsigned int fd
, struct statfs
* buf
);
990 asmlinkage
int sys32_fstatfs(unsigned int fd
, struct statfs32
*buf
)
994 mm_segment_t old_fs
= get_fs();
997 ret
= sys_fstatfs(fd
, &s
);
999 if (put_statfs(buf
, &s
))
1004 extern asmlinkage
long sys_truncate(const char * path
, unsigned long length
);
1005 extern asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
);
1007 asmlinkage
int sys32_truncate64(const char * path
, unsigned long high
, unsigned long low
)
1012 return sys_truncate(path
, (high
<< 32) | low
);
1015 asmlinkage
int sys32_ftruncate64(unsigned int fd
, unsigned long high
, unsigned long low
)
1020 return sys_ftruncate(fd
, (high
<< 32) | low
);
1023 extern asmlinkage
int sys_utime(char * filename
, struct utimbuf
* times
);
1026 __kernel_time_t32 actime
, modtime
;
1029 asmlinkage
int sys32_utime(char * filename
, struct utimbuf32
*times
)
1032 mm_segment_t old_fs
;
1037 return sys_utime(filename
, NULL
);
1038 if (get_user (t
.actime
, ×
->actime
) ||
1039 __get_user (t
.modtime
, ×
->modtime
))
1041 filenam
= getname (filename
);
1042 ret
= PTR_ERR(filenam
);
1043 if (!IS_ERR(filenam
)) {
1046 ret
= sys_utime(filenam
, &t
);
1053 struct iovec32
{ u32 iov_base
; __kernel_size_t32 iov_len
; };
1055 typedef ssize_t (*io_fn_t
)(struct file
*, char *, size_t, loff_t
*);
1056 typedef ssize_t (*iov_fn_t
)(struct file
*, const struct iovec
*, unsigned long, loff_t
*);
1058 static long do_readv_writev32(int type
, struct file
*file
,
1059 const struct iovec32
*vector
, u32 count
)
1061 unsigned long tot_len
;
1062 struct iovec iovstack
[UIO_FASTIOV
];
1063 struct iovec
*iov
=iovstack
, *ivp
;
1064 struct inode
*inode
;
1069 /* First get the "struct iovec" from user memory and
1070 * verify all the pointers
1074 if (verify_area(VERIFY_READ
, vector
, sizeof(struct iovec32
)*count
))
1076 if (count
> UIO_MAXIOV
)
1078 if (count
> UIO_FASTIOV
) {
1079 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
1091 __get_user(len
, &vector
->iov_len
);
1092 __get_user(buf
, &vector
->iov_base
);
1094 ivp
->iov_base
= (void *)A(buf
);
1095 ivp
->iov_len
= (__kernel_size_t
) len
;
1101 inode
= file
->f_dentry
->d_inode
;
1102 /* VERIFY_WRITE actually means a read, as we write to user space */
1103 retval
= locks_verify_area((type
== VERIFY_WRITE
1104 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
1105 inode
, file
, file
->f_pos
, tot_len
);
1109 /* VERIFY_WRITE actually means a read, as we write to user space */
1110 fnv
= (type
== VERIFY_WRITE
? file
->f_op
->readv
: file
->f_op
->writev
);
1112 retval
= fnv(file
, iov
, count
, &file
->f_pos
);
1116 fn
= (type
== VERIFY_WRITE
? file
->f_op
->read
:
1117 (io_fn_t
) file
->f_op
->write
);
1124 base
= ivp
->iov_base
;
1128 nr
= fn(file
, base
, len
, &file
->f_pos
);
1139 if (iov
!= iovstack
)
1145 asmlinkage
long sys32_readv(int fd
, struct iovec32
*vector
, u32 count
)
1154 if (file
->f_op
&& (file
->f_mode
& FMODE_READ
) &&
1155 (file
->f_op
->readv
|| file
->f_op
->read
))
1156 ret
= do_readv_writev32(VERIFY_WRITE
, file
, vector
, count
);
1163 asmlinkage
long sys32_writev(int fd
, struct iovec32
*vector
, u32 count
)
1171 if (file
->f_op
&& (file
->f_mode
& FMODE_WRITE
) &&
1172 (file
->f_op
->writev
|| file
->f_op
->write
))
1173 ret
= do_readv_writev32(VERIFY_READ
, file
, vector
, count
);
1180 /* readdir & getdents */
1182 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
1183 #define ROUND_UP(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1185 struct old_linux_dirent32
{
1188 unsigned short d_namlen
;
1192 struct readdir_callback32
{
1193 struct old_linux_dirent32
* dirent
;
1197 static int fillonedir(void * __buf
, const char * name
, int namlen
,
1198 off_t offset
, ino_t ino
, unsigned int d_type
)
1200 struct readdir_callback32
* buf
= (struct readdir_callback32
*) __buf
;
1201 struct old_linux_dirent32
* dirent
;
1206 dirent
= buf
->dirent
;
1207 put_user(ino
, &dirent
->d_ino
);
1208 put_user(offset
, &dirent
->d_offset
);
1209 put_user(namlen
, &dirent
->d_namlen
);
1210 copy_to_user(dirent
->d_name
, name
, namlen
);
1211 put_user(0, dirent
->d_name
+ namlen
);
1215 asmlinkage
int old32_readdir(unsigned int fd
, struct old_linux_dirent32
*dirent
, unsigned int count
)
1219 struct readdir_callback32 buf
;
1226 buf
.dirent
= dirent
;
1228 error
= vfs_readdir(file
, fillonedir
, &buf
);
1239 struct linux_dirent32
{
1242 unsigned short d_reclen
;
1246 struct getdents_callback32
{
1247 struct linux_dirent32
* current_dir
;
1248 struct linux_dirent32
* previous
;
1253 static int filldir(void * __buf
, const char * name
, int namlen
, off_t offset
, ino_t ino
,
1254 unsigned int d_type
)
1256 struct linux_dirent32
* dirent
;
1257 struct getdents_callback32
* buf
= (struct getdents_callback32
*) __buf
;
1258 int reclen
= ROUND_UP(NAME_OFFSET(dirent
) + namlen
+ 1);
1260 buf
->error
= -EINVAL
; /* only used if we fail.. */
1261 if (reclen
> buf
->count
)
1263 dirent
= buf
->previous
;
1265 put_user(offset
, &dirent
->d_off
);
1266 dirent
= buf
->current_dir
;
1267 buf
->previous
= dirent
;
1268 put_user(ino
, &dirent
->d_ino
);
1269 put_user(reclen
, &dirent
->d_reclen
);
1270 copy_to_user(dirent
->d_name
, name
, namlen
);
1271 put_user(0, dirent
->d_name
+ namlen
);
1272 ((char *) dirent
) += reclen
;
1273 buf
->current_dir
= dirent
;
1274 buf
->count
-= reclen
;
1278 asmlinkage
int sys32_getdents(unsigned int fd
, struct linux_dirent32
*dirent
, unsigned int count
)
1281 struct linux_dirent32
* lastdirent
;
1282 struct getdents_callback32 buf
;
1289 buf
.current_dir
= dirent
;
1290 buf
.previous
= NULL
;
1294 error
= vfs_readdir(file
, filldir
, &buf
);
1297 lastdirent
= buf
.previous
;
1300 put_user(file
->f_pos
, &lastdirent
->d_off
);
1301 error
= count
- buf
.count
;
1309 /* end of readdir & getdents */
1312 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1313 * 64-bit unsigned longs.
1317 get_fd_set32(unsigned long n
, unsigned long *fdset
, u32
*ufdset
)
1322 if (verify_area(VERIFY_WRITE
, ufdset
, n
*sizeof(u32
)))
1329 __get_user(l
, ufdset
);
1330 __get_user(h
, ufdset
+1);
1332 *fdset
++ = h
<< 32 | l
;
1336 __get_user(*fdset
, ufdset
);
1338 /* Tricky, must clear full unsigned long in the
1339 * kernel fdset at the end, this makes sure that
1342 memset(fdset
, 0, ((n
+ 1) & ~1)*sizeof(u32
));
1348 set_fd_set32(unsigned long n
, u32
*ufdset
, unsigned long *fdset
)
1361 __put_user(l
, ufdset
);
1362 __put_user(h
, ufdset
+1);
1367 __put_user(*fdset
, ufdset
);
1370 #define MAX_SELECT_SECONDS \
1371 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1373 asmlinkage
int sys32_select(int n
, u32
*inp
, u32
*outp
, u32
*exp
, u32 tvp_x
)
1376 struct timeval32
*tvp
= (struct timeval32
*)AA(tvp_x
);
1382 timeout
= MAX_SCHEDULE_TIMEOUT
;
1386 if ((ret
= verify_area(VERIFY_READ
, tvp
, sizeof(*tvp
)))
1387 || (ret
= __get_user(sec
, &tvp
->tv_sec
))
1388 || (ret
= __get_user(usec
, &tvp
->tv_usec
)))
1392 if(sec
< 0 || usec
< 0)
1395 if ((unsigned long) sec
< MAX_SELECT_SECONDS
) {
1396 timeout
= (usec
+ 1000000/HZ
- 1) / (1000000/HZ
);
1397 timeout
+= sec
* (unsigned long) HZ
;
1404 if (n
> current
->files
->max_fdset
)
1405 n
= current
->files
->max_fdset
;
1408 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1409 * since we used fdset we need to allocate memory in units of
1413 size
= FDS_BYTES(n
);
1414 bits
= kmalloc(6 * size
, GFP_KERNEL
);
1417 fds
.in
= (unsigned long *) bits
;
1418 fds
.out
= (unsigned long *) (bits
+ size
);
1419 fds
.ex
= (unsigned long *) (bits
+ 2*size
);
1420 fds
.res_in
= (unsigned long *) (bits
+ 3*size
);
1421 fds
.res_out
= (unsigned long *) (bits
+ 4*size
);
1422 fds
.res_ex
= (unsigned long *) (bits
+ 5*size
);
1424 nn
= (n
+ 8*sizeof(u32
) - 1) / (8*sizeof(u32
));
1425 if ((ret
= get_fd_set32(nn
, fds
.in
, inp
)) ||
1426 (ret
= get_fd_set32(nn
, fds
.out
, outp
)) ||
1427 (ret
= get_fd_set32(nn
, fds
.ex
, exp
)))
1429 zero_fd_set(n
, fds
.res_in
);
1430 zero_fd_set(n
, fds
.res_out
);
1431 zero_fd_set(n
, fds
.res_ex
);
1433 ret
= do_select(n
, &fds
, &timeout
);
1435 if (tvp
&& !(current
->personality
& STICKY_TIMEOUTS
)) {
1436 time_t sec
= 0, usec
= 0;
1439 usec
= timeout
% HZ
;
1440 usec
*= (1000000/HZ
);
1442 put_user(sec
, &tvp
->tv_sec
);
1443 put_user(usec
, &tvp
->tv_usec
);
1449 ret
= -ERESTARTNOHAND
;
1450 if (signal_pending(current
))
1455 set_fd_set32(nn
, inp
, fds
.res_in
);
1456 set_fd_set32(nn
, outp
, fds
.res_out
);
1457 set_fd_set32(nn
, exp
, fds
.res_ex
);
1465 static int cp_new_stat32(struct inode
*inode
, struct stat32
*statbuf
)
1467 unsigned long ino
, blksize
, blocks
;
1474 time_t atime
, mtime
, ctime
;
1477 /* Stream the loads of inode data into the load buffer,
1478 * then we push it all into the store buffer below. This
1479 * should give optimal cache performance.
1483 mode
= inode
->i_mode
;
1484 nlink
= inode
->i_nlink
;
1487 rdev
= inode
->i_rdev
;
1488 size
= inode
->i_size
;
1489 atime
= inode
->i_atime
;
1490 mtime
= inode
->i_mtime
;
1491 ctime
= inode
->i_ctime
;
1492 blksize
= inode
->i_blksize
;
1493 blocks
= inode
->i_blocks
;
1495 err
= put_user(kdev_t_to_nr(dev
), &statbuf
->st_dev
);
1496 err
|= put_user(ino
, &statbuf
->st_ino
);
1497 err
|= put_user(mode
, &statbuf
->st_mode
);
1498 err
|= put_user(nlink
, &statbuf
->st_nlink
);
1499 err
|= put_user(high2lowuid(uid
), &statbuf
->st_uid
);
1500 err
|= put_user(high2lowgid(gid
), &statbuf
->st_gid
);
1501 err
|= put_user(kdev_t_to_nr(rdev
), &statbuf
->st_rdev
);
1502 err
|= put_user(size
, &statbuf
->st_size
);
1503 err
|= put_user(atime
, &statbuf
->st_atime
);
1504 err
|= put_user(0, &statbuf
->__unused1
);
1505 err
|= put_user(mtime
, &statbuf
->st_mtime
);
1506 err
|= put_user(0, &statbuf
->__unused2
);
1507 err
|= put_user(ctime
, &statbuf
->st_ctime
);
1508 err
|= put_user(0, &statbuf
->__unused3
);
1510 err
|= put_user(blksize
, &statbuf
->st_blksize
);
1511 err
|= put_user(blocks
, &statbuf
->st_blocks
);
1513 unsigned int tmp_blocks
;
1516 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
1517 tmp_blocks
= (size
+ BLOCK_SIZE
- 1) / BLOCK_SIZE
;
1518 if (tmp_blocks
> D_B
) {
1519 unsigned int indirect
;
1521 indirect
= (tmp_blocks
- D_B
+ I_B
- 1) / I_B
;
1522 tmp_blocks
+= indirect
;
1524 indirect
= (indirect
- 1 + I_B
- 1) / I_B
;
1525 tmp_blocks
+= indirect
;
1530 err
|= put_user(BLOCK_SIZE
, &statbuf
->st_blksize
);
1531 err
|= put_user((BLOCK_SIZE
/ 512) * tmp_blocks
, &statbuf
->st_blocks
);
1535 err
|= put_user(0, &statbuf
->__unused4
[0]);
1536 err
|= put_user(0, &statbuf
->__unused4
[1]);
1541 /* Perhaps this belongs in fs.h or similar. -DaveM */
1542 static __inline__
int
1543 do_revalidate(struct dentry
*dentry
)
1545 struct inode
* inode
= dentry
->d_inode
;
1546 if (inode
->i_op
&& inode
->i_op
->revalidate
)
1547 return inode
->i_op
->revalidate(dentry
);
1551 asmlinkage
int sys32_newstat(char * filename
, struct stat32
*statbuf
)
1553 struct nameidata nd
;
1556 error
= user_path_walk(filename
, &nd
);
1558 error
= do_revalidate(nd
.dentry
);
1560 error
= cp_new_stat32(nd
.dentry
->d_inode
, statbuf
);
1566 asmlinkage
int sys32_newlstat(char * filename
, struct stat32
*statbuf
)
1568 struct nameidata nd
;
1571 error
= user_path_walk_link(filename
, &nd
);
1573 error
= do_revalidate(nd
.dentry
);
1575 error
= cp_new_stat32(nd
.dentry
->d_inode
, statbuf
);
1582 asmlinkage
int sys32_newfstat(unsigned int fd
, struct stat32
*statbuf
)
1589 struct dentry
* dentry
= f
->f_dentry
;
1591 err
= do_revalidate(dentry
);
1593 err
= cp_new_stat32(dentry
->d_inode
, statbuf
);
1599 extern asmlinkage
int sys_sysfs(int option
, unsigned long arg1
, unsigned long arg2
);
1601 asmlinkage
int sys32_sysfs(int option
, u32 arg1
, u32 arg2
)
1603 return sys_sysfs(option
, arg1
, arg2
);
1606 struct ncp_mount_data32
{
1608 unsigned int ncp_fd
;
1609 __kernel_uid_t32 mounted_uid
;
1610 __kernel_pid_t32 wdog_pid
;
1611 unsigned char mounted_vol
[NCP_VOLNAME_LEN
+ 1];
1612 unsigned int time_out
;
1613 unsigned int retry_count
;
1615 __kernel_uid_t32 uid
;
1616 __kernel_gid_t32 gid
;
1617 __kernel_mode_t32 file_mode
;
1618 __kernel_mode_t32 dir_mode
;
1621 static void *do_ncp_super_data_conv(void *raw_data
)
1623 struct ncp_mount_data
*n
= (struct ncp_mount_data
*)raw_data
;
1624 struct ncp_mount_data32
*n32
= (struct ncp_mount_data32
*)raw_data
;
1626 n
->dir_mode
= n32
->dir_mode
;
1627 n
->file_mode
= n32
->file_mode
;
1628 n
->gid
= low2highgid(n32
->gid
);
1629 n
->uid
= low2highuid(n32
->uid
);
1630 memmove (n
->mounted_vol
, n32
->mounted_vol
, (sizeof (n32
->mounted_vol
) + 3 * sizeof (unsigned int)));
1631 n
->wdog_pid
= n32
->wdog_pid
;
1632 n
->mounted_uid
= low2highuid(n32
->mounted_uid
);
1636 struct smb_mount_data32
{
1638 __kernel_uid_t32 mounted_uid
;
1639 __kernel_uid_t32 uid
;
1640 __kernel_gid_t32 gid
;
1641 __kernel_mode_t32 file_mode
;
1642 __kernel_mode_t32 dir_mode
;
1645 static void *do_smb_super_data_conv(void *raw_data
)
1647 struct smb_mount_data
*s
= (struct smb_mount_data
*)raw_data
;
1648 struct smb_mount_data32
*s32
= (struct smb_mount_data32
*)raw_data
;
1650 s
->version
= s32
->version
;
1651 s
->mounted_uid
= low2highuid(s32
->mounted_uid
);
1652 s
->uid
= low2highuid(s32
->uid
);
1653 s
->gid
= low2highgid(s32
->gid
);
1654 s
->file_mode
= s32
->file_mode
;
1655 s
->dir_mode
= s32
->dir_mode
;
1659 static int copy_mount_stuff_to_kernel(const void *user
, unsigned long *kernel
)
1663 struct vm_area_struct
*vma
;
1668 vma
= find_vma(current
->mm
, (unsigned long)user
);
1669 if(!vma
|| (unsigned long)user
< vma
->vm_start
)
1671 if(!(vma
->vm_flags
& VM_READ
))
1673 i
= vma
->vm_end
- (unsigned long) user
;
1674 if(PAGE_SIZE
<= (unsigned long) i
)
1676 if(!(page
= __get_free_page(GFP_KERNEL
)))
1678 if(copy_from_user((void *) page
, user
, i
)) {
1686 #define SMBFS_NAME "smbfs"
1687 #define NCPFS_NAME "ncpfs"
1689 asmlinkage
int sys32_mount(char *dev_name
, char *dir_name
, char *type
, unsigned long new_flags
, u32 data
)
1691 unsigned long type_page
= 0;
1692 unsigned long data_page
= 0;
1693 unsigned long dev_page
= 0;
1694 unsigned long dir_page
= 0;
1695 int err
, is_smb
, is_ncp
;
1697 is_smb
= is_ncp
= 0;
1699 err
= copy_mount_stuff_to_kernel((const void *)type
, &type_page
);
1708 is_smb
= !strcmp((char *)type_page
, SMBFS_NAME
);
1709 is_ncp
= !strcmp((char *)type_page
, NCPFS_NAME
);
1711 err
= copy_mount_stuff_to_kernel((const void *)AA(data
), &data_page
);
1715 err
= copy_mount_stuff_to_kernel(dev_name
, &dev_page
);
1719 err
= copy_mount_stuff_to_kernel(dir_name
, &dir_page
);
1723 if (!is_smb
&& !is_ncp
) {
1725 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1726 (char*)type_page
, new_flags
, (char*)data_page
);
1730 do_ncp_super_data_conv((void *)data_page
);
1732 do_smb_super_data_conv((void *)data_page
);
1735 err
= do_mount((char*)dev_page
, (char*)dir_page
,
1736 (char*)type_page
, new_flags
, (char*)data_page
);
1739 free_page(dir_page
);
1742 free_page(dev_page
);
1745 free_page(data_page
);
1748 free_page(type_page
);
1755 struct timeval32 ru_utime
;
1756 struct timeval32 ru_stime
;
1773 static int put_rusage (struct rusage32
*ru
, struct rusage
*r
)
1777 err
= put_user (r
->ru_utime
.tv_sec
, &ru
->ru_utime
.tv_sec
);
1778 err
|= __put_user (r
->ru_utime
.tv_usec
, &ru
->ru_utime
.tv_usec
);
1779 err
|= __put_user (r
->ru_stime
.tv_sec
, &ru
->ru_stime
.tv_sec
);
1780 err
|= __put_user (r
->ru_stime
.tv_usec
, &ru
->ru_stime
.tv_usec
);
1781 err
|= __put_user (r
->ru_maxrss
, &ru
->ru_maxrss
);
1782 err
|= __put_user (r
->ru_ixrss
, &ru
->ru_ixrss
);
1783 err
|= __put_user (r
->ru_idrss
, &ru
->ru_idrss
);
1784 err
|= __put_user (r
->ru_isrss
, &ru
->ru_isrss
);
1785 err
|= __put_user (r
->ru_minflt
, &ru
->ru_minflt
);
1786 err
|= __put_user (r
->ru_majflt
, &ru
->ru_majflt
);
1787 err
|= __put_user (r
->ru_nswap
, &ru
->ru_nswap
);
1788 err
|= __put_user (r
->ru_inblock
, &ru
->ru_inblock
);
1789 err
|= __put_user (r
->ru_oublock
, &ru
->ru_oublock
);
1790 err
|= __put_user (r
->ru_msgsnd
, &ru
->ru_msgsnd
);
1791 err
|= __put_user (r
->ru_msgrcv
, &ru
->ru_msgrcv
);
1792 err
|= __put_user (r
->ru_nsignals
, &ru
->ru_nsignals
);
1793 err
|= __put_user (r
->ru_nvcsw
, &ru
->ru_nvcsw
);
1794 err
|= __put_user (r
->ru_nivcsw
, &ru
->ru_nivcsw
);
1798 extern asmlinkage
int sys_wait4(pid_t pid
,unsigned int * stat_addr
,
1799 int options
, struct rusage
* ru
);
1801 asmlinkage
int sys32_wait4(__kernel_pid_t32 pid
, unsigned int *stat_addr
, int options
, struct rusage32
*ru
)
1804 return sys_wait4(pid
, stat_addr
, options
, NULL
);
1808 unsigned int status
;
1809 mm_segment_t old_fs
= get_fs();
1812 ret
= sys_wait4(pid
, stat_addr
? &status
: NULL
, options
, &r
);
1814 if (put_rusage (ru
, &r
)) return -EFAULT
;
1815 if (stat_addr
&& put_user (status
, stat_addr
))
1830 unsigned short procs
;
1834 extern asmlinkage
int sys_sysinfo(struct sysinfo
*info
);
1836 asmlinkage
int sys32_sysinfo(struct sysinfo32
*info
)
1840 mm_segment_t old_fs
= get_fs ();
1843 ret
= sys_sysinfo(&s
);
1845 err
= put_user (s
.uptime
, &info
->uptime
);
1846 err
|= __put_user (s
.loads
[0], &info
->loads
[0]);
1847 err
|= __put_user (s
.loads
[1], &info
->loads
[1]);
1848 err
|= __put_user (s
.loads
[2], &info
->loads
[2]);
1849 err
|= __put_user (s
.totalram
, &info
->totalram
);
1850 err
|= __put_user (s
.freeram
, &info
->freeram
);
1851 err
|= __put_user (s
.sharedram
, &info
->sharedram
);
1852 err
|= __put_user (s
.bufferram
, &info
->bufferram
);
1853 err
|= __put_user (s
.totalswap
, &info
->totalswap
);
1854 err
|= __put_user (s
.freeswap
, &info
->freeswap
);
1855 err
|= __put_user (s
.procs
, &info
->procs
);
1866 extern asmlinkage
int sys_sched_rr_get_interval(pid_t pid
, struct timespec
*interval
);
1868 asmlinkage
int sys32_sched_rr_get_interval(__kernel_pid_t32 pid
, struct timespec32
*interval
)
1872 mm_segment_t old_fs
= get_fs ();
1875 ret
= sys_sched_rr_get_interval(pid
, &t
);
1877 if (put_user (t
.tv_sec
, &interval
->tv_sec
) ||
1878 __put_user (t
.tv_nsec
, &interval
->tv_nsec
))
1883 extern asmlinkage
int sys_nanosleep(struct timespec
*rqtp
, struct timespec
*rmtp
);
1885 asmlinkage
int sys32_nanosleep(struct timespec32
*rqtp
, struct timespec32
*rmtp
)
1889 mm_segment_t old_fs
= get_fs ();
1891 if (get_user (t
.tv_sec
, &rqtp
->tv_sec
) ||
1892 __get_user (t
.tv_nsec
, &rqtp
->tv_nsec
))
1895 ret
= sys_nanosleep(&t
, rmtp
? &t
: NULL
);
1897 if (rmtp
&& ret
== -EINTR
) {
1898 if (__put_user (t
.tv_sec
, &rmtp
->tv_sec
) ||
1899 __put_user (t
.tv_nsec
, &rmtp
->tv_nsec
))
1905 extern asmlinkage
int sys_sigprocmask(int how
, old_sigset_t
*set
, old_sigset_t
*oset
);
1907 asmlinkage
int sys32_sigprocmask(int how
, old_sigset_t32
*set
, old_sigset_t32
*oset
)
1911 mm_segment_t old_fs
= get_fs();
1913 if (set
&& get_user (s
, set
)) return -EFAULT
;
1915 ret
= sys_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
);
1917 if (ret
) return ret
;
1918 if (oset
&& put_user (s
, oset
)) return -EFAULT
;
1922 extern asmlinkage
int sys_rt_sigprocmask(int how
, sigset_t
*set
, sigset_t
*oset
, size_t sigsetsize
);
1924 asmlinkage
int sys32_rt_sigprocmask(int how
, sigset_t32
*set
, sigset_t32
*oset
, __kernel_size_t32 sigsetsize
)
1929 mm_segment_t old_fs
= get_fs();
1932 if (copy_from_user (&s32
, set
, sizeof(sigset_t32
)))
1934 switch (_NSIG_WORDS
) {
1935 case 4: s
.sig
[3] = s32
.sig
[6] | (((long)s32
.sig
[7]) << 32);
1936 case 3: s
.sig
[2] = s32
.sig
[4] | (((long)s32
.sig
[5]) << 32);
1937 case 2: s
.sig
[1] = s32
.sig
[2] | (((long)s32
.sig
[3]) << 32);
1938 case 1: s
.sig
[0] = s32
.sig
[0] | (((long)s32
.sig
[1]) << 32);
1942 ret
= sys_rt_sigprocmask(how
, set
? &s
: NULL
, oset
? &s
: NULL
, sigsetsize
);
1944 if (ret
) return ret
;
1946 switch (_NSIG_WORDS
) {
1947 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
1948 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
1949 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
1950 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
1952 if (copy_to_user (oset
, &s32
, sizeof(sigset_t32
)))
1958 extern asmlinkage
int sys_sigpending(old_sigset_t
*set
);
1960 asmlinkage
int sys32_sigpending(old_sigset_t32
*set
)
1964 mm_segment_t old_fs
= get_fs();
1967 ret
= sys_sigpending(&s
);
1969 if (put_user (s
, set
)) return -EFAULT
;
1973 extern asmlinkage
int sys_rt_sigpending(sigset_t
*set
, size_t sigsetsize
);
1975 asmlinkage
int sys32_rt_sigpending(sigset_t32
*set
, __kernel_size_t32 sigsetsize
)
1980 mm_segment_t old_fs
= get_fs();
1983 ret
= sys_rt_sigpending(&s
, sigsetsize
);
1986 switch (_NSIG_WORDS
) {
1987 case 4: s32
.sig
[7] = (s
.sig
[3] >> 32); s32
.sig
[6] = s
.sig
[3];
1988 case 3: s32
.sig
[5] = (s
.sig
[2] >> 32); s32
.sig
[4] = s
.sig
[2];
1989 case 2: s32
.sig
[3] = (s
.sig
[1] >> 32); s32
.sig
[2] = s
.sig
[1];
1990 case 1: s32
.sig
[1] = (s
.sig
[0] >> 32); s32
.sig
[0] = s
.sig
[0];
1992 if (copy_to_user (set
, &s32
, sizeof(sigset_t32
)))
1999 sys32_rt_sigtimedwait(sigset_t32
*uthese
, siginfo_t32
*uinfo
,
2000 struct timespec32
*uts
, __kernel_size_t32 sigsetsize
)
2009 /* XXX: Don't preclude handling different sized sigset_t's. */
2010 if (sigsetsize
!= sizeof(sigset_t
))
2013 if (copy_from_user (&these32
, uthese
, sizeof(sigset_t32
)))
2016 switch (_NSIG_WORDS
) {
2017 case 4: these
.sig
[3] = these32
.sig
[6] | (((long)these32
.sig
[7]) << 32);
2018 case 3: these
.sig
[2] = these32
.sig
[4] | (((long)these32
.sig
[5]) << 32);
2019 case 2: these
.sig
[1] = these32
.sig
[2] | (((long)these32
.sig
[3]) << 32);
2020 case 1: these
.sig
[0] = these32
.sig
[0] | (((long)these32
.sig
[1]) << 32);
2024 * Invert the set of allowed signals to get those we
2027 sigdelsetmask(&these
, sigmask(SIGKILL
)|sigmask(SIGSTOP
));
2031 if (get_user (ts
.tv_sec
, &uts
->tv_sec
) ||
2032 get_user (ts
.tv_nsec
, &uts
->tv_nsec
))
2034 if (ts
.tv_nsec
>= 1000000000L || ts
.tv_nsec
< 0
2039 spin_lock_irq(¤t
->sigmask_lock
);
2040 sig
= dequeue_signal(&these
, &info
);
2042 /* None ready -- temporarily unblock those we're interested
2043 in so that we'll be awakened when they arrive. */
2044 sigset_t oldblocked
= current
->blocked
;
2045 sigandsets(¤t
->blocked
, ¤t
->blocked
, &these
);
2046 recalc_sigpending(current
);
2047 spin_unlock_irq(¤t
->sigmask_lock
);
2049 timeout
= MAX_SCHEDULE_TIMEOUT
;
2051 timeout
= (timespec_to_jiffies(&ts
)
2052 + (ts
.tv_sec
|| ts
.tv_nsec
));
2054 current
->state
= TASK_INTERRUPTIBLE
;
2055 timeout
= schedule_timeout(timeout
);
2057 spin_lock_irq(¤t
->sigmask_lock
);
2058 sig
= dequeue_signal(&these
, &info
);
2059 current
->blocked
= oldblocked
;
2060 recalc_sigpending(current
);
2062 spin_unlock_irq(¤t
->sigmask_lock
);
2067 if (copy_siginfo_to_user32(uinfo
, &info
))
2079 extern asmlinkage
int
2080 sys_rt_sigqueueinfo(int pid
, int sig
, siginfo_t
*uinfo
);
2083 sys32_rt_sigqueueinfo(int pid
, int sig
, siginfo_t32
*uinfo
)
2087 mm_segment_t old_fs
= get_fs();
2089 if (copy_from_user (&info
, uinfo
, 3*sizeof(int)) ||
2090 copy_from_user (info
._sifields
._pad
, uinfo
->_sifields
._pad
, SI_PAD_SIZE
))
2093 ret
= sys_rt_sigqueueinfo(pid
, sig
, &info
);
2099 __kernel_clock_t32 tms_utime
;
2100 __kernel_clock_t32 tms_stime
;
2101 __kernel_clock_t32 tms_cutime
;
2102 __kernel_clock_t32 tms_cstime
;
2105 extern asmlinkage
long sys_times(struct tms
* tbuf
);
2107 asmlinkage
long sys32_times(struct tms32
*tbuf
)
2111 mm_segment_t old_fs
= get_fs ();
2115 ret
= sys_times(tbuf
? &t
: NULL
);
2118 err
= put_user (t
.tms_utime
, &tbuf
->tms_utime
);
2119 err
|= __put_user (t
.tms_stime
, &tbuf
->tms_stime
);
2120 err
|= __put_user (t
.tms_cutime
, &tbuf
->tms_cutime
);
2121 err
|= __put_user (t
.tms_cstime
, &tbuf
->tms_cstime
);
2128 #define RLIM_INFINITY32 0x7fffffff
2129 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
2136 extern asmlinkage
int sys_getrlimit(unsigned int resource
, struct rlimit
*rlim
);
2138 asmlinkage
int sys32_getrlimit(unsigned int resource
, struct rlimit32
*rlim
)
2142 mm_segment_t old_fs
= get_fs ();
2145 ret
= sys_getrlimit(resource
, &r
);
2148 ret
= put_user (RESOURCE32(r
.rlim_cur
), &rlim
->rlim_cur
);
2149 ret
|= __put_user (RESOURCE32(r
.rlim_max
), &rlim
->rlim_max
);
2154 extern asmlinkage
int sys_setrlimit(unsigned int resource
, struct rlimit
*rlim
);
2156 asmlinkage
int sys32_setrlimit(unsigned int resource
, struct rlimit32
*rlim
)
2160 mm_segment_t old_fs
= get_fs ();
2162 if (resource
>= RLIM_NLIMITS
) return -EINVAL
;
2163 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
2164 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
2166 if (r
.rlim_cur
== RLIM_INFINITY32
)
2167 r
.rlim_cur
= RLIM_INFINITY
;
2168 if (r
.rlim_max
== RLIM_INFINITY32
)
2169 r
.rlim_max
= RLIM_INFINITY
;
2171 ret
= sys_setrlimit(resource
, &r
);
2176 extern asmlinkage
int sys_getrusage(int who
, struct rusage
*ru
);
2178 asmlinkage
int sys32_getrusage(int who
, struct rusage32
*ru
)
2182 mm_segment_t old_fs
= get_fs();
2185 ret
= sys_getrusage(who
, &r
);
2187 if (put_rusage (ru
, &r
)) return -EFAULT
;
2191 /* XXX This really belongs in some header file... -DaveM */
2192 #define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
2193 16 for IP, 16 for IPX,
2195 about 80 for AX.25 */
2197 extern struct socket
*sockfd_lookup(int fd
, int *err
);
2199 /* XXX This as well... */
2200 extern __inline__
void sockfd_put(struct socket
*sock
)
2209 __kernel_size_t32 msg_iovlen
;
2211 __kernel_size_t32 msg_controllen
;
2216 __kernel_size_t32 cmsg_len
;
2222 #define __CMSG32_NXTHDR(ctl, len, cmsg, cmsglen) __cmsg32_nxthdr((ctl),(len),(cmsg),(cmsglen))
2223 #define CMSG32_NXTHDR(mhdr, cmsg, cmsglen) cmsg32_nxthdr((mhdr), (cmsg), (cmsglen))
2225 #define CMSG32_ALIGN(len) ( ((len)+sizeof(int)-1) & ~(sizeof(int)-1) )
2227 #define CMSG32_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr32))))
2228 #define CMSG32_SPACE(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + CMSG32_ALIGN(len))
2229 #define CMSG32_LEN(len) (CMSG32_ALIGN(sizeof(struct cmsghdr32)) + (len))
2231 #define __CMSG32_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr32) ? \
2232 (struct cmsghdr32 *)(ctl) : \
2233 (struct cmsghdr32 *)NULL)
2234 #define CMSG32_FIRSTHDR(msg) __CMSG32_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
2236 __inline__
struct cmsghdr32
*__cmsg32_nxthdr(void *__ctl
, __kernel_size_t __size
,
2237 struct cmsghdr32
*__cmsg
, int __cmsg_len
)
2239 struct cmsghdr32
* __ptr
;
2241 __ptr
= (struct cmsghdr32
*)(((unsigned char *) __cmsg
) +
2242 CMSG32_ALIGN(__cmsg_len
));
2243 if ((unsigned long)((char*)(__ptr
+1) - (char *) __ctl
) > __size
)
2249 __inline__
struct cmsghdr32
*cmsg32_nxthdr (struct msghdr
*__msg
,
2250 struct cmsghdr32
*__cmsg
,
2253 return __cmsg32_nxthdr(__msg
->msg_control
, __msg
->msg_controllen
,
2254 __cmsg
, __cmsg_len
);
2257 static inline int iov_from_user32_to_kern(struct iovec
*kiov
,
2258 struct iovec32
*uiov32
,
2266 if(get_user(len
, &uiov32
->iov_len
) ||
2267 get_user(buf
, &uiov32
->iov_base
)) {
2272 kiov
->iov_base
= (void *)A(buf
);
2273 kiov
->iov_len
= (__kernel_size_t
) len
;
2281 static inline int msghdr_from_user32_to_kern(struct msghdr
*kmsg
,
2282 struct msghdr32
*umsg
)
2284 u32 tmp1
, tmp2
, tmp3
;
2287 err
= get_user(tmp1
, &umsg
->msg_name
);
2288 err
|= __get_user(tmp2
, &umsg
->msg_iov
);
2289 err
|= __get_user(tmp3
, &umsg
->msg_control
);
2293 kmsg
->msg_name
= (void *)A(tmp1
);
2294 kmsg
->msg_iov
= (struct iovec
*)A(tmp2
);
2295 kmsg
->msg_control
= (void *)A(tmp3
);
2297 err
= get_user(kmsg
->msg_namelen
, &umsg
->msg_namelen
);
2298 err
|= get_user(kmsg
->msg_iovlen
, &umsg
->msg_iovlen
);
2299 err
|= get_user(kmsg
->msg_controllen
, &umsg
->msg_controllen
);
2300 err
|= get_user(kmsg
->msg_flags
, &umsg
->msg_flags
);
2305 /* I've named the args so it is easy to tell whose space the pointers are in. */
2306 static int verify_iovec32(struct msghdr
*kern_msg
, struct iovec
*kern_iov
,
2307 char *kern_address
, int mode
)
2311 if(kern_msg
->msg_namelen
) {
2312 if(mode
==VERIFY_READ
) {
2313 int err
= move_addr_to_kernel(kern_msg
->msg_name
,
2314 kern_msg
->msg_namelen
,
2319 kern_msg
->msg_name
= kern_address
;
2321 kern_msg
->msg_name
= NULL
;
2323 if(kern_msg
->msg_iovlen
> UIO_FASTIOV
) {
2324 kern_iov
= kmalloc(kern_msg
->msg_iovlen
* sizeof(struct iovec
),
2330 tot_len
= iov_from_user32_to_kern(kern_iov
,
2331 (struct iovec32
*)kern_msg
->msg_iov
,
2332 kern_msg
->msg_iovlen
);
2334 kern_msg
->msg_iov
= kern_iov
;
2335 else if(kern_msg
->msg_iovlen
> UIO_FASTIOV
)
2341 /* There is a lot of hair here because the alignment rules (and
2342 * thus placement) of cmsg headers and length are different for
2343 * 32-bit apps. -DaveM
2345 static int cmsghdr_from_user32_to_kern(struct msghdr
*kmsg
,
2346 unsigned char *stackbuf
, int stackbuf_size
)
2348 struct cmsghdr32
*ucmsg
;
2349 struct cmsghdr
*kcmsg
, *kcmsg_base
;
2350 __kernel_size_t32 ucmlen
;
2351 __kernel_size_t kcmlen
, tmp
;
2354 kcmsg_base
= kcmsg
= (struct cmsghdr
*)stackbuf
;
2355 ucmsg
= CMSG32_FIRSTHDR(kmsg
);
2356 while(ucmsg
!= NULL
) {
2357 if(get_user(ucmlen
, &ucmsg
->cmsg_len
))
2361 if(CMSG32_ALIGN(ucmlen
) <
2362 CMSG32_ALIGN(sizeof(struct cmsghdr32
)))
2364 if((unsigned long)(((char *)ucmsg
- (char *)kmsg
->msg_control
)
2365 + ucmlen
) > kmsg
->msg_controllen
)
2368 tmp
= ((ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
))) +
2369 CMSG_ALIGN(sizeof(struct cmsghdr
)));
2371 ucmsg
= CMSG32_NXTHDR(kmsg
, ucmsg
, ucmlen
);
2376 /* The kcmlen holds the 64-bit version of the control length.
2377 * It may not be modified as we do not stick it into the kmsg
2378 * until we have successfully copied over all of the data
2381 if(kcmlen
> stackbuf_size
)
2382 kcmsg_base
= kcmsg
= kmalloc(kcmlen
, GFP_KERNEL
);
2386 /* Now copy them over neatly. */
2387 memset(kcmsg
, 0, kcmlen
);
2388 ucmsg
= CMSG32_FIRSTHDR(kmsg
);
2389 while(ucmsg
!= NULL
) {
2390 __get_user(ucmlen
, &ucmsg
->cmsg_len
);
2391 tmp
= ((ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
))) +
2392 CMSG_ALIGN(sizeof(struct cmsghdr
)));
2393 kcmsg
->cmsg_len
= tmp
;
2394 __get_user(kcmsg
->cmsg_level
, &ucmsg
->cmsg_level
);
2395 __get_user(kcmsg
->cmsg_type
, &ucmsg
->cmsg_type
);
2397 /* Copy over the data. */
2398 if(copy_from_user(CMSG_DATA(kcmsg
),
2400 (ucmlen
- CMSG32_ALIGN(sizeof(*ucmsg
)))))
2401 goto out_free_efault
;
2404 kcmsg
= (struct cmsghdr
*)((char *)kcmsg
+ CMSG_ALIGN(tmp
));
2405 ucmsg
= CMSG32_NXTHDR(kmsg
, ucmsg
, ucmlen
);
2408 /* Ok, looks like we made it. Hook it up and return success. */
2409 kmsg
->msg_control
= kcmsg_base
;
2410 kmsg
->msg_controllen
= kcmlen
;
2414 if(kcmsg_base
!= (struct cmsghdr
*)stackbuf
)
2419 static void put_cmsg32(struct msghdr
*kmsg
, int level
, int type
,
2420 int len
, void *data
)
2422 struct cmsghdr32
*cm
= (struct cmsghdr32
*) kmsg
->msg_control
;
2423 struct cmsghdr32 cmhdr
;
2424 int cmlen
= CMSG32_LEN(len
);
2426 if(cm
== NULL
|| kmsg
->msg_controllen
< sizeof(*cm
)) {
2427 kmsg
->msg_flags
|= MSG_CTRUNC
;
2431 if(kmsg
->msg_controllen
< cmlen
) {
2432 kmsg
->msg_flags
|= MSG_CTRUNC
;
2433 cmlen
= kmsg
->msg_controllen
;
2435 cmhdr
.cmsg_level
= level
;
2436 cmhdr
.cmsg_type
= type
;
2437 cmhdr
.cmsg_len
= cmlen
;
2439 if(copy_to_user(cm
, &cmhdr
, sizeof cmhdr
))
2441 if(copy_to_user(CMSG32_DATA(cm
), data
, cmlen
- sizeof(struct cmsghdr32
)))
2443 cmlen
= CMSG32_SPACE(len
);
2444 kmsg
->msg_control
+= cmlen
;
2445 kmsg
->msg_controllen
-= cmlen
;
2448 static void scm_detach_fds32(struct msghdr
*kmsg
, struct scm_cookie
*scm
)
2450 struct cmsghdr32
*cm
= (struct cmsghdr32
*) kmsg
->msg_control
;
2451 int fdmax
= (kmsg
->msg_controllen
- sizeof(struct cmsghdr32
)) / sizeof(int);
2452 int fdnum
= scm
->fp
->count
;
2453 struct file
**fp
= scm
->fp
->fp
;
2460 for (i
= 0, cmfptr
= (int *) CMSG32_DATA(cm
); i
< fdmax
; i
++, cmfptr
++) {
2462 err
= get_unused_fd();
2466 err
= put_user(new_fd
, cmfptr
);
2468 put_unused_fd(new_fd
);
2471 /* Bump the usage count and install the file. */
2473 fd_install(new_fd
, fp
[i
]);
2477 int cmlen
= CMSG32_LEN(i
* sizeof(int));
2479 err
= put_user(SOL_SOCKET
, &cm
->cmsg_level
);
2481 err
= put_user(SCM_RIGHTS
, &cm
->cmsg_type
);
2483 err
= put_user(cmlen
, &cm
->cmsg_len
);
2485 cmlen
= CMSG32_SPACE(i
* sizeof(int));
2486 kmsg
->msg_control
+= cmlen
;
2487 kmsg
->msg_controllen
-= cmlen
;
2491 kmsg
->msg_flags
|= MSG_CTRUNC
;
2494 * All of the files that fit in the message have had their
2495 * usage counts incremented, so we just free the list.
2500 /* In these cases we (currently) can just copy to data over verbatim
2501 * because all CMSGs created by the kernel have well defined types which
2502 * have the same layout in both the 32-bit and 64-bit API. One must add
2503 * some special cased conversions here if we start sending control messages
2504 * with incompatible types.
2506 * SCM_RIGHTS and SCM_CREDENTIALS are done by hand in recvmsg32 right after
2507 * we do our work. The remaining cases are:
2509 * SOL_IP IP_PKTINFO struct in_pktinfo 32-bit clean
2510 * IP_TTL int 32-bit clean
2511 * IP_TOS __u8 32-bit clean
2512 * IP_RECVOPTS variable length 32-bit clean
2513 * IP_RETOPTS variable length 32-bit clean
2514 * (these last two are clean because the types are defined
2515 * by the IPv4 protocol)
2516 * IP_RECVERR struct sock_extended_err +
2517 * struct sockaddr_in 32-bit clean
2518 * SOL_IPV6 IPV6_RECVERR struct sock_extended_err +
2519 * struct sockaddr_in6 32-bit clean
2520 * IPV6_PKTINFO struct in6_pktinfo 32-bit clean
2521 * IPV6_HOPLIMIT int 32-bit clean
2522 * IPV6_FLOWINFO u32 32-bit clean
2523 * IPV6_HOPOPTS ipv6 hop exthdr 32-bit clean
2524 * IPV6_DSTOPTS ipv6 dst exthdr(s) 32-bit clean
2525 * IPV6_RTHDR ipv6 routing exthdr 32-bit clean
2526 * IPV6_AUTHHDR ipv6 auth exthdr 32-bit clean
2528 static void cmsg32_recvmsg_fixup(struct msghdr
*kmsg
, unsigned long orig_cmsg_uptr
)
2530 unsigned char *workbuf
, *wp
;
2531 unsigned long bufsz
, space_avail
;
2532 struct cmsghdr
*ucmsg
;
2534 bufsz
= ((unsigned long)kmsg
->msg_control
) - orig_cmsg_uptr
;
2535 space_avail
= kmsg
->msg_controllen
+ bufsz
;
2536 wp
= workbuf
= kmalloc(bufsz
, GFP_KERNEL
);
2540 /* To make this more sane we assume the kernel sends back properly
2541 * formatted control messages. Because of how the kernel will truncate
2542 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
2544 ucmsg
= (struct cmsghdr
*) orig_cmsg_uptr
;
2545 while(((unsigned long)ucmsg
) <=
2546 (((unsigned long)kmsg
->msg_control
) - sizeof(struct cmsghdr
))) {
2547 struct cmsghdr32
*kcmsg32
= (struct cmsghdr32
*) wp
;
2550 /* UCMSG is the 64-bit format CMSG entry in user-space.
2551 * KCMSG32 is within the kernel space temporary buffer
2552 * we use to convert into a 32-bit style CMSG.
2554 __get_user(kcmsg32
->cmsg_len
, &ucmsg
->cmsg_len
);
2555 __get_user(kcmsg32
->cmsg_level
, &ucmsg
->cmsg_level
);
2556 __get_user(kcmsg32
->cmsg_type
, &ucmsg
->cmsg_type
);
2558 clen64
= kcmsg32
->cmsg_len
;
2559 copy_from_user(CMSG32_DATA(kcmsg32
), CMSG_DATA(ucmsg
),
2560 clen64
- CMSG_ALIGN(sizeof(*ucmsg
)));
2561 clen32
= ((clen64
- CMSG_ALIGN(sizeof(*ucmsg
))) +
2562 CMSG32_ALIGN(sizeof(struct cmsghdr32
)));
2563 kcmsg32
->cmsg_len
= clen32
;
2565 ucmsg
= (struct cmsghdr
*) (((char *)ucmsg
) + CMSG_ALIGN(clen64
));
2566 wp
= (((char *)kcmsg32
) + CMSG32_ALIGN(clen32
));
2569 /* Copy back fixed up data, and adjust pointers. */
2570 bufsz
= (wp
- workbuf
);
2571 copy_to_user((void *)orig_cmsg_uptr
, workbuf
, bufsz
);
2573 kmsg
->msg_control
= (struct cmsghdr
*)
2574 (((char *)orig_cmsg_uptr
) + bufsz
);
2575 kmsg
->msg_controllen
= space_avail
- bufsz
;
2581 /* If we leave the 64-bit format CMSG chunks in there,
2582 * the application could get confused and crash. So to
2583 * ensure greater recovery, we report no CMSGs.
2585 kmsg
->msg_controllen
+= bufsz
;
2586 kmsg
->msg_control
= (void *) orig_cmsg_uptr
;
2589 asmlinkage
int sys32_sendmsg(int fd
, struct msghdr32
*user_msg
, unsigned user_flags
)
2591 struct socket
*sock
;
2592 char address
[MAX_SOCK_ADDR
];
2593 struct iovec iov
[UIO_FASTIOV
];
2594 unsigned char ctl
[sizeof(struct cmsghdr
) + 20];
2595 unsigned char *ctl_buf
= ctl
;
2596 struct msghdr kern_msg
;
2599 if(msghdr_from_user32_to_kern(&kern_msg
, user_msg
))
2601 if(kern_msg
.msg_iovlen
> UIO_MAXIOV
)
2603 err
= verify_iovec32(&kern_msg
, iov
, address
, VERIFY_READ
);
2608 if(kern_msg
.msg_controllen
) {
2609 err
= cmsghdr_from_user32_to_kern(&kern_msg
, ctl
, sizeof(ctl
));
2612 ctl_buf
= kern_msg
.msg_control
;
2614 kern_msg
.msg_flags
= user_flags
;
2616 sock
= sockfd_lookup(fd
, &err
);
2618 if (sock
->file
->f_flags
& O_NONBLOCK
)
2619 kern_msg
.msg_flags
|= MSG_DONTWAIT
;
2620 err
= sock_sendmsg(sock
, &kern_msg
, total_len
);
2624 /* N.B. Use kfree here, as kern_msg.msg_controllen might change? */
2628 if(kern_msg
.msg_iov
!= iov
)
2629 kfree(kern_msg
.msg_iov
);
2634 asmlinkage
int sys32_recvmsg(int fd
, struct msghdr32
*user_msg
, unsigned int user_flags
)
2636 struct iovec iovstack
[UIO_FASTIOV
];
2637 struct msghdr kern_msg
;
2638 char addr
[MAX_SOCK_ADDR
];
2639 struct socket
*sock
;
2640 struct iovec
*iov
= iovstack
;
2641 struct sockaddr
*uaddr
;
2643 unsigned long cmsg_ptr
;
2644 int err
, total_len
, len
= 0;
2646 if(msghdr_from_user32_to_kern(&kern_msg
, user_msg
))
2648 if(kern_msg
.msg_iovlen
> UIO_MAXIOV
)
2651 uaddr
= kern_msg
.msg_name
;
2652 uaddr_len
= &user_msg
->msg_namelen
;
2653 err
= verify_iovec32(&kern_msg
, iov
, addr
, VERIFY_WRITE
);
2658 cmsg_ptr
= (unsigned long) kern_msg
.msg_control
;
2659 kern_msg
.msg_flags
= 0;
2661 sock
= sockfd_lookup(fd
, &err
);
2663 struct scm_cookie scm
;
2665 if (sock
->file
->f_flags
& O_NONBLOCK
)
2666 user_flags
|= MSG_DONTWAIT
;
2667 memset(&scm
, 0, sizeof(scm
));
2668 err
= sock
->ops
->recvmsg(sock
, &kern_msg
, total_len
,
2672 if(!kern_msg
.msg_control
) {
2673 if(sock
->passcred
|| scm
.fp
)
2674 kern_msg
.msg_flags
|= MSG_CTRUNC
;
2676 __scm_destroy(&scm
);
2678 /* If recvmsg processing itself placed some
2679 * control messages into user space, it's is
2680 * using 64-bit CMSG processing, so we need
2681 * to fix it up before we tack on more stuff.
2683 if((unsigned long) kern_msg
.msg_control
!= cmsg_ptr
)
2684 cmsg32_recvmsg_fixup(&kern_msg
, cmsg_ptr
);
2688 put_cmsg32(&kern_msg
,
2689 SOL_SOCKET
, SCM_CREDENTIALS
,
2690 sizeof(scm
.creds
), &scm
.creds
);
2692 scm_detach_fds32(&kern_msg
, &scm
);
2698 if(uaddr
!= NULL
&& err
>= 0)
2699 err
= move_addr_to_user(addr
, kern_msg
.msg_namelen
, uaddr
, uaddr_len
);
2700 if(cmsg_ptr
!= 0 && err
>= 0) {
2701 unsigned long ucmsg_ptr
= ((unsigned long)kern_msg
.msg_control
);
2702 __kernel_size_t32 uclen
= (__kernel_size_t32
) (ucmsg_ptr
- cmsg_ptr
);
2703 err
|= __put_user(uclen
, &user_msg
->msg_controllen
);
2706 err
= __put_user(kern_msg
.msg_flags
, &user_msg
->msg_flags
);
2707 if(kern_msg
.msg_iov
!= iov
)
2708 kfree(kern_msg
.msg_iov
);
2715 extern asmlinkage
int sys_setsockopt(int fd
, int level
, int optname
,
2716 char *optval
, int optlen
);
2718 static int do_set_attach_filter(int fd
, int level
, int optname
,
2719 char *optval
, int optlen
)
2721 struct sock_fprog32
{
2724 } *fprog32
= (struct sock_fprog32
*)optval
;
2725 struct sock_fprog kfprog
;
2726 struct sock_filter
*kfilter
;
2728 mm_segment_t old_fs
;
2732 if (get_user(kfprog
.len
, &fprog32
->len
) ||
2733 __get_user(uptr
, &fprog32
->filter
))
2736 kfprog
.filter
= (struct sock_filter
*)A(uptr
);
2737 fsize
= kfprog
.len
* sizeof(struct sock_filter
);
2739 kfilter
= (struct sock_filter
*)kmalloc(fsize
, GFP_KERNEL
);
2740 if (kfilter
== NULL
)
2743 if (copy_from_user(kfilter
, kfprog
.filter
, fsize
)) {
2748 kfprog
.filter
= kfilter
;
2752 ret
= sys_setsockopt(fd
, level
, optname
,
2753 (char *)&kfprog
, sizeof(kfprog
));
2761 static int do_set_icmpv6_filter(int fd
, int level
, int optname
,
2762 char *optval
, int optlen
)
2764 struct icmp6_filter kfilter
;
2765 mm_segment_t old_fs
;
2768 if (copy_from_user(&kfilter
, optval
, sizeof(kfilter
)))
2772 for (i
= 0; i
< 8; i
+= 2) {
2773 u32 tmp
= kfilter
.data
[i
];
2775 kfilter
.data
[i
] = kfilter
.data
[i
+ 1];
2776 kfilter
.data
[i
+ 1] = tmp
;
2781 ret
= sys_setsockopt(fd
, level
, optname
,
2782 (char *) &kfilter
, sizeof(kfilter
));
2788 asmlinkage
int sys32_setsockopt(int fd
, int level
, int optname
,
2789 char *optval
, int optlen
)
2791 if (optname
== SO_ATTACH_FILTER
)
2792 return do_set_attach_filter(fd
, level
, optname
,
2794 if (level
== SOL_ICMPV6
&& optname
== ICMPV6_FILTER
)
2795 return do_set_icmpv6_filter(fd
, level
, optname
,
2798 return sys_setsockopt(fd
, level
, optname
, optval
, optlen
);
2801 extern void check_pending(int signum
);
2803 asmlinkage
int sys32_sigaction (int sig
, struct old_sigaction32
*act
, struct old_sigaction32
*oact
)
2805 struct k_sigaction new_ka
, old_ka
;
2809 current
->thread
.flags
|= SPARC_FLAG_NEWSIGNALS
;
2814 old_sigset_t32 mask
;
2816 ret
= get_user((long)new_ka
.sa
.sa_handler
, &act
->sa_handler
);
2817 ret
|= __get_user((long)new_ka
.sa
.sa_restorer
, &act
->sa_restorer
);
2818 ret
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
2819 ret
|= __get_user(mask
, &act
->sa_mask
);
2822 new_ka
.ka_restorer
= NULL
;
2823 siginitset(&new_ka
.sa
.sa_mask
, mask
);
2826 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
2829 ret
= put_user((long)old_ka
.sa
.sa_handler
, &oact
->sa_handler
);
2830 ret
|= __put_user((long)old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
);
2831 ret
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
2832 ret
|= __put_user(old_ka
.sa
.sa_mask
.sig
[0], &oact
->sa_mask
);
2839 sys32_rt_sigaction(int sig
, struct sigaction32
*act
, struct sigaction32
*oact
,
2840 void *restorer
, __kernel_size_t32 sigsetsize
)
2842 struct k_sigaction new_ka
, old_ka
;
2846 /* XXX: Don't preclude handling different sized sigset_t's. */
2847 if (sigsetsize
!= sizeof(sigset_t32
))
2850 /* All tasks which use RT signals (effectively) use
2851 * new style signals.
2853 current
->thread
.flags
|= SPARC_FLAG_NEWSIGNALS
;
2856 new_ka
.ka_restorer
= restorer
;
2857 ret
= get_user((long)new_ka
.sa
.sa_handler
, &act
->sa_handler
);
2858 ret
|= __copy_from_user(&set32
, &act
->sa_mask
, sizeof(sigset_t32
));
2859 switch (_NSIG_WORDS
) {
2860 case 4: new_ka
.sa
.sa_mask
.sig
[3] = set32
.sig
[6] | (((long)set32
.sig
[7]) << 32);
2861 case 3: new_ka
.sa
.sa_mask
.sig
[2] = set32
.sig
[4] | (((long)set32
.sig
[5]) << 32);
2862 case 2: new_ka
.sa
.sa_mask
.sig
[1] = set32
.sig
[2] | (((long)set32
.sig
[3]) << 32);
2863 case 1: new_ka
.sa
.sa_mask
.sig
[0] = set32
.sig
[0] | (((long)set32
.sig
[1]) << 32);
2865 ret
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
2866 ret
|= __get_user((long)new_ka
.sa
.sa_restorer
, &act
->sa_restorer
);
2871 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
2874 switch (_NSIG_WORDS
) {
2875 case 4: set32
.sig
[7] = (old_ka
.sa
.sa_mask
.sig
[3] >> 32); set32
.sig
[6] = old_ka
.sa
.sa_mask
.sig
[3];
2876 case 3: set32
.sig
[5] = (old_ka
.sa
.sa_mask
.sig
[2] >> 32); set32
.sig
[4] = old_ka
.sa
.sa_mask
.sig
[2];
2877 case 2: set32
.sig
[3] = (old_ka
.sa
.sa_mask
.sig
[1] >> 32); set32
.sig
[2] = old_ka
.sa
.sa_mask
.sig
[1];
2878 case 1: set32
.sig
[1] = (old_ka
.sa
.sa_mask
.sig
[0] >> 32); set32
.sig
[0] = old_ka
.sa
.sa_mask
.sig
[0];
2880 ret
= put_user((long)old_ka
.sa
.sa_handler
, &oact
->sa_handler
);
2881 ret
|= __copy_to_user(&oact
->sa_mask
, &set32
, sizeof(sigset_t32
));
2882 ret
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
2883 ret
|= __put_user((long)old_ka
.sa
.sa_restorer
, &oact
->sa_restorer
);
2891 * count32() counts the number of arguments/envelopes
2893 static int count32(u32
* argv
)
2901 error
= get_user(p
,argv
);
2902 if (error
) return error
;
2911 * 'copy_string32()' copies argument/envelope strings from user
2912 * memory to free pages in kernel mem. These are in a format ready
2913 * to be put directly into the top of new user memory.
2915 static int copy_strings32(int argc
, u32
* argv
, struct linux_binprm
*bprm
)
2917 while (argc
-- > 0) {
2922 if (get_user(str
, argv
+ argc
) ||
2924 !(len
= strnlen_user((char *)A(str
), bprm
->p
)))
2936 int offset
, bytes_to_copy
, new, err
;
2938 offset
= pos
% PAGE_SIZE
;
2939 page
= bprm
->page
[pos
/ PAGE_SIZE
];
2942 page
= alloc_page(GFP_USER
);
2943 bprm
->page
[pos
/ PAGE_SIZE
] = page
;
2948 kaddr
= (char *)kmap(page
);
2951 memset(kaddr
, 0, offset
);
2952 bytes_to_copy
= PAGE_SIZE
- offset
;
2953 if (bytes_to_copy
> len
) {
2954 bytes_to_copy
= len
;
2956 memset(kaddr
+offset
+len
, 0,
2957 PAGE_SIZE
-offset
-len
);
2960 err
= copy_from_user(kaddr
+ offset
, (char *)A(str
),
2962 flush_page_to_ram(page
);
2963 kunmap((unsigned long)kaddr
);
2968 pos
+= bytes_to_copy
;
2969 str
+= bytes_to_copy
;
2970 len
-= bytes_to_copy
;
2977 * sys32_execve() executes a new program.
2980 do_execve32(char * filename
, u32
* argv
, u32
* envp
, struct pt_regs
* regs
)
2982 struct linux_binprm bprm
;
2987 bprm
.p
= PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(void *);
2988 memset(bprm
.page
, 0, MAX_ARG_PAGES
* sizeof(bprm
.page
[0]));
2990 file
= open_exec(filename
);
2992 retval
= PTR_ERR(file
);
2997 bprm
.filename
= filename
;
3001 if ((bprm
.argc
= count32(argv
)) < 0) {
3002 allow_write_access(file
);
3006 if ((bprm
.envc
= count32(envp
)) < 0) {
3007 allow_write_access(file
);
3012 retval
= prepare_binprm(&bprm
);
3016 retval
= copy_strings_kernel(1, &bprm
.filename
, &bprm
);
3021 retval
= copy_strings32(bprm
.envc
, envp
, &bprm
);
3025 retval
= copy_strings32(bprm
.argc
, argv
, &bprm
);
3029 retval
= search_binary_handler(&bprm
, regs
);
3031 /* execve success */
3035 /* Something went wrong, return the inode and free the argument pages*/
3036 allow_write_access(bprm
.file
);
3040 for (i
=0 ; i
<MAX_ARG_PAGES
; i
++)
3042 __free_page(bprm
.page
[i
]);
3048 * sparc32_execve() executes a new program after the asm stub has set
3049 * things up for us. This should basically do what I want it to.
3051 asmlinkage
int sparc32_execve(struct pt_regs
*regs
)
3053 int error
, base
= 0;
3056 /* User register window flush is done by entry.S */
3058 /* Check for indirect call. */
3059 if((u32
)regs
->u_regs
[UREG_G1
] == 0)
3062 filename
= getname((char *)AA(regs
->u_regs
[base
+ UREG_I0
]));
3063 error
= PTR_ERR(filename
);
3064 if(IS_ERR(filename
))
3066 error
= do_execve32(filename
,
3067 (u32
*)AA((u32
)regs
->u_regs
[base
+ UREG_I1
]),
3068 (u32
*)AA((u32
)regs
->u_regs
[base
+ UREG_I2
]), regs
);
3073 current
->thread
.xfsr
[0] = 0;
3074 current
->thread
.fpsaved
[0] = 0;
3075 regs
->tstate
&= ~TSTATE_PEF
;
3081 #ifdef CONFIG_MODULES
3083 extern asmlinkage
unsigned long sys_create_module(const char *name_user
, size_t size
);
3085 asmlinkage
unsigned long sys32_create_module(const char *name_user
, __kernel_size_t32 size
)
3087 return sys_create_module(name_user
, (size_t)size
);
3090 extern asmlinkage
int sys_init_module(const char *name_user
, struct module
*mod_user
);
3092 /* Hey, when you're trying to init module, take time and prepare us a nice 64bit
3093 * module structure, even if from 32bit modutils... Why to pollute kernel... :))
3095 asmlinkage
int sys32_init_module(const char *name_user
, struct module
*mod_user
)
3097 return sys_init_module(name_user
, mod_user
);
3100 extern asmlinkage
int sys_delete_module(const char *name_user
);
3102 asmlinkage
int sys32_delete_module(const char *name_user
)
3104 return sys_delete_module(name_user
);
3107 struct module_info32
{
3114 /* Query various bits about modules. */
3117 get_mod_name(const char *user_name
, char **buf
)
3122 if ((unsigned long)user_name
>= TASK_SIZE
3123 && !segment_eq(get_fs (), KERNEL_DS
))
3126 page
= __get_free_page(GFP_KERNEL
);
3130 retval
= strncpy_from_user((char *)page
, user_name
, PAGE_SIZE
);
3132 if (retval
< PAGE_SIZE
) {
3133 *buf
= (char *)page
;
3136 retval
= -ENAMETOOLONG
;
3145 put_mod_name(char *buf
)
3147 free_page((unsigned long)buf
);
3150 static __inline__
struct module
*find_module(const char *name
)
3154 for (mod
= module_list
; mod
; mod
= mod
->next
) {
3155 if (mod
->flags
& MOD_DELETED
)
3157 if (!strcmp(mod
->name
, name
))
3165 qm_modules(char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3168 size_t nmod
, space
, len
;
3172 for (mod
= module_list
; mod
->next
!= NULL
; mod
= mod
->next
, ++nmod
) {
3173 len
= strlen(mod
->name
)+1;
3175 goto calc_space_needed
;
3176 if (copy_to_user(buf
, mod
->name
, len
))
3183 if (put_user(nmod
, ret
))
3190 while ((mod
= mod
->next
)->next
!= NULL
)
3191 space
+= strlen(mod
->name
)+1;
3193 if (put_user(space
, ret
))
3200 qm_deps(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3202 size_t i
, space
, len
;
3204 if (mod
->next
== NULL
)
3206 if (!MOD_CAN_QUERY(mod
))
3207 return put_user(0, ret
);
3210 for (i
= 0; i
< mod
->ndeps
; ++i
) {
3211 const char *dep_name
= mod
->deps
[i
].dep
->name
;
3213 len
= strlen(dep_name
)+1;
3215 goto calc_space_needed
;
3216 if (copy_to_user(buf
, dep_name
, len
))
3223 return put_user(i
, ret
);
3227 while (++i
< mod
->ndeps
)
3228 space
+= strlen(mod
->deps
[i
].dep
->name
)+1;
3230 if (put_user(space
, ret
))
3237 qm_refs(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3239 size_t nrefs
, space
, len
;
3240 struct module_ref
*ref
;
3242 if (mod
->next
== NULL
)
3244 if (!MOD_CAN_QUERY(mod
))
3245 if (put_user(0, ret
))
3251 for (nrefs
= 0, ref
= mod
->refs
; ref
; ++nrefs
, ref
= ref
->next_ref
) {
3252 const char *ref_name
= ref
->ref
->name
;
3254 len
= strlen(ref_name
)+1;
3256 goto calc_space_needed
;
3257 if (copy_to_user(buf
, ref_name
, len
))
3264 if (put_user(nrefs
, ret
))
3271 while ((ref
= ref
->next_ref
) != NULL
)
3272 space
+= strlen(ref
->ref
->name
)+1;
3274 if (put_user(space
, ret
))
3281 qm_symbols(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3283 size_t i
, space
, len
;
3284 struct module_symbol
*s
;
3288 if (!MOD_CAN_QUERY(mod
))
3289 if (put_user(0, ret
))
3294 space
= mod
->nsyms
* 2*sizeof(u32
);
3299 if (space
> bufsize
)
3300 goto calc_space_needed
;
3302 if (!access_ok(VERIFY_WRITE
, buf
, space
))
3306 vals
= (unsigned *)buf
;
3307 strings
= buf
+space
;
3309 for (; i
< mod
->nsyms
; ++i
, ++s
, vals
+= 2) {
3310 len
= strlen(s
->name
)+1;
3312 goto calc_space_needed
;
3314 if (copy_to_user(strings
, s
->name
, len
)
3315 || __put_user(s
->value
, vals
+0)
3316 || __put_user(space
, vals
+1))
3324 if (put_user(i
, ret
))
3330 for (; i
< mod
->nsyms
; ++i
, ++s
)
3331 space
+= strlen(s
->name
)+1;
3333 if (put_user(space
, ret
))
3340 qm_info(struct module
*mod
, char *buf
, size_t bufsize
, __kernel_size_t32
*ret
)
3344 if (mod
->next
== NULL
)
3347 if (sizeof(struct module_info32
) <= bufsize
) {
3348 struct module_info32 info
;
3349 info
.addr
= (unsigned long)mod
;
3350 info
.size
= mod
->size
;
3351 info
.flags
= mod
->flags
;
3353 ((mod_member_present(mod
, can_unload
)
3355 ? -1 : atomic_read(&mod
->uc
.usecount
));
3357 if (copy_to_user(buf
, &info
, sizeof(struct module_info32
)))
3362 if (put_user(sizeof(struct module_info32
), ret
))
3368 asmlinkage
int sys32_query_module(char *name_user
, int which
, char *buf
, __kernel_size_t32 bufsize
, u32 ret
)
3374 if (name_user
== 0) {
3375 /* This finds "kernel_module" which is not exported. */
3376 for(mod
= module_list
; mod
->next
!= NULL
; mod
= mod
->next
)
3382 if ((namelen
= get_mod_name(name_user
, &name
)) < 0) {
3388 /* This finds "kernel_module" which is not exported. */
3389 for(mod
= module_list
; mod
->next
!= NULL
; mod
= mod
->next
)
3391 } else if ((mod
= find_module(name
)) == NULL
) {
3404 err
= qm_modules(buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3407 err
= qm_deps(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3410 err
= qm_refs(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3413 err
= qm_symbols(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3416 err
= qm_info(mod
, buf
, bufsize
, (__kernel_size_t32
*)AA(ret
));
3427 struct kernel_sym32
{
3432 extern asmlinkage
int sys_get_kernel_syms(struct kernel_sym
*table
);
3434 asmlinkage
int sys32_get_kernel_syms(struct kernel_sym32
*table
)
3437 struct kernel_sym
*tbl
;
3438 mm_segment_t old_fs
;
3440 len
= sys_get_kernel_syms(NULL
);
3441 if (!table
) return len
;
3442 tbl
= kmalloc (len
* sizeof (struct kernel_sym
), GFP_KERNEL
);
3443 if (!tbl
) return -ENOMEM
;
3446 sys_get_kernel_syms(tbl
);
3448 for (i
= 0; i
< len
; i
++, table
+= sizeof (struct kernel_sym32
)) {
3449 if (put_user (tbl
[i
].value
, &table
->value
) ||
3450 copy_to_user (table
->name
, tbl
[i
].name
, 60))
3457 #else /* CONFIG_MODULES */
3459 asmlinkage
unsigned long
3460 sys32_create_module(const char *name_user
, size_t size
)
3466 sys32_init_module(const char *name_user
, struct module
*mod_user
)
3472 sys32_delete_module(const char *name_user
)
3478 sys32_query_module(const char *name_user
, int which
, char *buf
, size_t bufsize
,
3481 /* Let the program know about the new interface. Not that
3482 it'll do them much good. */
3490 sys32_get_kernel_syms(struct kernel_sym
*table
)
3495 #endif /* CONFIG_MODULES */
3497 /* Stuff for NFS server syscalls... */
3498 struct nfsctl_svc32
{
3503 struct nfsctl_client32
{
3504 s8 cl32_ident
[NFSCLNT_IDMAX
+1];
3506 struct in_addr cl32_addrlist
[NFSCLNT_ADDRMAX
];
3509 u8 cl32_fhkey
[NFSCLNT_KEYMAX
];
3512 struct nfsctl_export32
{
3513 s8 ex32_client
[NFSCLNT_IDMAX
+1];
3514 s8 ex32_path
[NFS_MAXPATHLEN
+1];
3515 __kernel_dev_t32 ex32_dev
;
3516 __kernel_ino_t32 ex32_ino
;
3518 __kernel_uid_t32 ex32_anon_uid
;
3519 __kernel_gid_t32 ex32_anon_gid
;
3522 struct nfsctl_uidmap32
{
3523 u32 ug32_ident
; /* char * */
3524 __kernel_uid_t32 ug32_uidbase
;
3526 u32 ug32_udimap
; /* uid_t * */
3527 __kernel_uid_t32 ug32_gidbase
;
3529 u32 ug32_gdimap
; /* gid_t * */
3532 struct nfsctl_fhparm32
{
3533 struct sockaddr gf32_addr
;
3534 __kernel_dev_t32 gf32_dev
;
3535 __kernel_ino_t32 gf32_ino
;
3539 struct nfsctl_fdparm32
{
3540 struct sockaddr gd32_addr
;
3541 s8 gd32_path
[NFS_MAXPATHLEN
+1];
3545 struct nfsctl_fsparm32
{
3546 struct sockaddr gd32_addr
;
3547 s8 gd32_path
[NFS_MAXPATHLEN
+1];
3551 struct nfsctl_arg32
{
3552 s32 ca32_version
; /* safeguard */
3554 struct nfsctl_svc32 u32_svc
;
3555 struct nfsctl_client32 u32_client
;
3556 struct nfsctl_export32 u32_export
;
3557 struct nfsctl_uidmap32 u32_umap
;
3558 struct nfsctl_fhparm32 u32_getfh
;
3559 struct nfsctl_fdparm32 u32_getfd
;
3560 struct nfsctl_fsparm32 u32_getfs
;
3562 #define ca32_svc u.u32_svc
3563 #define ca32_client u.u32_client
3564 #define ca32_export u.u32_export
3565 #define ca32_umap u.u32_umap
3566 #define ca32_getfh u.u32_getfh
3567 #define ca32_getfd u.u32_getfd
3568 #define ca32_getfs u.u32_getfs
3569 #define ca32_authd u.u32_authd
3572 union nfsctl_res32
{
3573 __u8 cr32_getfh
[NFS_FHSIZE
];
3574 struct knfsd_fh cr32_getfs
;
3577 static int nfs_svc32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3581 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3582 err
|= __get_user(karg
->ca_svc
.svc_port
, &arg32
->ca32_svc
.svc32_port
);
3583 err
|= __get_user(karg
->ca_svc
.svc_nthreads
, &arg32
->ca32_svc
.svc32_nthreads
);
3587 static int nfs_clnt32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3591 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3592 err
|= copy_from_user(&karg
->ca_client
.cl_ident
[0],
3593 &arg32
->ca32_client
.cl32_ident
[0],
3595 err
|= __get_user(karg
->ca_client
.cl_naddr
, &arg32
->ca32_client
.cl32_naddr
);
3596 err
|= copy_from_user(&karg
->ca_client
.cl_addrlist
[0],
3597 &arg32
->ca32_client
.cl32_addrlist
[0],
3598 (sizeof(struct in_addr
) * NFSCLNT_ADDRMAX
));
3599 err
|= __get_user(karg
->ca_client
.cl_fhkeytype
,
3600 &arg32
->ca32_client
.cl32_fhkeytype
);
3601 err
|= __get_user(karg
->ca_client
.cl_fhkeylen
,
3602 &arg32
->ca32_client
.cl32_fhkeylen
);
3603 err
|= copy_from_user(&karg
->ca_client
.cl_fhkey
[0],
3604 &arg32
->ca32_client
.cl32_fhkey
[0],
3609 static int nfs_exp32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3613 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3614 err
|= copy_from_user(&karg
->ca_export
.ex_client
[0],
3615 &arg32
->ca32_export
.ex32_client
[0],
3617 err
|= copy_from_user(&karg
->ca_export
.ex_path
[0],
3618 &arg32
->ca32_export
.ex32_path
[0],
3620 err
|= __get_user(karg
->ca_export
.ex_dev
,
3621 &arg32
->ca32_export
.ex32_dev
);
3622 err
|= __get_user(karg
->ca_export
.ex_ino
,
3623 &arg32
->ca32_export
.ex32_ino
);
3624 err
|= __get_user(karg
->ca_export
.ex_flags
,
3625 &arg32
->ca32_export
.ex32_flags
);
3626 err
|= __get_user(karg
->ca_export
.ex_anon_uid
,
3627 &arg32
->ca32_export
.ex32_anon_uid
);
3628 err
|= __get_user(karg
->ca_export
.ex_anon_gid
,
3629 &arg32
->ca32_export
.ex32_anon_gid
);
3630 karg
->ca_export
.ex_anon_uid
= high2lowuid(karg
->ca_export
.ex_anon_uid
);
3631 karg
->ca_export
.ex_anon_gid
= high2lowgid(karg
->ca_export
.ex_anon_gid
);
3635 static int nfs_uud32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3641 memset(karg
, 0, sizeof(*karg
));
3642 if(__get_user(karg
->ca_version
, &arg32
->ca32_version
))
3644 karg
->ca_umap
.ug_ident
= (char *)get_free_page(GFP_USER
);
3645 if(!karg
->ca_umap
.ug_ident
)
3647 err
= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_ident
);
3648 if(strncpy_from_user(karg
->ca_umap
.ug_ident
,
3649 (char *)A(uaddr
), PAGE_SIZE
) <= 0)
3651 err
|= __get_user(karg
->ca_umap
.ug_uidbase
,
3652 &arg32
->ca32_umap
.ug32_uidbase
);
3653 err
|= __get_user(karg
->ca_umap
.ug_uidlen
,
3654 &arg32
->ca32_umap
.ug32_uidlen
);
3655 err
|= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_udimap
);
3658 karg
->ca_umap
.ug_udimap
= kmalloc((sizeof(uid_t
) * karg
->ca_umap
.ug_uidlen
),
3660 if(!karg
->ca_umap
.ug_udimap
)
3662 for(i
= 0; i
< karg
->ca_umap
.ug_uidlen
; i
++)
3663 err
|= __get_user(karg
->ca_umap
.ug_udimap
[i
],
3664 &(((__kernel_uid_t32
*)A(uaddr
))[i
]));
3665 err
|= __get_user(karg
->ca_umap
.ug_gidbase
,
3666 &arg32
->ca32_umap
.ug32_gidbase
);
3667 err
|= __get_user(karg
->ca_umap
.ug_uidlen
,
3668 &arg32
->ca32_umap
.ug32_gidlen
);
3669 err
|= __get_user(uaddr
, &arg32
->ca32_umap
.ug32_gdimap
);
3672 karg
->ca_umap
.ug_gdimap
= kmalloc((sizeof(gid_t
) * karg
->ca_umap
.ug_uidlen
),
3674 if(!karg
->ca_umap
.ug_gdimap
)
3676 for(i
= 0; i
< karg
->ca_umap
.ug_gidlen
; i
++)
3677 err
|= __get_user(karg
->ca_umap
.ug_gdimap
[i
],
3678 &(((__kernel_gid_t32
*)A(uaddr
))[i
]));
3683 static int nfs_getfh32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3687 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3688 err
|= copy_from_user(&karg
->ca_getfh
.gf_addr
,
3689 &arg32
->ca32_getfh
.gf32_addr
,
3690 (sizeof(struct sockaddr
)));
3691 err
|= __get_user(karg
->ca_getfh
.gf_dev
,
3692 &arg32
->ca32_getfh
.gf32_dev
);
3693 err
|= __get_user(karg
->ca_getfh
.gf_ino
,
3694 &arg32
->ca32_getfh
.gf32_ino
);
3695 err
|= __get_user(karg
->ca_getfh
.gf_version
,
3696 &arg32
->ca32_getfh
.gf32_version
);
3700 static int nfs_getfd32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3704 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3705 err
|= copy_from_user(&karg
->ca_getfd
.gd_addr
,
3706 &arg32
->ca32_getfd
.gd32_addr
,
3707 (sizeof(struct sockaddr
)));
3708 err
|= copy_from_user(&karg
->ca_getfd
.gd_path
,
3709 &arg32
->ca32_getfd
.gd32_path
,
3710 (NFS_MAXPATHLEN
+1));
3711 err
|= __get_user(karg
->ca_getfd
.gd_version
,
3712 &arg32
->ca32_getfd
.gd32_version
);
3716 static int nfs_getfs32_trans(struct nfsctl_arg
*karg
, struct nfsctl_arg32
*arg32
)
3720 err
= __get_user(karg
->ca_version
, &arg32
->ca32_version
);
3721 err
|= copy_from_user(&karg
->ca_getfs
.gd_addr
,
3722 &arg32
->ca32_getfs
.gd32_addr
,
3723 (sizeof(struct sockaddr
)));
3724 err
|= copy_from_user(&karg
->ca_getfs
.gd_path
,
3725 &arg32
->ca32_getfs
.gd32_path
,
3726 (NFS_MAXPATHLEN
+1));
3727 err
|= __get_user(karg
->ca_getfs
.gd_maxlen
,
3728 &arg32
->ca32_getfs
.gd32_maxlen
);
3732 /* This really doesn't need translations, we are only passing
3733 * back a union which contains opaque nfs file handle data.
3735 static int nfs_getfh32_res_trans(union nfsctl_res
*kres
, union nfsctl_res32
*res32
)
3737 return copy_to_user(res32
, kres
, sizeof(*res32
));
3740 int asmlinkage
sys32_nfsservctl(int cmd
, struct nfsctl_arg32
*arg32
, union nfsctl_res32
*res32
)
3742 struct nfsctl_arg
*karg
= NULL
;
3743 union nfsctl_res
*kres
= NULL
;
3747 karg
= kmalloc(sizeof(*karg
), GFP_USER
);
3751 kres
= kmalloc(sizeof(*kres
), GFP_USER
);
3759 err
= nfs_svc32_trans(karg
, arg32
);
3761 case NFSCTL_ADDCLIENT
:
3762 err
= nfs_clnt32_trans(karg
, arg32
);
3764 case NFSCTL_DELCLIENT
:
3765 err
= nfs_clnt32_trans(karg
, arg32
);
3768 case NFSCTL_UNEXPORT
:
3769 err
= nfs_exp32_trans(karg
, arg32
);
3771 /* This one is unimplemented, be we're ready for it. */
3772 case NFSCTL_UGIDUPDATE
:
3773 err
= nfs_uud32_trans(karg
, arg32
);
3776 err
= nfs_getfh32_trans(karg
, arg32
);
3779 err
= nfs_getfd32_trans(karg
, arg32
);
3782 err
= nfs_getfs32_trans(karg
, arg32
);
3792 err
= sys_nfsservctl(cmd
, karg
, kres
);
3798 if((cmd
== NFSCTL_GETFH
) ||
3799 (cmd
== NFSCTL_GETFD
) ||
3800 (cmd
== NFSCTL_GETFS
))
3801 err
= nfs_getfh32_res_trans(kres
, res32
);
3805 if(cmd
== NFSCTL_UGIDUPDATE
) {
3806 if(karg
->ca_umap
.ug_ident
)
3807 kfree(karg
->ca_umap
.ug_ident
);
3808 if(karg
->ca_umap
.ug_udimap
)
3809 kfree(karg
->ca_umap
.ug_udimap
);
3810 if(karg
->ca_umap
.ug_gdimap
)
3811 kfree(karg
->ca_umap
.ug_gdimap
);
3820 /* Translations due to time_t size differences. Which affects all
3821 sorts of things, like timeval and itimerval. */
3823 extern struct timezone sys_tz
;
3824 extern int do_sys_settimeofday(struct timeval
*tv
, struct timezone
*tz
);
3826 asmlinkage
int sys32_gettimeofday(struct timeval32
*tv
, struct timezone
*tz
)
3830 do_gettimeofday(&ktv
);
3831 if (put_tv32(tv
, &ktv
))
3835 if (copy_to_user(tz
, &sys_tz
, sizeof(sys_tz
)))
3841 asmlinkage
int sys32_settimeofday(struct timeval32
*tv
, struct timezone
*tz
)
3844 struct timezone ktz
;
3847 if (get_tv32(&ktv
, tv
))
3851 if (copy_from_user(&ktz
, tz
, sizeof(ktz
)))
3855 return do_sys_settimeofday(tv
? &ktv
: NULL
, tz
? &ktz
: NULL
);
3858 extern int do_getitimer(int which
, struct itimerval
*value
);
3860 asmlinkage
int sys32_getitimer(int which
, struct itimerval32
*it
)
3862 struct itimerval kit
;
3865 error
= do_getitimer(which
, &kit
);
3866 if (!error
&& put_it32(it
, &kit
))
3872 extern int do_setitimer(int which
, struct itimerval
*, struct itimerval
*);
3874 asmlinkage
int sys32_setitimer(int which
, struct itimerval32
*in
, struct itimerval32
*out
)
3876 struct itimerval kin
, kout
;
3880 if (get_it32(&kin
, in
))
3883 memset(&kin
, 0, sizeof(kin
));
3885 error
= do_setitimer(which
, &kin
, out
? &kout
: NULL
);
3888 if (put_it32(out
, &kout
))
3895 asmlinkage
int sys_utimes(char *, struct timeval
*);
3897 asmlinkage
int sys32_utimes(char *filename
, struct timeval32
*tvs
)
3900 struct timeval ktvs
[2];
3901 mm_segment_t old_fs
;
3904 kfilename
= getname(filename
);
3905 ret
= PTR_ERR(kfilename
);
3906 if (!IS_ERR(kfilename
)) {
3908 if (get_tv32(&ktvs
[0], tvs
) ||
3909 get_tv32(&ktvs
[1], 1+tvs
))
3915 ret
= sys_utimes(kfilename
, &ktvs
[0]);
3923 /* These are here just in case some old sparc32 binary calls it. */
3924 asmlinkage
int sys32_pause(void)
3926 current
->state
= TASK_INTERRUPTIBLE
;
3928 return -ERESTARTNOHAND
;
3931 /* PCI config space poking. */
3932 extern asmlinkage
int sys_pciconfig_read(unsigned long bus
,
3936 unsigned char *buf
);
3938 extern asmlinkage
int sys_pciconfig_write(unsigned long bus
,
3942 unsigned char *buf
);
3944 asmlinkage
int sys32_pciconfig_read(u32 bus
, u32 dfn
, u32 off
, u32 len
, u32 ubuf
)
3946 return sys_pciconfig_read((unsigned long) bus
,
3947 (unsigned long) dfn
,
3948 (unsigned long) off
,
3949 (unsigned long) len
,
3950 (unsigned char *)AA(ubuf
));
3953 asmlinkage
int sys32_pciconfig_write(u32 bus
, u32 dfn
, u32 off
, u32 len
, u32 ubuf
)
3955 return sys_pciconfig_write((unsigned long) bus
,
3956 (unsigned long) dfn
,
3957 (unsigned long) off
,
3958 (unsigned long) len
,
3959 (unsigned char *)AA(ubuf
));
3962 extern asmlinkage
int sys_prctl(int option
, unsigned long arg2
, unsigned long arg3
,
3963 unsigned long arg4
, unsigned long arg5
);
3965 asmlinkage
int sys32_prctl(int option
, u32 arg2
, u32 arg3
, u32 arg4
, u32 arg5
)
3967 return sys_prctl(option
,
3968 (unsigned long) arg2
,
3969 (unsigned long) arg3
,
3970 (unsigned long) arg4
,
3971 (unsigned long) arg5
);
3975 extern asmlinkage ssize_t
sys_pread(unsigned int fd
, char * buf
,
3976 size_t count
, loff_t pos
);
3978 extern asmlinkage ssize_t
sys_pwrite(unsigned int fd
, const char * buf
,
3979 size_t count
, loff_t pos
);
3981 typedef __kernel_ssize_t32 ssize_t32
;
3983 asmlinkage ssize_t32
sys32_pread(unsigned int fd
, char *ubuf
,
3984 __kernel_size_t32 count
, u32 poshi
, u32 poslo
)
3986 return sys_pread(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
3989 asmlinkage ssize_t32
sys32_pwrite(unsigned int fd
, char *ubuf
,
3990 __kernel_size_t32 count
, u32 poshi
, u32 poslo
)
3992 return sys_pwrite(fd
, ubuf
, count
, ((loff_t
)AA(poshi
) << 32) | AA(poslo
));
3996 extern asmlinkage ssize_t
sys_sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
);
3998 asmlinkage
int sys32_sendfile(int out_fd
, int in_fd
, __kernel_off_t32
*offset
, s32 count
)
4000 mm_segment_t old_fs
= get_fs();
4004 if (offset
&& get_user(of
, offset
))
4008 ret
= sys_sendfile(out_fd
, in_fd
, offset
? &of
: NULL
, count
);
4011 if (!ret
&& offset
&& put_user(of
, offset
))
4017 /* Handle adjtimex compatability. */
4021 s32 offset
, freq
, maxerror
, esterror
;
4022 s32 status
, constant
, precision
, tolerance
;
4023 struct timeval32 time
;
4025 s32 ppsfreq
, jitter
, shift
, stabil
;
4026 s32 jitcnt
, calcnt
, errcnt
, stbcnt
;
4027 s32
:32; s32
:32; s32
:32; s32
:32;
4028 s32
:32; s32
:32; s32
:32; s32
:32;
4029 s32
:32; s32
:32; s32
:32; s32
:32;
4032 extern int do_adjtimex(struct timex
*);
4034 asmlinkage
int sys32_adjtimex(struct timex32
*utp
)
4039 memset(&txc
, 0, sizeof(struct timex
));
4041 if(get_user(txc
.modes
, &utp
->modes
) ||
4042 __get_user(txc
.offset
, &utp
->offset
) ||
4043 __get_user(txc
.freq
, &utp
->freq
) ||
4044 __get_user(txc
.maxerror
, &utp
->maxerror
) ||
4045 __get_user(txc
.esterror
, &utp
->esterror
) ||
4046 __get_user(txc
.status
, &utp
->status
) ||
4047 __get_user(txc
.constant
, &utp
->constant
) ||
4048 __get_user(txc
.precision
, &utp
->precision
) ||
4049 __get_user(txc
.tolerance
, &utp
->tolerance
) ||
4050 __get_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
4051 __get_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
4052 __get_user(txc
.tick
, &utp
->tick
) ||
4053 __get_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
4054 __get_user(txc
.jitter
, &utp
->jitter
) ||
4055 __get_user(txc
.shift
, &utp
->shift
) ||
4056 __get_user(txc
.stabil
, &utp
->stabil
) ||
4057 __get_user(txc
.jitcnt
, &utp
->jitcnt
) ||
4058 __get_user(txc
.calcnt
, &utp
->calcnt
) ||
4059 __get_user(txc
.errcnt
, &utp
->errcnt
) ||
4060 __get_user(txc
.stbcnt
, &utp
->stbcnt
))
4063 ret
= do_adjtimex(&txc
);
4065 if(put_user(txc
.modes
, &utp
->modes
) ||
4066 __put_user(txc
.offset
, &utp
->offset
) ||
4067 __put_user(txc
.freq
, &utp
->freq
) ||
4068 __put_user(txc
.maxerror
, &utp
->maxerror
) ||
4069 __put_user(txc
.esterror
, &utp
->esterror
) ||
4070 __put_user(txc
.status
, &utp
->status
) ||
4071 __put_user(txc
.constant
, &utp
->constant
) ||
4072 __put_user(txc
.precision
, &utp
->precision
) ||
4073 __put_user(txc
.tolerance
, &utp
->tolerance
) ||
4074 __put_user(txc
.time
.tv_sec
, &utp
->time
.tv_sec
) ||
4075 __put_user(txc
.time
.tv_usec
, &utp
->time
.tv_usec
) ||
4076 __put_user(txc
.tick
, &utp
->tick
) ||
4077 __put_user(txc
.ppsfreq
, &utp
->ppsfreq
) ||
4078 __put_user(txc
.jitter
, &utp
->jitter
) ||
4079 __put_user(txc
.shift
, &utp
->shift
) ||
4080 __put_user(txc
.stabil
, &utp
->stabil
) ||
4081 __put_user(txc
.jitcnt
, &utp
->jitcnt
) ||
4082 __put_user(txc
.calcnt
, &utp
->calcnt
) ||
4083 __put_user(txc
.errcnt
, &utp
->errcnt
) ||
4084 __put_user(txc
.stbcnt
, &utp
->stbcnt
))
4090 /* This is just a version for 32-bit applications which does
4091 * not force O_LARGEFILE on.
4094 asmlinkage
long sparc32_open(const char * filename
, int flags
, int mode
)
4099 tmp
= getname(filename
);
4102 fd
= get_unused_fd();
4104 struct file
* f
= filp_open(tmp
, flags
, mode
);
4121 extern unsigned long do_mremap(unsigned long addr
,
4122 unsigned long old_len
, unsigned long new_len
,
4123 unsigned long flags
, unsigned long new_addr
);
4125 asmlinkage
unsigned long sys32_mremap(unsigned long addr
,
4126 unsigned long old_len
, unsigned long new_len
,
4127 unsigned long flags
, u32 __new_addr
)
4129 unsigned long ret
= -EINVAL
;
4130 unsigned long new_addr
= AA(__new_addr
);
4132 if (old_len
> 0xf0000000UL
|| new_len
> 0xf0000000UL
)
4134 if (addr
> 0xf0000000UL
- old_len
)
4136 down(¤t
->mm
->mmap_sem
);
4137 if (flags
& MREMAP_FIXED
) {
4138 if (new_addr
> 0xf0000000UL
- new_len
)
4140 } else if (addr
> 0xf0000000UL
- new_len
) {
4142 if (!(flags
& MREMAP_MAYMOVE
))
4144 new_addr
= get_unmapped_area (addr
, new_len
);
4147 flags
|= MREMAP_FIXED
;
4149 ret
= do_mremap(addr
, old_len
, new_len
, flags
, new_addr
);
4151 up(¤t
->mm
->mmap_sem
);
4156 extern asmlinkage
long sys_setpriority(int which
, int who
, int niceval
);
4158 asmlinkage
int sys_setpriority32(u32 which
, u32 who
, u32 niceval
)
4160 return sys_setpriority((int) which
,