Commit 0ad50c38 authored by Catalin Marinas's avatar Catalin Marinas Committed by Linus Torvalds

compat: generic compat_sys_sched_rr_get_interval() implementation

This function is used by sparc, powerpc tile and arm64 for compat support.
 The patch adds a generic implementation with a wrapper for PowerPC to do
the u32->int sign extension.

The reason for a single patch covering powerpc, tile, sparc and arm64 is
to keep it bisectable, otherwise kernel building may fail with mismatched
function declarations.
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Acked-by: Chris Metcalf <cmetcalf@tilera.com>  [for tile]
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 918854a6
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define __ARCH_WANT_SYS_GETPGRP #define __ARCH_WANT_SYS_GETPGRP
#define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_SYS_NICE #define __ARCH_WANT_SYS_NICE
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
#define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK #define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
......
...@@ -28,21 +28,6 @@ ...@@ -28,21 +28,6 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/unistd32.h> #include <asm/unistd32.h>
asmlinkage int compat_sys_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 __user *)&t);
set_fs(old_fs);
if (put_compat_timespec(&t, interval))
return -EFAULT;
return ret;
}
static inline void static inline void
do_compat_cache_op(unsigned long start, unsigned long end, int flags) do_compat_cache_op(unsigned long start, unsigned long end, int flags)
{ {
......
...@@ -164,7 +164,7 @@ COMPAT_SYS_SPU(sched_getscheduler) ...@@ -164,7 +164,7 @@ COMPAT_SYS_SPU(sched_getscheduler)
SYSCALL_SPU(sched_yield) SYSCALL_SPU(sched_yield)
COMPAT_SYS_SPU(sched_get_priority_max) COMPAT_SYS_SPU(sched_get_priority_max)
COMPAT_SYS_SPU(sched_get_priority_min) COMPAT_SYS_SPU(sched_get_priority_min)
COMPAT_SYS_SPU(sched_rr_get_interval) SYSX_SPU(sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval_wrapper,sys_sched_rr_get_interval)
COMPAT_SYS_SPU(nanosleep) COMPAT_SYS_SPU(nanosleep)
SYSCALL_SPU(mremap) SYSCALL_SPU(mremap)
SYSCALL_SPU(setresuid) SYSCALL_SPU(setresuid)
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_SYS_NEWFSTATAT #define __ARCH_WANT_SYS_NEWFSTATAT
#define __ARCH_WANT_COMPAT_SYS_SENDFILE #define __ARCH_WANT_COMPAT_SYS_SENDFILE
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
#endif #endif
#define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_EXECVE
#define __ARCH_WANT_SYS_FORK #define __ARCH_WANT_SYS_FORK
......
...@@ -175,19 +175,10 @@ asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 a ...@@ -175,19 +175,10 @@ asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 a
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
* and the register representation of a signed int (msr in 64-bit mode) is performed. * and the register representation of a signed int (msr in 64-bit mode) is performed.
*/ */
asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) asmlinkage long compat_sys_sched_rr_get_interval_wrapper(u32 pid,
{ struct compat_timespec __user *interval)
struct timespec t; {
int ret; return compat_sys_sched_rr_get_interval((int)pid, interval);
mm_segment_t old_fs = get_fs ();
/* The __user pointer cast is valid because of the set_fs() */
set_fs (KERNEL_DS);
ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t);
set_fs (old_fs);
if (put_compat_timespec(&t, interval))
return -EFAULT;
return ret;
} }
/* Note: it is necessary to treat mode as an unsigned int, /* Note: it is necessary to treat mode as an unsigned int,
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#define __ARCH_WANT_COMPAT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_COMPAT_SYS_SENDFILE #define __ARCH_WANT_COMPAT_SYS_SENDFILE
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
#endif #endif
#define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_EXECVE
......
...@@ -211,20 +211,6 @@ asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2) ...@@ -211,20 +211,6 @@ asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
return sys_sysfs(option, arg1, arg2); return sys_sysfs(option, arg1, arg2);
} }
asmlinkage long compat_sys_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 __user *) &t);
set_fs (old_fs);
if (put_compat_timespec(&t, interval))
return -EFAULT;
return ret;
}
asmlinkage long compat_sys_rt_sigprocmask(int how, asmlinkage long compat_sys_rt_sigprocmask(int how,
compat_sigset_t __user *set, compat_sigset_t __user *set,
compat_sigset_t __user *oset, compat_sigset_t __user *oset,
......
...@@ -296,8 +296,6 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags, ...@@ -296,8 +296,6 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
long compat_sys_fallocate(int fd, int mode, long compat_sys_fallocate(int fd, int mode,
u32 offset_lo, u32 offset_hi, u32 offset_lo, u32 offset_hi,
u32 len_lo, u32 len_hi); u32 len_lo, u32 len_hi);
long compat_sys_sched_rr_get_interval(compat_pid_t pid,
struct compat_timespec __user *interval);
/* Assembly trampoline to avoid clobbering r0. */ /* Assembly trampoline to avoid clobbering r0. */
long _compat_sys_rt_sigreturn(void); long _compat_sys_rt_sigreturn(void);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */ /* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
#define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_LLSEEK
#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
#endif #endif
#define __ARCH_WANT_SYS_NEWFSTATAT #define __ARCH_WANT_SYS_NEWFSTATAT
#define __ARCH_WANT_SYS_EXECVE #define __ARCH_WANT_SYS_EXECVE
......
...@@ -76,24 +76,6 @@ long compat_sys_fallocate(int fd, int mode, ...@@ -76,24 +76,6 @@ long compat_sys_fallocate(int fd, int mode,
((loff_t)len_hi << 32) | len_lo); ((loff_t)len_hi << 32) | len_lo);
} }
long compat_sys_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;
}
/* Provide the compat syscall number to call mapping. */ /* Provide the compat syscall number to call mapping. */
#undef __SYSCALL #undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call), #define __SYSCALL(nr, call) [nr] = (call),
......
...@@ -588,6 +588,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid, ...@@ -588,6 +588,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
compat_off_t __user *offset, compat_size_t count); compat_off_t __user *offset, compat_size_t count);
asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
struct compat_timespec __user *interval);
#else #else
#define is_compat_task() (0) #define is_compat_task() (0)
......
...@@ -1215,6 +1215,23 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info) ...@@ -1215,6 +1215,23 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
return 0; return 0;
} }
#ifdef __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
asmlinkage long compat_sys_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 __user *)&t);
set_fs(old_fs);
if (put_compat_timespec(&t, interval))
return -EFAULT;
return ret;
}
#endif /* __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL */
/* /*
* Allocate user-space memory for the duration of a single system call, * Allocate user-space memory for the duration of a single system call,
* in order to marshall parameters inside a compat thunk. * in order to marshall parameters inside a compat thunk.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment