2 * Conversion between 32-bit and 64-bit native system calls.
4 * Copyright (C) 2000 Silicon Graphics, Inc.
5 * Written by Ulf Carlsson (ulfc@engr.sgi.com)
6 * sys32_execve from ia64/ia32 code, Feb 2000, Kanoj Sarcar (kanoj@sgi.com)
10 #include <linux/errno.h>
11 #include <linux/file.h>
12 #include <linux/smp_lock.h>
13 #include <linux/highuid.h>
14 #include <linux/dirent.h>
15 #include <linux/resource.h>
16 #include <linux/highmem.h>
17 #include <linux/time.h>
18 #include <linux/poll.h>
19 #include <linux/slab.h>
20 #include <linux/skbuff.h>
21 #include <linux/filter.h>
23 #include <asm/uaccess.h>
27 #define A(__x) ((unsigned long)(__x))
30 * Revalidate the inode. This is required for proper NFS attribute caching.
33 do_revalidate(struct dentry
*dentry
)
35 struct inode
* inode
= dentry
->d_inode
;
37 if (inode
->i_op
&& inode
->i_op
->revalidate
)
38 return inode
->i_op
->revalidate(dentry
);
43 static int cp_new_stat32(struct inode
* inode
, struct stat32
* statbuf
)
46 unsigned int blocks
, indirect
;
48 memset(&tmp
, 0, sizeof(tmp
));
49 tmp
.st_dev
= kdev_t_to_nr(inode
->i_dev
);
50 tmp
.st_ino
= inode
->i_ino
;
51 tmp
.st_mode
= inode
->i_mode
;
52 tmp
.st_nlink
= inode
->i_nlink
;
53 SET_STAT_UID(tmp
, inode
->i_uid
);
54 SET_STAT_GID(tmp
, inode
->i_gid
);
55 tmp
.st_rdev
= kdev_t_to_nr(inode
->i_rdev
);
56 tmp
.st_size
= inode
->i_size
;
57 tmp
.st_atime
= inode
->i_atime
;
58 tmp
.st_mtime
= inode
->i_mtime
;
59 tmp
.st_ctime
= inode
->i_ctime
;
62 * st_blocks and st_blksize are approximated with a simple algorithm if
63 * they aren't supported directly by the filesystem. The minix and msdos
64 * filesystems don't keep track of blocks, so they would either have to
65 * be counted explicitly (by delving into the file itself), or by using
66 * this simple algorithm to get a reasonable (although not 100%
71 * Use minix fs values for the number of direct and indirect blocks.
72 * The count is now exact for the minix fs except that it counts zero
73 * blocks. Everything is in units of BLOCK_SIZE until the assignment
77 #define I_B (BLOCK_SIZE / sizeof(unsigned short))
79 if (!inode
->i_blksize
) {
80 blocks
= (tmp
.st_size
+ BLOCK_SIZE
- 1) / BLOCK_SIZE
;
82 indirect
= (blocks
- D_B
+ I_B
- 1) / I_B
;
85 indirect
= (indirect
- 1 + I_B
- 1) / I_B
;
91 tmp
.st_blocks
= (BLOCK_SIZE
/ 512) * blocks
;
92 tmp
.st_blksize
= BLOCK_SIZE
;
94 tmp
.st_blocks
= inode
->i_blocks
;
95 tmp
.st_blksize
= inode
->i_blksize
;
98 return copy_to_user(statbuf
,&tmp
,sizeof(tmp
)) ? -EFAULT
: 0;
101 asmlinkage
int sys32_newstat(char * filename
, struct stat32
*statbuf
)
106 error
= user_path_walk(filename
, &nd
);
108 error
= do_revalidate(nd
.dentry
);
110 error
= cp_new_stat32(nd
.dentry
->d_inode
, statbuf
);
118 asmlinkage
int sys32_newlstat(char * filename
, struct stat32
*statbuf
)
123 error
= user_path_walk_link(filename
, &nd
);
125 error
= do_revalidate(nd
.dentry
);
127 error
= cp_new_stat32(nd
.dentry
->d_inode
, statbuf
);
135 asmlinkage
long sys32_newfstat(unsigned int fd
, struct stat32
* statbuf
)
142 struct dentry
* dentry
= f
->f_dentry
;
144 err
= do_revalidate(dentry
);
146 err
= cp_new_stat32(dentry
->d_inode
, statbuf
);
153 asmlinkage
int sys_mmap2(void) {return 0;}
155 asmlinkage
long sys_truncate(const char * path
, unsigned long length
);
157 asmlinkage
int sys_truncate64(const char *path
, unsigned int high
,
162 return sys_truncate(path
, ((long) high
<< 32) | low
);
165 asmlinkage
long sys_ftruncate(unsigned int fd
, unsigned long length
);
167 asmlinkage
int sys_ftruncate64(unsigned int fd
, unsigned int high
,
172 return sys_ftruncate(fd
, ((long) high
<< 32) | low
);
177 * count32() counts the number of arguments/envelopes
179 static int count32(u32
* argv
, int max
)
187 if (!access_ok(VERIFY_READ
, argv
, sizeof (u32
)))
202 * 'copy_strings32()' copies argument/envelope strings from user
203 * memory to free pages in kernel mem. These are in a format ready
204 * to be put directly into the top of new user memory.
206 int copy_strings32(int argc
, u32
* argv
, struct linux_binprm
*bprm
)
213 if (get_user(str
, argv
+argc
) || !str
||
214 !(len
= strnlen_user((char *)A(str
), bprm
->p
)))
220 /* XXX: add architecture specific overflow check here. */
227 int offset
, bytes_to_copy
;
229 offset
= pos
% PAGE_SIZE
;
231 page
= bprm
->page
[i
];
234 page
= alloc_page(GFP_HIGHUSER
);
235 bprm
->page
[i
] = page
;
240 kaddr
= (char *)kmap(page
);
243 memset(kaddr
, 0, offset
);
244 bytes_to_copy
= PAGE_SIZE
- offset
;
245 if (bytes_to_copy
> len
) {
248 memset(kaddr
+offset
+len
, 0,
249 PAGE_SIZE
-offset
-len
);
251 err
= copy_from_user(kaddr
+ offset
, (char *)A(str
),
253 flush_page_to_ram(page
);
259 pos
+= bytes_to_copy
;
260 str
+= bytes_to_copy
;
261 len
-= bytes_to_copy
;
269 * sys_execve32() executes a new program.
271 int do_execve32(char * filename
, u32
* argv
, u32
* envp
, struct pt_regs
* regs
)
273 struct linux_binprm bprm
;
274 struct dentry
* dentry
;
278 bprm
.p
= PAGE_SIZE
*MAX_ARG_PAGES
-sizeof(void *);
279 memset(bprm
.page
, 0, MAX_ARG_PAGES
*sizeof(bprm
.page
[0]));
281 dentry
= open_namei(filename
, 0, 0);
282 retval
= PTR_ERR(dentry
);
286 bprm
.dentry
= dentry
;
287 bprm
.filename
= filename
;
291 if ((bprm
.argc
= count32(argv
, bprm
.p
/ sizeof(u32
))) < 0) {
296 if ((bprm
.envc
= count32(envp
, bprm
.p
/ sizeof(u32
))) < 0) {
301 retval
= prepare_binprm(&bprm
);
305 retval
= copy_strings_kernel(1, &bprm
.filename
, &bprm
);
310 retval
= copy_strings32(bprm
.envc
, envp
, &bprm
);
314 retval
= copy_strings32(bprm
.argc
, argv
, &bprm
);
318 retval
= search_binary_handler(&bprm
,regs
);
324 /* Something went wrong, return the inode and free the argument pages*/
328 /* Assumes that free_page() can take a NULL argument. */
329 /* I hope this is ok for all architectures */
330 for (i
= 0 ; i
< MAX_ARG_PAGES
; i
++)
332 __free_page(bprm
.page
[i
]);
338 * sys_execve() executes a new program.
340 asmlinkage
int sys32_execve(abi64_no_regargs
, struct pt_regs regs
)
345 filename
= getname((char *) (long)regs
.regs
[4]);
346 printk("Executing: %s\n", filename
);
347 error
= PTR_ERR(filename
);
348 if (IS_ERR(filename
))
350 error
= do_execve32(filename
, (u32
*) (long)regs
.regs
[5],
351 (u32
*) (long)regs
.regs
[6], ®s
);
359 nargs(unsigned int arg
, char **ap
)
367 if (!access_ok(VERIFY_READ
, arg
, sizeof (unsigned int)))
369 __get_user((long)ptr
,(int *)A(arg
));
372 arg
+= sizeof(unsigned int);
379 sys32_execve(abi64_no_regargs
, struct pt_regs regs
)
381 extern asmlinkage
int sys_execve(abi64_no_regargs
, struct pt_regs regs
);
382 extern asmlinkage
long sys_munmap(unsigned long addr
, size_t len
);
383 unsigned int argv
= (unsigned int)regs
.regs
[5];
384 unsigned int envp
= (unsigned int)regs
.regs
[6];
389 na
= nargs(argv
, NULL
);
390 ne
= nargs(envp
, NULL
);
391 len
= (na
+ ne
+ 2) * sizeof(*av
);
393 * kmalloc won't work because the `sys_exec' code will attempt
394 * to do a `get_user' on the arg list and `get_user' will fail
395 * on a kernel address (simplifies `get_user'). Instead we
396 * do an mmap to get a user address. Note that since a successful
397 * `execve' frees all current memory we only have to do an
398 * `munmap' if the `execve' failes.
400 down(¤t
->mm
->mmap_sem
);
401 av
= (char **) do_mmap_pgoff(0, 0, len
, PROT_READ
| PROT_WRITE
,
402 MAP_PRIVATE
| MAP_ANONYMOUS
, 0);
403 up(¤t
->mm
->mmap_sem
);
410 (void)nargs(argv
, av
);
411 (void)nargs(envp
, ae
);
412 filename
= getname((char *) (long)regs
.regs
[4]);
413 r
= PTR_ERR(filename
);
414 if (IS_ERR(filename
))
417 r
= do_execve(filename
, av
, ae
, ®s
);
420 sys_munmap((unsigned long)av
, len
);
428 unsigned short d_reclen
;
429 char d_name
[NAME_MAX
+ 1];
433 xlate_dirent(void *dirent64
, void *dirent32
, long n
)
437 struct dirent32
*dirp32
;
441 dirp
= (struct dirent
*)(dirent64
+ off
);
442 dirp32
= (struct dirent32
*)(dirent32
+ off
);
443 off
+= dirp
->d_reclen
;
444 dirp32
->d_ino
= dirp
->d_ino
;
445 dirp32
->d_off
= (unsigned int)dirp
->d_off
;
446 dirp32
->d_reclen
= dirp
->d_reclen
;
447 strncpy(dirp32
->d_name
, dirp
->d_name
, dirp
->d_reclen
- ((3 * 4) + 2));
452 asmlinkage
long sys_getdents(unsigned int fd
, void * dirent
, unsigned int count
);
455 sys32_getdents(unsigned int fd
, void * dirent32
, unsigned int count
)
460 dirent64
= (void *)((unsigned long)(dirent32
+ (sizeof(long) - 1)) & ~(sizeof(long) - 1));
461 if ((n
= sys_getdents(fd
, dirent64
, count
- (dirent64
- dirent32
))) < 0)
463 xlate_dirent(dirent64
, dirent32
, n
);
467 asmlinkage
int old_readdir(unsigned int fd
, void * dirent
, unsigned int count
);
470 sys32_readdir(unsigned int fd
, void * dirent32
, unsigned int count
)
473 struct dirent dirent64
;
475 if ((n
= old_readdir(fd
, &dirent64
, count
)) < 0)
477 xlate_dirent(&dirent64
, dirent32
, dirent64
.d_reclen
);
488 struct timeval32 it_interval
;
489 struct timeval32 it_value
;
493 struct timeval32 ru_utime
;
494 struct timeval32 ru_stime
;
512 put_rusage (struct rusage32
*ru
, struct rusage
*r
)
516 err
= put_user (r
->ru_utime
.tv_sec
, &ru
->ru_utime
.tv_sec
);
517 err
|= __put_user (r
->ru_utime
.tv_usec
, &ru
->ru_utime
.tv_usec
);
518 err
|= __put_user (r
->ru_stime
.tv_sec
, &ru
->ru_stime
.tv_sec
);
519 err
|= __put_user (r
->ru_stime
.tv_usec
, &ru
->ru_stime
.tv_usec
);
520 err
|= __put_user (r
->ru_maxrss
, &ru
->ru_maxrss
);
521 err
|= __put_user (r
->ru_ixrss
, &ru
->ru_ixrss
);
522 err
|= __put_user (r
->ru_idrss
, &ru
->ru_idrss
);
523 err
|= __put_user (r
->ru_isrss
, &ru
->ru_isrss
);
524 err
|= __put_user (r
->ru_minflt
, &ru
->ru_minflt
);
525 err
|= __put_user (r
->ru_majflt
, &ru
->ru_majflt
);
526 err
|= __put_user (r
->ru_nswap
, &ru
->ru_nswap
);
527 err
|= __put_user (r
->ru_inblock
, &ru
->ru_inblock
);
528 err
|= __put_user (r
->ru_oublock
, &ru
->ru_oublock
);
529 err
|= __put_user (r
->ru_msgsnd
, &ru
->ru_msgsnd
);
530 err
|= __put_user (r
->ru_msgrcv
, &ru
->ru_msgrcv
);
531 err
|= __put_user (r
->ru_nsignals
, &ru
->ru_nsignals
);
532 err
|= __put_user (r
->ru_nvcsw
, &ru
->ru_nvcsw
);
533 err
|= __put_user (r
->ru_nivcsw
, &ru
->ru_nivcsw
);
537 extern asmlinkage
int sys_wait4(pid_t pid
, unsigned int * stat_addr
,
538 int options
, struct rusage
* ru
);
541 sys32_wait4(__kernel_pid_t32 pid
, unsigned int * stat_addr
, int options
,
542 struct rusage32
* ru
)
545 return sys_wait4(pid
, stat_addr
, options
, NULL
);
550 mm_segment_t old_fs
= get_fs();
553 ret
= sys_wait4(pid
, stat_addr
? &status
: NULL
, options
, &r
);
555 if (put_rusage (ru
, &r
)) return -EFAULT
;
556 if (stat_addr
&& put_user (status
, stat_addr
))
563 sys32_waitpid(__kernel_pid_t32 pid
, unsigned int *stat_addr
, int options
)
565 return sys32_wait4(pid
, stat_addr
, options
, NULL
);
568 #define RLIM_INFINITY32 0x7fffffff
569 #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
576 extern asmlinkage
int sys_old_getrlimit(unsigned int resource
, struct rlimit
*rlim
);
579 sys32_getrlimit(unsigned int resource
, struct rlimit32
*rlim
)
583 mm_segment_t old_fs
= get_fs ();
586 ret
= sys_old_getrlimit(resource
, &r
);
589 ret
= put_user (RESOURCE32(r
.rlim_cur
), &rlim
->rlim_cur
);
590 ret
|= __put_user (RESOURCE32(r
.rlim_max
), &rlim
->rlim_max
);
595 extern asmlinkage
int sys_setrlimit(unsigned int resource
, struct rlimit
*rlim
);
598 sys32_setrlimit(unsigned int resource
, struct rlimit32
*rlim
)
602 mm_segment_t old_fs
= get_fs ();
604 if (resource
>= RLIM_NLIMITS
) return -EINVAL
;
605 if (get_user (r
.rlim_cur
, &rlim
->rlim_cur
) ||
606 __get_user (r
.rlim_max
, &rlim
->rlim_max
))
608 if (r
.rlim_cur
== RLIM_INFINITY32
)
609 r
.rlim_cur
= RLIM_INFINITY
;
610 if (r
.rlim_max
== RLIM_INFINITY32
)
611 r
.rlim_max
= RLIM_INFINITY
;
613 ret
= sys_setrlimit(resource
, &r
);
627 __kernel_fsid_t32 f_fsid
;
633 put_statfs (struct statfs32
*ubuf
, struct statfs
*kbuf
)
637 err
= put_user (kbuf
->f_type
, &ubuf
->f_type
);
638 err
|= __put_user (kbuf
->f_bsize
, &ubuf
->f_bsize
);
639 err
|= __put_user (kbuf
->f_blocks
, &ubuf
->f_blocks
);
640 err
|= __put_user (kbuf
->f_bfree
, &ubuf
->f_bfree
);
641 err
|= __put_user (kbuf
->f_bavail
, &ubuf
->f_bavail
);
642 err
|= __put_user (kbuf
->f_files
, &ubuf
->f_files
);
643 err
|= __put_user (kbuf
->f_ffree
, &ubuf
->f_ffree
);
644 err
|= __put_user (kbuf
->f_namelen
, &ubuf
->f_namelen
);
645 err
|= __put_user (kbuf
->f_fsid
.val
[0], &ubuf
->f_fsid
.val
[0]);
646 err
|= __put_user (kbuf
->f_fsid
.val
[1], &ubuf
->f_fsid
.val
[1]);
650 extern asmlinkage
int sys_statfs(const char * path
, struct statfs
* buf
);
653 sys32_statfs(const char * path
, struct statfs32
*buf
)
657 mm_segment_t old_fs
= get_fs();
660 ret
= sys_statfs((const char *)path
, &s
);
662 if (put_statfs(buf
, &s
))
667 extern asmlinkage
int sys_fstatfs(unsigned int fd
, struct statfs
* buf
);
670 sys32_fstatfs(unsigned int fd
, struct statfs32
*buf
)
674 mm_segment_t old_fs
= get_fs();
677 ret
= sys_fstatfs(fd
, &s
);
679 if (put_statfs(buf
, &s
))
684 extern asmlinkage
int
685 sys_getrusage(int who
, struct rusage
*ru
);
688 sys32_getrusage(int who
, struct rusage32
*ru
)
692 mm_segment_t old_fs
= get_fs();
695 ret
= sys_getrusage(who
, &r
);
697 if (put_rusage (ru
, &r
)) return -EFAULT
;
702 get_tv32(struct timeval
*o
, struct timeval32
*i
)
704 return (!access_ok(VERIFY_READ
, i
, sizeof(*i
)) ||
705 (__get_user(o
->tv_sec
, &i
->tv_sec
) |
706 __get_user(o
->tv_usec
, &i
->tv_usec
)));
711 get_it32(struct itimerval
*o
, struct itimerval32
*i
)
713 return (!access_ok(VERIFY_READ
, i
, sizeof(*i
)) ||
714 (__get_user(o
->it_interval
.tv_sec
, &i
->it_interval
.tv_sec
) |
715 __get_user(o
->it_interval
.tv_usec
, &i
->it_interval
.tv_usec
) |
716 __get_user(o
->it_value
.tv_sec
, &i
->it_value
.tv_sec
) |
717 __get_user(o
->it_value
.tv_usec
, &i
->it_value
.tv_usec
)));
722 put_tv32(struct timeval32
*o
, struct timeval
*i
)
724 return (!access_ok(VERIFY_WRITE
, o
, sizeof(*o
)) ||
725 (__put_user(i
->tv_sec
, &o
->tv_sec
) |
726 __put_user(i
->tv_usec
, &o
->tv_usec
)));
730 put_it32(struct itimerval32
*o
, struct itimerval
*i
)
732 return (!access_ok(VERIFY_WRITE
, i
, sizeof(*i
)) ||
733 (__put_user(i
->it_interval
.tv_sec
, &o
->it_interval
.tv_sec
) |
734 __put_user(i
->it_interval
.tv_usec
, &o
->it_interval
.tv_usec
) |
735 __put_user(i
->it_value
.tv_sec
, &o
->it_value
.tv_sec
) |
736 __put_user(i
->it_value
.tv_usec
, &o
->it_value
.tv_usec
)));
740 extern int do_getitimer(int which
, struct itimerval
*value
);
743 sys32_getitimer(int which
, struct itimerval32
*it
)
745 struct itimerval kit
;
748 error
= do_getitimer(which
, &kit
);
749 if (!error
&& put_it32(it
, &kit
))
755 extern int do_setitimer(int which
, struct itimerval
*, struct itimerval
*);
759 sys32_setitimer(int which
, struct itimerval32
*in
, struct itimerval32
*out
)
761 struct itimerval kin
, kout
;
765 if (get_it32(&kin
, in
))
768 memset(&kin
, 0, sizeof(kin
));
770 error
= do_setitimer(which
, &kin
, out
? &kout
: NULL
);
773 if (put_it32(out
, &kout
))
779 asmlinkage
unsigned long
780 sys32_alarm(unsigned int seconds
)
782 struct itimerval it_new
, it_old
;
783 unsigned int oldalarm
;
785 it_new
.it_interval
.tv_sec
= it_new
.it_interval
.tv_usec
= 0;
786 it_new
.it_value
.tv_sec
= seconds
;
787 it_new
.it_value
.tv_usec
= 0;
788 do_setitimer(ITIMER_REAL
, &it_new
, &it_old
);
789 oldalarm
= it_old
.it_value
.tv_sec
;
790 /* ehhh.. We can't return 0 if we have an alarm pending.. */
791 /* And we'd better return too much than too little anyway */
792 if (it_old
.it_value
.tv_usec
)
797 /* Translations due to time_t size differences. Which affects all
798 sorts of things, like timeval and itimerval. */
801 extern struct timezone sys_tz
;
802 extern int do_sys_settimeofday(struct timeval
*tv
, struct timezone
*tz
);
805 sys32_gettimeofday(struct timeval32
*tv
, struct timezone
*tz
)
809 do_gettimeofday(&ktv
);
810 if (put_tv32(tv
, &ktv
))
814 if (copy_to_user(tz
, &sys_tz
, sizeof(sys_tz
)))
821 sys32_settimeofday(struct timeval32
*tv
, struct timezone
*tz
)
827 if (get_tv32(&ktv
, tv
))
831 if (copy_from_user(&ktz
, tz
, sizeof(ktz
)))
835 return do_sys_settimeofday(tv
? &ktv
: NULL
, tz
? &ktz
: NULL
);
838 extern asmlinkage
long sys_llseek(unsigned int fd
, unsigned long offset_high
,
839 unsigned long offset_low
, loff_t
* result
,
840 unsigned int origin
);
842 extern asmlinkage
int sys32_llseek(unsigned int fd
, unsigned int offset_high
,
843 unsigned int offset_low
, loff_t
* result
,
846 return sys_llseek(fd
, offset_high
, offset_low
, result
, origin
);
849 struct iovec32
{ unsigned int iov_base
; int iov_len
; };
851 typedef ssize_t (*IO_fn_t
)(struct file
*, char *, size_t, loff_t
*);
854 do_readv_writev32(int type
, struct file
*file
, const struct iovec32
*vector
,
857 unsigned long tot_len
;
858 struct iovec iovstack
[UIO_FASTIOV
];
859 struct iovec
*iov
=iovstack
, *ivp
;
864 /* First get the "struct iovec" from user memory and
865 * verify all the pointers
869 if(verify_area(VERIFY_READ
, vector
, sizeof(struct iovec32
)*count
))
871 if (count
> UIO_MAXIOV
)
873 if (count
> UIO_FASTIOV
) {
874 iov
= kmalloc(count
*sizeof(struct iovec
), GFP_KERNEL
);
886 __get_user(len
, &vector
->iov_len
);
887 __get_user(buf
, &vector
->iov_base
);
889 ivp
->iov_base
= (void *)A(buf
);
890 ivp
->iov_len
= (__kernel_size_t
) len
;
896 inode
= file
->f_dentry
->d_inode
;
897 /* VERIFY_WRITE actually means a read, as we write to user space */
898 retval
= locks_verify_area((type
== VERIFY_WRITE
899 ? FLOCK_VERIFY_READ
: FLOCK_VERIFY_WRITE
),
900 inode
, file
, file
->f_pos
, tot_len
);
907 /* Then do the actual IO. Note that sockets need to be handled
908 * specially as they have atomicity guarantees and can handle
913 err
= sock_readv_writev(type
, inode
, file
, iov
, count
, tot_len
);
924 /* VERIFY_WRITE actually means a read, as we write to user space */
925 fn
= file
->f_op
->read
;
926 if (type
== VERIFY_READ
)
927 fn
= (IO_fn_t
) file
->f_op
->write
;
933 base
= ivp
->iov_base
;
937 nr
= fn(file
, base
, len
, &file
->f_pos
);
955 sys32_readv(int fd
, struct iovec32
*vector
, u32 count
)
964 if (file
->f_op
&& (file
->f_mode
& FMODE_READ
) &&
965 (file
->f_op
->readv
|| file
->f_op
->read
))
966 ret
= do_readv_writev32(VERIFY_WRITE
, file
, vector
, count
);
975 sys32_writev(int fd
, struct iovec32
*vector
, u32 count
)
984 if (file
->f_op
&& (file
->f_mode
& FMODE_WRITE
) &&
985 (file
->f_op
->writev
|| file
->f_op
->write
))
986 ret
= do_readv_writev32(VERIFY_READ
, file
, vector
, count
);
994 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
995 * 64-bit unsigned longs.
999 get_fd_set32(unsigned long n
, unsigned long *fdset
, u32
*ufdset
)
1005 if (verify_area(VERIFY_WRITE
, ufdset
, n
*sizeof(u32
)))
1012 __get_user(l
, ufdset
);
1013 __get_user(h
, ufdset
+1);
1015 *fdset
++ = h
<< 32 | l
;
1019 __get_user(*fdset
, ufdset
);
1021 /* Tricky, must clear full unsigned long in the
1022 * kernel fdset at the end, this makes sure that
1025 memset(fdset
, 0, ((n
+ 1) & ~1)*sizeof(u32
));
1029 <<Bomb
- little endian support must define
this>>
1034 set_fd_set32(unsigned long n
, u32
*ufdset
, unsigned long *fdset
)
1047 __put_user(l
, ufdset
);
1048 __put_user(h
, ufdset
+1);
1053 __put_user(*fdset
, ufdset
);
1057 * We can actually return ERESTARTSYS instead of EINTR, but I'd
1058 * like to be certain this leads to no problems. So I return
1059 * EINTR just for safety.
1061 * Update: ERESTARTSYS breaks at least the xview clock binary, so
1062 * I'm trying ERESTARTNOHAND which restart only when you want to.
1064 #define MAX_SELECT_SECONDS \
1065 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1067 asmlinkage
int sys32_select(int n
, u32
*inp
, u32
*outp
, u32
*exp
, struct timeval32
*tvp
)
1075 timeout
= MAX_SCHEDULE_TIMEOUT
;
1079 if ((ret
= verify_area(VERIFY_READ
, tvp
, sizeof(*tvp
)))
1080 || (ret
= __get_user(sec
, &tvp
->tv_sec
))
1081 || (ret
= __get_user(usec
, &tvp
->tv_usec
)))
1085 if(sec
< 0 || usec
< 0)
1088 if ((unsigned long) sec
< MAX_SELECT_SECONDS
) {
1089 timeout
= (usec
+ 1000000/HZ
- 1) / (1000000/HZ
);
1090 timeout
+= sec
* (unsigned long) HZ
;
1097 if (n
> current
->files
->max_fdset
)
1098 n
= current
->files
->max_fdset
;
1101 * We need 6 bitmaps (in/out/ex for both incoming and outgoing),
1102 * since we used fdset we need to allocate memory in units of
1106 size
= FDS_BYTES(n
);
1107 bits
= kmalloc(6 * size
, GFP_KERNEL
);
1110 fds
.in
= (unsigned long *) bits
;
1111 fds
.out
= (unsigned long *) (bits
+ size
);
1112 fds
.ex
= (unsigned long *) (bits
+ 2*size
);
1113 fds
.res_in
= (unsigned long *) (bits
+ 3*size
);
1114 fds
.res_out
= (unsigned long *) (bits
+ 4*size
);
1115 fds
.res_ex
= (unsigned long *) (bits
+ 5*size
);
1117 nn
= (n
+ 8*sizeof(u32
) - 1) / (8*sizeof(u32
));
1118 if ((ret
= get_fd_set32(nn
, fds
.in
, inp
)) ||
1119 (ret
= get_fd_set32(nn
, fds
.out
, outp
)) ||
1120 (ret
= get_fd_set32(nn
, fds
.ex
, exp
)))
1122 zero_fd_set(n
, fds
.res_in
);
1123 zero_fd_set(n
, fds
.res_out
);
1124 zero_fd_set(n
, fds
.res_ex
);
1126 ret
= do_select(n
, &fds
, &timeout
);
1128 if (tvp
&& !(current
->personality
& STICKY_TIMEOUTS
)) {
1129 time_t sec
= 0, usec
= 0;
1132 usec
= timeout
% HZ
;
1133 usec
*= (1000000/HZ
);
1135 put_user(sec
, &tvp
->tv_sec
);
1136 put_user(usec
, &tvp
->tv_usec
);
1142 ret
= -ERESTARTNOHAND
;
1143 if (signal_pending(current
))
1148 set_fd_set32(nn
, inp
, fds
.res_in
);
1149 set_fd_set32(nn
, outp
, fds
.res_out
);
1150 set_fd_set32(nn
, exp
, fds
.res_ex
);
1165 extern asmlinkage
int sys_sched_rr_get_interval(pid_t pid
,
1166 struct timespec
*interval
);
1169 sys32_sched_rr_get_interval(__kernel_pid_t32 pid
, struct timespec32
*interval
)
1173 mm_segment_t old_fs
= get_fs ();
1176 ret
= sys_sched_rr_get_interval(pid
, &t
);
1178 if (put_user (t
.tv_sec
, &interval
->tv_sec
) ||
1179 __put_user (t
.tv_nsec
, &interval
->tv_nsec
))
1185 extern asmlinkage
int sys_nanosleep(struct timespec
*rqtp
,
1186 struct timespec
*rmtp
);
1189 sys32_nanosleep(struct timespec32
*rqtp
, struct timespec32
*rmtp
)
1193 mm_segment_t old_fs
= get_fs ();
1195 if (get_user (t
.tv_sec
, &rqtp
->tv_sec
) ||
1196 __get_user (t
.tv_nsec
, &rqtp
->tv_nsec
))
1200 ret
= sys_nanosleep(&t
, rmtp
? &t
: NULL
);
1202 if (rmtp
&& ret
== -EINTR
) {
1203 if (__put_user (t
.tv_sec
, &rmtp
->tv_sec
) ||
1204 __put_user (t
.tv_nsec
, &rmtp
->tv_nsec
))
1217 extern asmlinkage
long sys_times(struct tms
* tbuf
);
1218 asmlinkage
long sys32_times(struct tms32
*tbuf
)
1222 mm_segment_t old_fs
= get_fs();
1226 ret
= sys_times(tbuf
? &t
: NULL
);
1229 err
= put_user (t
.tms_utime
, &tbuf
->tms_utime
);
1230 err
|= __put_user (t
.tms_stime
, &tbuf
->tms_stime
);
1231 err
|= __put_user (t
.tms_cutime
, &tbuf
->tms_cutime
);
1232 err
|= __put_user (t
.tms_cstime
, &tbuf
->tms_cstime
);
1239 extern asmlinkage
int sys_setsockopt(int fd
, int level
, int optname
,
1240 char *optval
, int optlen
);
1242 asmlinkage
int sys32_setsockopt(int fd
, int level
, int optname
,
1243 char *optval
, int optlen
)
1245 if (optname
== SO_ATTACH_FILTER
) {
1246 struct sock_fprog32
{
1249 } *fprog32
= (struct sock_fprog32
*)optval
;
1250 struct sock_fprog kfprog
;
1251 struct sock_filter
*kfilter
;
1253 mm_segment_t old_fs
;
1257 if (get_user(kfprog
.len
, &fprog32
->len
) ||
1258 __get_user(uptr
, &fprog32
->filter
))
1260 kfprog
.filter
= (struct sock_filter
*)A(uptr
);
1261 fsize
= kfprog
.len
* sizeof(struct sock_filter
);
1262 kfilter
= (struct sock_filter
*)kmalloc(fsize
, GFP_KERNEL
);
1263 if (kfilter
== NULL
)
1265 if (copy_from_user(kfilter
, kfprog
.filter
, fsize
)) {
1269 kfprog
.filter
= kfilter
;
1272 ret
= sys_setsockopt(fd
, level
, optname
,
1273 (char *)&kfprog
, sizeof(kfprog
));
1278 return sys_setsockopt(fd
, level
, optname
, optval
, optlen
);
1284 __kernel_off_t32 l_start
;
1285 __kernel_off_t32 l_len
;
1286 __kernel_pid_t32 l_pid
;
1290 static inline int get_flock(struct flock
*kfl
, struct flock32
*ufl
)
1294 err
= get_user(kfl
->l_type
, &ufl
->l_type
);
1295 err
|= __get_user(kfl
->l_whence
, &ufl
->l_whence
);
1296 err
|= __get_user(kfl
->l_start
, &ufl
->l_start
);
1297 err
|= __get_user(kfl
->l_len
, &ufl
->l_len
);
1298 err
|= __get_user(kfl
->l_pid
, &ufl
->l_pid
);
1302 static inline int put_flock(struct flock
*kfl
, struct flock32
*ufl
)
1306 err
= __put_user(kfl
->l_type
, &ufl
->l_type
);
1307 err
|= __put_user(kfl
->l_whence
, &ufl
->l_whence
);
1308 err
|= __put_user(kfl
->l_start
, &ufl
->l_start
);
1309 err
|= __put_user(kfl
->l_len
, &ufl
->l_len
);
1310 err
|= __put_user(kfl
->l_pid
, &ufl
->l_pid
);
1314 extern asmlinkage
long sys_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
);
1316 asmlinkage
long sys32_fcntl(unsigned int fd
, unsigned int cmd
, unsigned long arg
)
1324 mm_segment_t old_fs
;
1327 if(get_flock(&f
, (struct flock32
*)arg
))
1329 old_fs
= get_fs(); set_fs (KERNEL_DS
);
1330 ret
= sys_fcntl(fd
, cmd
, (unsigned long)&f
);
1332 if(put_flock(&f
, (struct flock32
*)arg
))
1337 return sys_fcntl(fd
, cmd
, (unsigned long)arg
);