Commit 0ad50c3896afbb3c103409a18260e601b87a744c

Authored by Catalin Marinas
Committed by Linus Torvalds
1 parent 918854a65e

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: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Chris Metcalf <cmetcalf@tilera.com>  [for tile]
Acked-by: David S. Miller <davem@davemloft.net>
Acked-by: Arnd 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 12 changed files with 29 additions and 63 deletions Side-by-side Diff

arch/arm64/include/asm/unistd.h
... ... @@ -20,6 +20,7 @@
20 20 #define __ARCH_WANT_SYS_GETPGRP
21 21 #define __ARCH_WANT_SYS_LLSEEK
22 22 #define __ARCH_WANT_SYS_NICE
  23 +#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
23 24 #define __ARCH_WANT_SYS_SIGPENDING
24 25 #define __ARCH_WANT_SYS_SIGPROCMASK
25 26 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
arch/arm64/kernel/sys_compat.c
... ... @@ -28,21 +28,6 @@
28 28 #include <asm/cacheflush.h>
29 29 #include <asm/unistd32.h>
30 30  
31   -asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
32   - struct compat_timespec __user *interval)
33   -{
34   - struct timespec t;
35   - int ret;
36   - mm_segment_t old_fs = get_fs();
37   -
38   - set_fs(KERNEL_DS);
39   - ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
40   - set_fs(old_fs);
41   - if (put_compat_timespec(&t, interval))
42   - return -EFAULT;
43   - return ret;
44   -}
45   -
46 31 static inline void
47 32 do_compat_cache_op(unsigned long start, unsigned long end, int flags)
48 33 {
arch/powerpc/include/asm/systbl.h
... ... @@ -164,7 +164,7 @@
164 164 SYSCALL_SPU(sched_yield)
165 165 COMPAT_SYS_SPU(sched_get_priority_max)
166 166 COMPAT_SYS_SPU(sched_get_priority_min)
167   -COMPAT_SYS_SPU(sched_rr_get_interval)
  167 +SYSX_SPU(sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval_wrapper,sys_sched_rr_get_interval)
168 168 COMPAT_SYS_SPU(nanosleep)
169 169 SYSCALL_SPU(mremap)
170 170 SYSCALL_SPU(setresuid)
arch/powerpc/include/asm/unistd.h
... ... @@ -54,6 +54,7 @@
54 54 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
55 55 #define __ARCH_WANT_SYS_NEWFSTATAT
56 56 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
  57 +#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
57 58 #endif
58 59 #define __ARCH_WANT_SYS_EXECVE
59 60 #define __ARCH_WANT_SYS_FORK
arch/powerpc/kernel/sys_ppc32.c
... ... @@ -175,19 +175,10 @@
175 175 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
176 176 * and the register representation of a signed int (msr in 64-bit mode) is performed.
177 177 */
178   -asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval)
  178 +asmlinkage long compat_sys_sched_rr_get_interval_wrapper(u32 pid,
  179 + struct compat_timespec __user *interval)
179 180 {
180   - struct timespec t;
181   - int ret;
182   - mm_segment_t old_fs = get_fs ();
183   -
184   - /* The __user pointer cast is valid because of the set_fs() */
185   - set_fs (KERNEL_DS);
186   - ret = sys_sched_rr_get_interval((int)pid, (struct timespec __user *) &t);
187   - set_fs (old_fs);
188   - if (put_compat_timespec(&t, interval))
189   - return -EFAULT;
190   - return ret;
  181 + return compat_sys_sched_rr_get_interval((int)pid, interval);
191 182 }
192 183  
193 184 /* Note: it is necessary to treat mode as an unsigned int,
arch/sparc/include/asm/unistd.h
... ... @@ -45,6 +45,7 @@
45 45 #define __ARCH_WANT_COMPAT_SYS_TIME
46 46 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
47 47 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
  48 +#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
48 49 #endif
49 50 #define __ARCH_WANT_SYS_EXECVE
50 51  
arch/sparc/kernel/sys_sparc32.c
... ... @@ -211,20 +211,6 @@
211 211 return sys_sysfs(option, arg1, arg2);
212 212 }
213 213  
214   -asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *interval)
215   -{
216   - struct timespec t;
217   - int ret;
218   - mm_segment_t old_fs = get_fs ();
219   -
220   - set_fs (KERNEL_DS);
221   - ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t);
222   - set_fs (old_fs);
223   - if (put_compat_timespec(&t, interval))
224   - return -EFAULT;
225   - return ret;
226   -}
227   -
228 214 asmlinkage long compat_sys_rt_sigprocmask(int how,
229 215 compat_sigset_t __user *set,
230 216 compat_sigset_t __user *oset,
arch/tile/include/asm/compat.h
... ... @@ -296,8 +296,6 @@
296 296 long compat_sys_fallocate(int fd, int mode,
297 297 u32 offset_lo, u32 offset_hi,
298 298 u32 len_lo, u32 len_hi);
299   -long compat_sys_sched_rr_get_interval(compat_pid_t pid,
300   - struct compat_timespec __user *interval);
301 299  
302 300 /* Assembly trampoline to avoid clobbering r0. */
303 301 long _compat_sys_rt_sigreturn(void);
arch/tile/include/asm/unistd.h
... ... @@ -14,6 +14,7 @@
14 14 /* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
15 15 #ifdef CONFIG_COMPAT
16 16 #define __ARCH_WANT_SYS_LLSEEK
  17 +#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
17 18 #endif
18 19 #define __ARCH_WANT_SYS_NEWFSTATAT
19 20 #define __ARCH_WANT_SYS_EXECVE
arch/tile/kernel/compat.c
... ... @@ -76,24 +76,6 @@
76 76 ((loff_t)len_hi << 32) | len_lo);
77 77 }
78 78  
79   -
80   -
81   -long compat_sys_sched_rr_get_interval(compat_pid_t pid,
82   - struct compat_timespec __user *interval)
83   -{
84   - struct timespec t;
85   - int ret;
86   - mm_segment_t old_fs = get_fs();
87   -
88   - set_fs(KERNEL_DS);
89   - ret = sys_sched_rr_get_interval(pid,
90   - (struct timespec __force __user *)&t);
91   - set_fs(old_fs);
92   - if (put_compat_timespec(&t, interval))
93   - return -EFAULT;
94   - return ret;
95   -}
96   -
97 79 /* Provide the compat syscall number to call mapping. */
98 80 #undef __SYSCALL
99 81 #define __SYSCALL(nr, call) [nr] = (call),
include/linux/compat.h
... ... @@ -588,6 +588,9 @@
588 588 asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
589 589 compat_off_t __user *offset, compat_size_t count);
590 590  
  591 +asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
  592 + struct compat_timespec __user *interval);
  593 +
591 594 #else
592 595  
593 596 #define is_compat_task() (0)
... ... @@ -1215,6 +1215,23 @@
1215 1215 return 0;
1216 1216 }
1217 1217  
  1218 +#ifdef __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
  1219 +asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
  1220 + struct compat_timespec __user *interval)
  1221 +{
  1222 + struct timespec t;
  1223 + int ret;
  1224 + mm_segment_t old_fs = get_fs();
  1225 +
  1226 + set_fs(KERNEL_DS);
  1227 + ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t);
  1228 + set_fs(old_fs);
  1229 + if (put_compat_timespec(&t, interval))
  1230 + return -EFAULT;
  1231 + return ret;
  1232 +}
  1233 +#endif /* __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL */
  1234 +
1218 1235 /*
1219 1236 * Allocate user-space memory for the duration of a single system call,
1220 1237 * in order to marshall parameters inside a compat thunk.