@@ -48,6 +48,7 @@
# define __ARCH_WANT_COMPAT_SYS_TIME
# define __ARCH_WANT_COMPAT_SYS_FALLOCATE
# define __ARCH_WANT_COMPAT_SYS_TRUNCATE64
+# define __ARCH_WANT_COMPAT_SYS_PREADWRITE64
# ifdef __MIPSEL__
# define __ARCH_WANT_LE_COMPAT_SYS
# endif
@@ -92,22 +92,6 @@ SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
return sys_llseek(fd, offset_high, offset_low, result, origin);
}
-/* From the Single Unix Spec: pread & pwrite act like lseek to pos + op +
- lseek back to original location. They fail just like lseek does on
- non-seekable files. */
-
-SYSCALL_DEFINE6(32_pread, unsigned long, fd, char __user *, buf, size_t, count,
- unsigned long, unused, unsigned long, a4, unsigned long, a5)
-{
- return sys_pread64(fd, buf, count, merge_64(a4, a5));
-}
-
-SYSCALL_DEFINE6(32_pwrite, unsigned int, fd, const char __user *, buf,
- size_t, count, u32, unused, u64, a4, u64, a5)
-{
- return sys_pwrite64(fd, buf, count, merge_64(a4, a5));
-}
-
SYSCALL_DEFINE1(32_personality, unsigned long, personality)
{
unsigned int p = personality & 0xffffffff;
@@ -416,8 +416,8 @@ EXPORT(sys32_call_table)
PTR compat_sys_rt_sigtimedwait
PTR compat_sys_rt_sigqueueinfo
PTR compat_sys_rt_sigsuspend
- PTR sys_32_pread /* 4200 */
- PTR sys_32_pwrite
+ PTR compat_sys_pread64 /* 4200 */
+ PTR compat_sys_pwrite64
PTR sys_chown
PTR sys_getcwd
PTR sys_capget
@@ -52,6 +52,7 @@
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#define __ARCH_WANT_COMPAT_SYS_FALLOCATE
#define __ARCH_WANT_COMPAT_SYS_TRUNCATE64
+#define __ARCH_WANT_COMPAT_SYS_PREADWRITE64
#endif
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
@@ -74,18 +74,6 @@ unsigned long compat_sys_mmap2(unsigned long addr, size_t len,
* The 32 bit ABI passes long longs in an odd even register pair.
*/
-compat_ssize_t compat_sys_pread64(unsigned int fd, char __user *ubuf, compat_size_t count,
- u32 reg6, u32 poshi, u32 poslo)
-{
- return sys_pread64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
-}
-
-compat_ssize_t compat_sys_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count,
- u32 reg6, u32 poshi, u32 poslo)
-{
- return sys_pwrite64(fd, ubuf, count, ((loff_t)poshi << 32) | poslo);
-}
-
compat_ssize_t compat_sys_readahead(int fd, u32 r4, u32 offhi, u32 offlo, u32 count)
{
return sys_readahead(fd, ((loff_t)offhi << 32) | offlo, count);
@@ -36,6 +36,7 @@
# define __ARCH_WANT_COMPAT_SYS_TIME
# define __ARCH_WANT_COMPAT_SYS_FALLOCATE
# define __ARCH_WANT_COMPAT_SYS_TRUNCATE64
+# define __ARCH_WANT_COMPAT_SYS_PREADWRITE64
# endif
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
@@ -305,22 +305,6 @@ COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low)
return sys_ftruncate(fd, (unsigned long)high << 32 | low);
}
-COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf,
- compat_size_t, count, u32, high, u32, low)
-{
- if ((compat_ssize_t) count < 0)
- return -EINVAL;
- return sys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low);
-}
-
-COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubuf,
- compat_size_t, count, u32, high, u32, low)
-{
- if ((compat_ssize_t) count < 0)
- return -EINVAL;
- return sys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low);
-}
-
COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count)
{
return sys_readahead(fd, (unsigned long)high << 32 | low, count);
@@ -108,8 +108,6 @@ long compat_sys_s390_geteuid16(void);
long compat_sys_s390_getgid16(void);
long compat_sys_s390_getegid16(void);
long compat_sys_s390_ftruncate64(unsigned int fd, u32 high, u32 low);
-long compat_sys_s390_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 high, u32 low);
-long compat_sys_s390_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 high, u32 low);
long compat_sys_s390_readahead(int fd, u32 high, u32 low, s32 count);
long compat_sys_s390_stat64(const char __user *filename, struct stat64_emu31 __user *statbuf);
long compat_sys_s390_lstat64(const char __user *filename, struct stat64_emu31 __user *statbuf);
@@ -168,8 +168,8 @@
177 common rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait
178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
-180 common pread64 sys_pread64 compat_sys_s390_pread64
-181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64
+180 common pread64 sys_pread64 compat_sys_pread64
+181 common pwrite64 sys_pwrite64 compat_sys_pwrite64
182 32 chown - compat_sys_s390_chown16
183 common getcwd sys_getcwd compat_sys_getcwd
184 common capget sys_capget compat_sys_capget
@@ -45,6 +45,7 @@
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#define __ARCH_WANT_COMPAT_SYS_FALLOCATE
#define __ARCH_WANT_COMPAT_SYS_TRUNCATE64
+#define __ARCH_WANT_COMPAT_SYS_PREADWRITE64
#endif
#endif /* _SPARC_UNISTD_H */
@@ -186,24 +186,6 @@ COMPAT_SYSCALL_DEFINE5(rt_sigaction, int, sig,
return ret;
}
-asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
- char __user *ubuf,
- compat_size_t count,
- unsigned long poshi,
- unsigned long poslo)
-{
- return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo);
-}
-
-asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd,
- char __user *ubuf,
- compat_size_t count,
- unsigned long poshi,
- unsigned long poslo)
-{
- return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo);
-}
-
asmlinkage long compat_sys_readahead(int fd,
unsigned long offhi,
unsigned long offlo,
@@ -63,16 +63,6 @@ asmlinkage long compat_sys_fstat64(unsigned int fd,
asmlinkage long compat_sys_fstatat64(unsigned int dfd,
const char __user *filename,
struct compat_stat64 __user * statbuf, int flag);
-asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
- char __user *ubuf,
- compat_size_t count,
- unsigned long poshi,
- unsigned long poslo);
-asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd,
- char __user *ubuf,
- compat_size_t count,
- unsigned long poshi,
- unsigned long poslo);
asmlinkage long compat_sys_readahead(int fd,
unsigned long offhi,
unsigned long offlo,
@@ -32,7 +32,7 @@ sys_call_table32:
/*50*/ .word sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, compat_sys_ioctl
.word sys_reboot, sys32_mmap2, sys_symlink, sys_readlink, sys32_execve
/*60*/ .word sys_umask, sys_chroot, compat_sys_newfstat, compat_sys_fstat64, sys_getpagesize
- .word sys_msync, sys_vfork, sys32_pread64, sys32_pwrite64, sys_geteuid
+ .word sys_msync, sys_vfork, compat_sys_pread64, compat_sys_pwrite64, sys_geteuid
/*70*/ .word sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect
.word sys_madvise, sys_vhangup, compat_sys_truncate64, sys_mincore, sys_getgroups16
/*80*/ .word sys_setgroups16, sys_getpgrp, sys_setgroups, compat_sys_setitimer, sys32_ftruncate64
@@ -186,8 +186,8 @@
177 i386 rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait
178 i386 rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
179 i386 rt_sigsuspend sys_rt_sigsuspend
-180 i386 pread64 sys_pread64 compat_sys_x86_pread
-181 i386 pwrite64 sys_pwrite64 compat_sys_x86_pwrite
+180 i386 pread64 sys_pread64 compat_sys_pread64
+181 i386 pwrite64 sys_pwrite64 compat_sys_pwrite64
182 i386 chown sys_chown16
183 i386 getcwd sys_getcwd
184 i386 capget sys_capget
@@ -167,22 +167,6 @@ COMPAT_SYSCALL_DEFINE3(x86_waitpid, compat_pid_t, pid, unsigned int __user *,
return compat_sys_wait4(pid, stat_addr, options, NULL);
}
-/* warning: next two assume little endian */
-COMPAT_SYSCALL_DEFINE5(x86_pread, unsigned int, fd, char __user *, ubuf,
- u32, count, u32, poslo, u32, poshi)
-{
- return sys_pread64(fd, ubuf, count,
- ((loff_t)AA(poshi) << 32) | AA(poslo));
-}
-
-COMPAT_SYSCALL_DEFINE5(x86_pwrite, unsigned int, fd, const char __user *, ubuf,
- u32, count, u32, poslo, u32, poshi)
-{
- return sys_pwrite64(fd, ubuf, count,
- ((loff_t)AA(poshi) << 32) | AA(poslo));
-}
-
-
/*
* Some system calls that need sign extended arguments. This could be
* done by a generic wrapper.
@@ -36,11 +36,6 @@ asmlinkage long compat_sys_x86_mmap(struct mmap_arg_struct32 __user *);
asmlinkage long compat_sys_x86_waitpid(compat_pid_t, unsigned int __user *,
int);
-asmlinkage long compat_sys_x86_pread(unsigned int, char __user *, u32, u32,
- u32);
-asmlinkage long compat_sys_x86_pwrite(unsigned int, const char __user *, u32,
- u32, u32);
-
asmlinkage long compat_sys_x86_fadvise64_64(int, __u32, __u32, __u32, __u32,
int);
@@ -31,6 +31,7 @@
# define __ARCH_WANT_LE_COMPAT_SYS
# define __ARCH_WANT_COMPAT_SYS_FALLOCATE
# define __ARCH_WANT_COMPAT_SYS_TRUNCATE64
+# define __ARCH_WANT_COMPAT_SYS_PREADWRITE64
# endif
@@ -595,8 +595,8 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
return ret;
}
-SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
- size_t, count, loff_t, pos)
+static ssize_t do_pread64(unsigned int fd, char __user *buf,
+ size_t count, loff_t pos)
{
struct fd f;
ssize_t ret = -EBADF;
@@ -615,8 +615,8 @@ SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
return ret;
}
-SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
- size_t, count, loff_t, pos)
+static ssize_t do_pwrite64(unsigned int fd, const char __user *buf,
+ size_t count, loff_t pos)
{
struct fd f;
ssize_t ret = -EBADF;
@@ -635,6 +635,72 @@ SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
return ret;
}
+SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
+ size_t, count, loff_t, pos)
+{
+ return do_pread64(fd, buf, count, pos);
+}
+
+SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
+ size_t, count, loff_t, pos)
+{
+ return do_pwrite64(fd, buf, count, pos);
+}
+
+#ifdef __ARCH_WANT_COMPAT_SYS_PREADWRITE64
+#if defined(__ARCH_WANT_COMPAT_SYS_WITH_PADDING) && \
+ defined(__ARCH_WANT_LE_COMPAT_SYS)
+COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf,
+ u32, count, u32, padding, u32, poslo, u32, poshi)
+#elif defined(__ARCH_WANT_COMPAT_SYS_WITH_PADDING) && \
+ !defined(__ARCH_WANT_LE_COMPAT_SYS)
+COMPAT_SYSCALL_DEFINE6(pread64, unsigned int, fd, char __user *, ubuf,
+ u32, count, u32, padding, u32, poshi, u32, poslo)
+#elif !defined(__ARCH_WANT_COMPAT_SYS_WITH_PADDING) && \
+ defined(__ARCH_WANT_LE_COMPAT_SYS)
+COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, ubuf,
+ u32, count, u32, poslo, u32, poshi)
+#else /* no padding, big endian */
+COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, ubuf,
+ u32, count, u32, poshi, u32, poslo)
+#endif
+{
+#ifdef CONFIG_S390
+ if ((compat_ssize_t) count < 0)
+ return -EINVAL;
+#endif /* CONFIG_S390 */
+ return do_pread64(fd, ubuf, count,
+ ((loff_t) (unsigned long) (poshi) << 32) |
+ (unsigned long) (poslo));
+}
+
+#if defined(__ARCH_WANT_COMPAT_SYS_WITH_PADDING) && \
+ defined(__ARCH_WANT_LE_COMPAT_SYS)
+COMPAT_SYSCALL_DEFINE6(pwrite64, unsigned int, fd, const char __user *, ubuf,
+ u32, count, u32, padding, u32, poslo, u32, poshi)
+#elif defined(__ARCH_WANT_COMPAT_SYS_WITH_PADDING) && \
+ !defined(__ARCH_WANT_LE_COMPAT_SYS)
+COMPAT_SYSCALL_DEFINE6(pwrite64, unsigned int, fd, const char __user *, ubuf,
+ u32, count, u32, padding, u32, poshi, u32, poslo)
+#elif !defined(__ARCH_WANT_COMPAT_SYS_WITH_PADDING) && \
+ defined(__ARCH_WANT_LE_COMPAT_SYS)
+COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, ubuf,
+ u32, count, u32, poslo, u32, poshi)
+#else /* no padding, big endian */
+COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, ubuf,
+ u32, count, u32, poshi, u32, poslo)
+#endif
+{
+#ifdef CONFIG_S390
+ if ((compat_ssize_t) count < 0)
+ return -EINVAL;
+#endif /* CONFIG_S390 */
+ return do_pwrite64(fd, ubuf, count,
+ ((loff_t) (unsigned long) (poshi) << 32) |
+ (unsigned long) (poslo));
+}
+#endif /* __ARCH_WANT_COMPAT_SYS_PREADWRITE64 */
+
static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
loff_t *ppos, int type, rwf_t flags)
{
@@ -857,6 +857,21 @@ asmlinkage long compat_sys_truncate64(const char __user *,
#endif /* __ARCH_WANT_COMPAT_SYS_WITH_PADDING */
#endif /* __ARCH_WANT_COMPAT_SYS_TRUNCATE64 */
+#ifdef __ARCH_WANT_COMPAT_SYS_PREADWRITE64
+/* __ARCH_WANT_LE_COMPAT_SYS determines order of lo and hi */
+#ifdef __ARCH_WANT_COMPAT_SYS_WITH_PADDING
+asmlinkage long compat_sys_pwrite64(unsigned int, const char __user *, u32,
+ u32, u32, u32);
+asmlinkage long compat_sys_pread64(unsigned int, char __user *, u32,
+ u32, u32, u32);
+#else /* __ARCH_WANT_COMPAT_SYS_WITH_PADDING */
+asmlinkage long compat_sys_pwrite64(unsigned int, const char __user *,
+ u32, u32, u32);
+asmlinkage long compat_sys_pread64(unsigned int, char __user *,
+ u32, u32, u32);
+#endif /* __ARCH_WANT_COMPAT_SYS_WITH_PADDING */
+#endif /* __ARCH_WANT_COMPAT_SYS_PREADWRITE64 */
+
int compat_restore_altstack(const compat_stack_t __user *uss);
int __compat_save_altstack(compat_stack_t __user *, unsigned long);
#define compat_save_altstack_ex(uss, sp) do { \
The compat_sys_{read,write}64() implementations in mips, powerpc, s390, sparc and x86 only differed based on whether the u64 parameter needed padding and on their endianness. Oh, and some defined the parameters as u64 or "unsigned long" which expanded to u64, though it only expected u32 in these parameters. This patch is part of a series which tries to remove in-kernel calls to syscalls. On this basis, the syscall entry path can be streamlined. Suggested-by: Al Viro <viro@ZenIV.linux.org.uk> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: James Hogan <jhogan@kernel.org> Cc: linux-mips@linux-mips.org Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: linuxppc-dev@lists.ozlabs.org Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: linux-s390@vger.kernel.org Cc: David S. Miller <davem@davemloft.net> Cc: sparclinux@vger.kernel.org Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Slaby <jslaby@suse.com> Cc: x86@kernel.org Cc: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net> --- arch/mips/include/asm/unistd.h | 1 + arch/mips/kernel/linux32.c | 16 -------- arch/mips/kernel/scall64-o32.S | 4 +- arch/powerpc/include/asm/unistd.h | 1 + arch/powerpc/kernel/sys_ppc32.c | 12 ------ arch/s390/include/asm/unistd.h | 1 + arch/s390/kernel/compat_linux.c | 16 -------- arch/s390/kernel/compat_linux.h | 2 - arch/s390/kernel/syscalls/syscall.tbl | 4 +- arch/sparc/include/asm/unistd.h | 1 + arch/sparc/kernel/sys_sparc32.c | 18 --------- arch/sparc/kernel/systbls.h | 10 ----- arch/sparc/kernel/systbls_64.S | 2 +- arch/x86/entry/syscalls/syscall_32.tbl | 4 +- arch/x86/ia32/sys_ia32.c | 16 -------- arch/x86/include/asm/sys_ia32.h | 5 --- arch/x86/include/asm/unistd.h | 1 + fs/read_write.c | 74 ++++++++++++++++++++++++++++++++-- include/linux/compat.h | 15 +++++++ 19 files changed, 97 insertions(+), 106 deletions(-)