Commit 0ad50c3896afbb3c103409a18260e601b87a744c
Committed by
Linus Torvalds
1 parent
918854a65e
Exists in
master
and in
20 other branches
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
- arch/arm64/kernel/sys_compat.c
- arch/powerpc/include/asm/systbl.h
- arch/powerpc/include/asm/unistd.h
- arch/powerpc/kernel/sys_ppc32.c
- arch/sparc/include/asm/unistd.h
- arch/sparc/kernel/sys_sparc32.c
- arch/tile/include/asm/compat.h
- arch/tile/include/asm/unistd.h
- arch/tile/kernel/compat.c
- include/linux/compat.h
- kernel/compat.c
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
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) |
kernel/compat.c
... | ... | @@ -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. |