diff options
Diffstat (limited to 'arch/s390/kernel/compat_linux.c')
| -rw-r--r-- | arch/s390/kernel/compat_linux.c | 397 | 
1 files changed, 108 insertions, 289 deletions
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 1e6449c79ab..ca38139423a 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -1,8 +1,6 @@  /* - *  arch/s390x/kernel/linux32.c - *   *  S390 version - *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation + *    Copyright IBM Corp. 2000   *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),   *               Gerhard Tonn (ton@de.ibm.com)      *               Thomas Spatzier (tspat@de.ibm.com) @@ -25,7 +23,6 @@  #include <linux/resource.h>  #include <linux/times.h>  #include <linux/smp.h> -#include <linux/smp_lock.h>  #include <linux/sem.h>  #include <linux/msg.h>  #include <linux/shm.h> @@ -61,13 +58,6 @@  #include "compat_linux.h" -long psw_user32_bits	= (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME | -			   PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | -			   PSW_MASK_PSTATE | PSW_DEFAULT_KEY); -long psw32_user_bits	= (PSW32_BASE_BITS | PSW32_MASK_DAT | PSW32_ASC_HOME | -			   PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK | -			   PSW32_MASK_PSTATE); -   /* For this source file, we want overflow handling. */  #undef high2lowuid @@ -96,92 +86,111 @@ long psw32_user_bits	= (PSW32_BASE_BITS | PSW32_MASK_DAT | PSW32_ASC_HOME |  #define SET_STAT_UID(stat, uid)		(stat).st_uid = high2lowuid(uid)  #define SET_STAT_GID(stat, gid)		(stat).st_gid = high2lowgid(gid) -asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group) +COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename, +		       u16, user, u16, group)  {  	return sys_chown(filename, low2highuid(user), low2highgid(group));  } -asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group) +COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *, +		       filename, u16, user, u16, group)  {  	return sys_lchown(filename, low2highuid(user), low2highgid(group));  } -asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group) +COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group)  {  	return sys_fchown(fd, low2highuid(user), low2highgid(group));  } -asmlinkage long sys32_setregid16(u16 rgid, u16 egid) +COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid)  {  	return sys_setregid(low2highgid(rgid), low2highgid(egid));  } -asmlinkage long sys32_setgid16(u16 gid) +COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid)  {  	return sys_setgid((gid_t)gid);  } -asmlinkage long sys32_setreuid16(u16 ruid, u16 euid) +COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid)  {  	return sys_setreuid(low2highuid(ruid), low2highuid(euid));  } -asmlinkage long sys32_setuid16(u16 uid) +COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid)  {  	return sys_setuid((uid_t)uid);  } -asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid) +COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid)  {  	return sys_setresuid(low2highuid(ruid), low2highuid(euid), -		low2highuid(suid)); +			     low2highuid(suid));  } -asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid) +COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp, +		       u16 __user *, euidp, u16 __user *, suidp)  { +	const struct cred *cred = current_cred();  	int retval; +	u16 ruid, euid, suid; + +	ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid)); +	euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid)); +	suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid)); -	if (!(retval = put_user(high2lowuid(current->cred->uid), ruid)) && -	    !(retval = put_user(high2lowuid(current->cred->euid), euid))) -		retval = put_user(high2lowuid(current->cred->suid), suid); +	if (!(retval   = put_user(ruid, ruidp)) && +	    !(retval   = put_user(euid, euidp))) +		retval = put_user(suid, suidp);  	return retval;  } -asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid) +COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid)  {  	return sys_setresgid(low2highgid(rgid), low2highgid(egid), -		low2highgid(sgid)); +			     low2highgid(sgid));  } -asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid) +COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp, +		       u16 __user *, egidp, u16 __user *, sgidp)  { +	const struct cred *cred = current_cred();  	int retval; +	u16 rgid, egid, sgid; -	if (!(retval = put_user(high2lowgid(current->cred->gid), rgid)) && -	    !(retval = put_user(high2lowgid(current->cred->egid), egid))) -		retval = put_user(high2lowgid(current->cred->sgid), sgid); +	rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid)); +	egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid)); +	sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid)); + +	if (!(retval   = put_user(rgid, rgidp)) && +	    !(retval   = put_user(egid, egidp))) +		retval = put_user(sgid, sgidp);  	return retval;  } -asmlinkage long sys32_setfsuid16(u16 uid) +COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid)  {  	return sys_setfsuid((uid_t)uid);  } -asmlinkage long sys32_setfsgid16(u16 gid) +COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid)  {  	return sys_setfsgid((gid_t)gid);  }  static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info)  { +	struct user_namespace *user_ns = current_user_ns();  	int i;  	u16 group; +	kgid_t kgid;  	for (i = 0; i < group_info->ngroups; i++) { -		group = (u16)GROUP_AT(group_info, i); +		kgid = GROUP_AT(group_info, i); +		group = (u16)from_kgid_munged(user_ns, kgid);  		if (put_user(group, grouplist+i))  			return -EFAULT;  	} @@ -191,43 +200,51 @@ static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info  static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist)  { +	struct user_namespace *user_ns = current_user_ns();  	int i;  	u16 group; +	kgid_t kgid;  	for (i = 0; i < group_info->ngroups; i++) {  		if (get_user(group, grouplist+i))  			return  -EFAULT; -		GROUP_AT(group_info, i) = (gid_t)group; + +		kgid = make_kgid(user_ns, (gid_t)group); +		if (!gid_valid(kgid)) +			return -EINVAL; + +		GROUP_AT(group_info, i) = kgid;  	}  	return 0;  } -asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist) +COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist)  { +	const struct cred *cred = current_cred();  	int i;  	if (gidsetsize < 0)  		return -EINVAL; -	get_group_info(current->cred->group_info); -	i = current->cred->group_info->ngroups; +	get_group_info(cred->group_info); +	i = cred->group_info->ngroups;  	if (gidsetsize) {  		if (i > gidsetsize) {  			i = -EINVAL;  			goto out;  		} -		if (groups16_to_user(grouplist, current->cred->group_info)) { +		if (groups16_to_user(grouplist, cred->group_info)) {  			i = -EFAULT;  			goto out;  		}  	}  out: -	put_group_info(current->cred->group_info); +	put_group_info(cred->group_info);  	return i;  } -asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) +COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist)  {  	struct group_info *group_info;  	int retval; @@ -252,273 +269,65 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)  	return retval;  } -asmlinkage long sys32_getuid16(void) +COMPAT_SYSCALL_DEFINE0(s390_getuid16)  { -	return high2lowuid(current->cred->uid); +	return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));  } -asmlinkage long sys32_geteuid16(void) +COMPAT_SYSCALL_DEFINE0(s390_geteuid16)  { -	return high2lowuid(current->cred->euid); +	return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));  } -asmlinkage long sys32_getgid16(void) +COMPAT_SYSCALL_DEFINE0(s390_getgid16)  { -	return high2lowgid(current->cred->gid); +	return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));  } -asmlinkage long sys32_getegid16(void) +COMPAT_SYSCALL_DEFINE0(s390_getegid16)  { -	return high2lowgid(current->cred->egid); +	return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));  } -/* - * sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation. - * - * This is really horribly ugly. - */  #ifdef CONFIG_SYSVIPC -asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) +COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, +		compat_ulong_t, third, compat_uptr_t, ptr)  {  	if (call >> 16)		/* hack for backward compatibility */  		return -EINVAL; - -	call &= 0xffff; - -	switch (call) { -	case SEMTIMEDOP: -		return compat_sys_semtimedop(first, compat_ptr(ptr), -					     second, compat_ptr(third)); -	case SEMOP: -		/* struct sembuf is the same on 32 and 64bit :)) */ -		return sys_semtimedop(first, compat_ptr(ptr), -				      second, NULL); -	case SEMGET: -		return sys_semget(first, second, third); -	case SEMCTL: -		return compat_sys_semctl(first, second, third, -					 compat_ptr(ptr)); -	case MSGSND: -		return compat_sys_msgsnd(first, second, third, -					 compat_ptr(ptr)); -	case MSGRCV: -		return compat_sys_msgrcv(first, second, 0, third, -					 0, compat_ptr(ptr)); -	case MSGGET: -		return sys_msgget((key_t) first, second); -	case MSGCTL: -		return compat_sys_msgctl(first, second, compat_ptr(ptr)); -	case SHMAT: -		return compat_sys_shmat(first, second, third, -					0, compat_ptr(ptr)); -	case SHMDT: -		return sys_shmdt(compat_ptr(ptr)); -	case SHMGET: -		return sys_shmget(first, (unsigned)second, third); -	case SHMCTL: -		return compat_sys_shmctl(first, second, compat_ptr(ptr)); -	} - -	return -ENOSYS; +	return compat_sys_ipc(call, first, second, third, ptr, third);  }  #endif -asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) +COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u32, low)  { -	if ((int)high < 0) -		return -EINVAL; -	else -		return sys_truncate(path, (high << 32) | low); +	return sys_truncate(path, (unsigned long)high << 32 | low);  } -asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned long low) +COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low)  { -	if ((int)high < 0) -		return -EINVAL; -	else -		return sys_ftruncate(fd, (high << 32) | low); -} - -asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, -				struct compat_timespec __user *interval) -{ -	struct timespec t; -	int ret; -	mm_segment_t old_fs = get_fs (); -	 -	set_fs (KERNEL_DS); -	ret = sys_sched_rr_get_interval(pid, -					(struct timespec __force __user *) &t); -	set_fs (old_fs); -	if (put_compat_timespec(&t, interval)) -		return -EFAULT; -	return ret; +	return sys_ftruncate(fd, (unsigned long)high << 32 | low);  } -asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, -			compat_sigset_t __user *oset, size_t sigsetsize) -{ -	sigset_t s; -	compat_sigset_t s32; -	int ret; -	mm_segment_t old_fs = get_fs(); -	 -	if (set) { -		if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) -			return -EFAULT; -		switch (_NSIG_WORDS) { -		case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); -		case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); -		case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); -		case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); -		} -	} -	set_fs (KERNEL_DS); -	ret = sys_rt_sigprocmask(how, -				 set ? (sigset_t __force __user *) &s : NULL, -				 oset ? (sigset_t __force __user *) &s : NULL, -				 sigsetsize); -	set_fs (old_fs); -	if (ret) return ret; -	if (oset) { -		switch (_NSIG_WORDS) { -		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; -		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; -		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; -		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; -		} -		if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) -			return -EFAULT; -	} -	return 0; -} - -asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set, -				size_t sigsetsize) -{ -	sigset_t s; -	compat_sigset_t s32; -	int ret; -	mm_segment_t old_fs = get_fs(); -		 -	set_fs (KERNEL_DS); -	ret = sys_rt_sigpending((sigset_t __force __user *) &s, sigsetsize); -	set_fs (old_fs); -	if (!ret) { -		switch (_NSIG_WORDS) { -		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3]; -		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2]; -		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1]; -		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0]; -		} -		if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) -			return -EFAULT; -	} -	return ret; -} - -asmlinkage long -sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) -{ -	siginfo_t info; -	int ret; -	mm_segment_t old_fs = get_fs(); -	 -	if (copy_siginfo_from_user32(&info, uinfo)) -		return -EFAULT; -	set_fs (KERNEL_DS); -	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *) &info); -	set_fs (old_fs); -	return ret; -} - -/* - * sys32_execve() executes a new program after the asm stub has set - * things up for us.  This should basically do what I want it to. - */ -asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv, -			     compat_uptr_t __user *envp) -{ -	struct pt_regs *regs = task_pt_regs(current); -	char *filename; -	long rc; - -	filename = getname(name); -	rc = PTR_ERR(filename); -	if (IS_ERR(filename)) -		return rc; -	rc = compat_do_execve(filename, argv, envp, regs); -	if (rc) -		goto out; -	current->thread.fp_regs.fpc=0; -	asm volatile("sfpc %0,0" : : "d" (0)); -	rc = regs->gprs[2]; -out: -	putname(filename); -	return rc; -} - -asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, -				size_t count, u32 poshi, u32 poslo) +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, ((loff_t)AA(poshi) << 32) | AA(poslo)); +	return sys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low);  } -asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf, -				size_t count, u32 poshi, u32 poslo) +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, ((loff_t)AA(poshi) << 32) | AA(poslo)); +	return sys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low);  } -asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 count) +COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count)  { -	return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); -} - -asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count) -{ -	mm_segment_t old_fs = get_fs(); -	int ret; -	off_t of; -	 -	if (offset && get_user(of, offset)) -		return -EFAULT; -		 -	set_fs(KERNEL_DS); -	ret = sys_sendfile(out_fd, in_fd, -			   offset ? (off_t __force __user *) &of : NULL, count); -	set_fs(old_fs); -	 -	if (offset && put_user(of, offset)) -		return -EFAULT; -		 -	return ret; -} - -asmlinkage long sys32_sendfile64(int out_fd, int in_fd, -				compat_loff_t __user *offset, s32 count) -{ -	mm_segment_t old_fs = get_fs(); -	int ret; -	loff_t lof; -	 -	if (offset && get_user(lof, offset)) -		return -EFAULT; -		 -	set_fs(KERNEL_DS); -	ret = sys_sendfile64(out_fd, in_fd, -			     offset ? (loff_t __force __user *) &lof : NULL, -			     count); -	set_fs(old_fs); -	 -	if (offset && put_user(lof, offset)) -		return -EFAULT; -		 -	return ret; +	return sys_readahead(fd, (unsigned long)high << 32 | low, count);  }  struct stat64_emu31 { @@ -557,8 +366,8 @@ static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)  	tmp.__st_ino = (u32)stat->ino;  	tmp.st_mode = stat->mode;  	tmp.st_nlink = (unsigned int)stat->nlink; -	tmp.st_uid = stat->uid; -	tmp.st_gid = stat->gid; +	tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid); +	tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);  	tmp.st_rdev = huge_encode_dev(stat->rdev);  	tmp.st_size = stat->size;  	tmp.st_blksize = (u32)stat->blksize; @@ -570,7 +379,7 @@ static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)  	return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;   } -asmlinkage long sys32_stat64(const char __user * filename, struct stat64_emu31 __user * statbuf) +COMPAT_SYSCALL_DEFINE2(s390_stat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf)  {  	struct kstat stat;  	int ret = vfs_stat(filename, &stat); @@ -579,7 +388,7 @@ asmlinkage long sys32_stat64(const char __user * filename, struct stat64_emu31 _  	return ret;  } -asmlinkage long sys32_lstat64(const char __user * filename, struct stat64_emu31 __user * statbuf) +COMPAT_SYSCALL_DEFINE2(s390_lstat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf)  {  	struct kstat stat;  	int ret = vfs_lstat(filename, &stat); @@ -588,7 +397,7 @@ asmlinkage long sys32_lstat64(const char __user * filename, struct stat64_emu31  	return ret;  } -asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf) +COMPAT_SYSCALL_DEFINE2(s390_fstat64, unsigned int, fd, struct stat64_emu31 __user *, statbuf)  {  	struct kstat stat;  	int ret = vfs_fstat(fd, &stat); @@ -597,8 +406,8 @@ asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * sta  	return ret;  } -asmlinkage long sys32_fstatat64(unsigned int dfd, const char __user *filename, -				struct stat64_emu31 __user* statbuf, int flag) +COMPAT_SYSCALL_DEFINE4(s390_fstatat64, unsigned int, dfd, const char __user *, filename, +		       struct stat64_emu31 __user *, statbuf, int, flag)  {  	struct kstat stat;  	int error; @@ -624,7 +433,7 @@ struct mmap_arg_struct_emu31 {  	compat_ulong_t offset;  }; -asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) +COMPAT_SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct_emu31 __user *, arg)  {  	struct mmap_arg_struct_emu31 a; @@ -632,22 +441,20 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg)  		return -EFAULT;  	if (a.offset & ~PAGE_MASK)  		return -EINVAL; -	a.addr = (unsigned long) compat_ptr(a.addr);  	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,  			      a.offset >> PAGE_SHIFT);  } -asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) +COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg)  {  	struct mmap_arg_struct_emu31 a;  	if (copy_from_user(&a, arg, sizeof(a)))  		return -EFAULT; -	a.addr = (unsigned long) compat_ptr(a.addr);  	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);  } -asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count) +COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)  {  	if ((compat_ssize_t) count < 0)  		return -EINVAL;  @@ -655,7 +462,7 @@ asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count)  	return sys_read(fd, buf, count);  } -asmlinkage long sys32_write(unsigned int fd, const char __user * buf, size_t count) +COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count)  {  	if ((compat_ssize_t) count < 0)  		return -EINVAL;  @@ -669,14 +476,13 @@ asmlinkage long sys32_write(unsigned int fd, const char __user * buf, size_t cou   * because the 31 bit values differ from the 64 bit values.   */ -asmlinkage long -sys32_fadvise64(int fd, loff_t offset, size_t len, int advise) +COMPAT_SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, high, u32, low, compat_size_t, len, int, advise)  {  	if (advise == 4)  		advise = POSIX_FADV_DONTNEED;  	else if (advise == 5)  		advise = POSIX_FADV_NOREUSE; -	return sys_fadvise64(fd, offset, len, advise); +	return sys_fadvise64(fd, (unsigned long)high << 32 | low, len, advise);  }  struct fadvise64_64_args { @@ -686,8 +492,7 @@ struct fadvise64_64_args {  	int advice;  }; -asmlinkage long -sys32_fadvise64_64(struct fadvise64_64_args __user *args) +COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args)  {  	struct fadvise64_64_args a; @@ -699,3 +504,17 @@ sys32_fadvise64_64(struct fadvise64_64_args __user *args)  		a.advice = POSIX_FADV_NOREUSE;  	return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);  } + +COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow, +		       u32, nhigh, u32, nlow, unsigned int, flags) +{ +	return sys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow, +				   ((u64)nhigh << 32) + nlow, flags); +} + +COMPAT_SYSCALL_DEFINE6(s390_fallocate, int, fd, int, mode, u32, offhigh, u32, offlow, +		       u32, lenhigh, u32, lenlow) +{ +	return sys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow, +			     ((u64)lenhigh << 32) + lenlow); +}  | 
