aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2012-12-17 19:01:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-17 20:15:18 -0500
commit0ad50c3896afbb3c103409a18260e601b87a744c (patch)
tree3a59c1e90b3ee62daf18bc9689cf454a31f164be
parent918854a65e856574523d94763ef2a2b48ad55a25 (diff)
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>
-rw-r--r--arch/arm64/include/asm/unistd.h1
-rw-r--r--arch/arm64/kernel/sys_compat.c15
-rw-r--r--arch/powerpc/include/asm/systbl.h2
-rw-r--r--arch/powerpc/include/asm/unistd.h1
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c17
-rw-r--r--arch/sparc/include/asm/unistd.h1
-rw-r--r--arch/sparc/kernel/sys_sparc32.c14
-rw-r--r--arch/tile/include/asm/compat.h2
-rw-r--r--arch/tile/include/asm/unistd.h1
-rw-r--r--arch/tile/kernel/compat.c18
-rw-r--r--include/linux/compat.h3
-rw-r--r--kernel/compat.c17
12 files changed, 29 insertions, 63 deletions
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index d69aeea6da1..76fb7dd3350 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -20,6 +20,7 @@
20#define __ARCH_WANT_SYS_GETPGRP 20#define __ARCH_WANT_SYS_GETPGRP
21#define __ARCH_WANT_SYS_LLSEEK 21#define __ARCH_WANT_SYS_LLSEEK
22#define __ARCH_WANT_SYS_NICE 22#define __ARCH_WANT_SYS_NICE
23#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
23#define __ARCH_WANT_SYS_SIGPENDING 24#define __ARCH_WANT_SYS_SIGPENDING
24#define __ARCH_WANT_SYS_SIGPROCMASK 25#define __ARCH_WANT_SYS_SIGPROCMASK
25#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 26#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index f7b05edf8ce..26e9c4eeaba 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -28,21 +28,6 @@
28#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
29#include <asm/unistd32.h> 29#include <asm/unistd32.h>
30 30
31asmlinkage 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
46static inline void 31static inline void
47do_compat_cache_op(unsigned long start, unsigned long end, int flags) 32do_compat_cache_op(unsigned long start, unsigned long end, int flags)
48{ 33{
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index 84083876985..cec8aae5cbf 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -164,7 +164,7 @@ COMPAT_SYS_SPU(sched_getscheduler)
164SYSCALL_SPU(sched_yield) 164SYSCALL_SPU(sched_yield)
165COMPAT_SYS_SPU(sched_get_priority_max) 165COMPAT_SYS_SPU(sched_get_priority_max)
166COMPAT_SYS_SPU(sched_get_priority_min) 166COMPAT_SYS_SPU(sched_get_priority_min)
167COMPAT_SYS_SPU(sched_rr_get_interval) 167SYSX_SPU(sys_sched_rr_get_interval,compat_sys_sched_rr_get_interval_wrapper,sys_sched_rr_get_interval)
168COMPAT_SYS_SPU(nanosleep) 168COMPAT_SYS_SPU(nanosleep)
169SYSCALL_SPU(mremap) 169SYSCALL_SPU(mremap)
170SYSCALL_SPU(setresuid) 170SYSCALL_SPU(setresuid)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 76fe846ec40..bcbbe413c60 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -54,6 +54,7 @@
54#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 54#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
55#define __ARCH_WANT_SYS_NEWFSTATAT 55#define __ARCH_WANT_SYS_NEWFSTATAT
56#define __ARCH_WANT_COMPAT_SYS_SENDFILE 56#define __ARCH_WANT_COMPAT_SYS_SENDFILE
57#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
57#endif 58#endif
58#define __ARCH_WANT_SYS_EXECVE 59#define __ARCH_WANT_SYS_EXECVE
59#define __ARCH_WANT_SYS_FORK 60#define __ARCH_WANT_SYS_FORK
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 9c2ed90ece8..8a93778ed9f 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -175,19 +175,10 @@ asmlinkage long compat_sys_prctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 a
175 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 175 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
176 * and the register representation of a signed int (msr in 64-bit mode) is performed. 176 * and the register representation of a signed int (msr in 64-bit mode) is performed.
177 */ 177 */
178asmlinkage long compat_sys_sched_rr_get_interval(u32 pid, struct compat_timespec __user *interval) 178asmlinkage long compat_sys_sched_rr_get_interval_wrapper(u32 pid,
179{ 179 struct compat_timespec __user *interval)
180 struct timespec t; 180{
181 int ret; 181 return compat_sys_sched_rr_get_interval((int)pid, interval);
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;
191} 182}
192 183
193/* Note: it is necessary to treat mode as an unsigned int, 184/* Note: it is necessary to treat mode as an unsigned int,
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index c3e5d8b6417..497386a7ed2 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -45,6 +45,7 @@
45#define __ARCH_WANT_COMPAT_SYS_TIME 45#define __ARCH_WANT_COMPAT_SYS_TIME
46#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 46#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
47#define __ARCH_WANT_COMPAT_SYS_SENDFILE 47#define __ARCH_WANT_COMPAT_SYS_SENDFILE
48#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
48#endif 49#endif
49#define __ARCH_WANT_SYS_EXECVE 50#define __ARCH_WANT_SYS_EXECVE
50 51
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c
index 03c7e929ec3..4a4cdc633f6 100644
--- a/arch/sparc/kernel/sys_sparc32.c
+++ b/arch/sparc/kernel/sys_sparc32.c
@@ -211,20 +211,6 @@ asmlinkage long compat_sys_sysfs(int option, u32 arg1, u32 arg2)
211 return sys_sysfs(option, arg1, arg2); 211 return sys_sysfs(option, arg1, arg2);
212} 212}
213 213
214asmlinkage 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
228asmlinkage long compat_sys_rt_sigprocmask(int how, 214asmlinkage long compat_sys_rt_sigprocmask(int how,
229 compat_sigset_t __user *set, 215 compat_sigset_t __user *set,
230 compat_sigset_t __user *oset, 216 compat_sigset_t __user *oset,
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
index ca61fb4296b..88f3c227afd 100644
--- a/arch/tile/include/asm/compat.h
+++ b/arch/tile/include/asm/compat.h
@@ -296,8 +296,6 @@ long compat_sys_sync_file_range2(int fd, unsigned int flags,
296long compat_sys_fallocate(int fd, int mode, 296long compat_sys_fallocate(int fd, int mode,
297 u32 offset_lo, u32 offset_hi, 297 u32 offset_lo, u32 offset_hi,
298 u32 len_lo, u32 len_hi); 298 u32 len_lo, u32 len_hi);
299long compat_sys_sched_rr_get_interval(compat_pid_t pid,
300 struct compat_timespec __user *interval);
301 299
302/* Assembly trampoline to avoid clobbering r0. */ 300/* Assembly trampoline to avoid clobbering r0. */
303long _compat_sys_rt_sigreturn(void); 301long _compat_sys_rt_sigreturn(void);
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h
index b51c6ee3cd6..fe841e7d496 100644
--- a/arch/tile/include/asm/unistd.h
+++ b/arch/tile/include/asm/unistd.h
@@ -14,6 +14,7 @@
14/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */ 14/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
15#ifdef CONFIG_COMPAT 15#ifdef CONFIG_COMPAT
16#define __ARCH_WANT_SYS_LLSEEK 16#define __ARCH_WANT_SYS_LLSEEK
17#define __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
17#endif 18#endif
18#define __ARCH_WANT_SYS_NEWFSTATAT 19#define __ARCH_WANT_SYS_NEWFSTATAT
19#define __ARCH_WANT_SYS_EXECVE 20#define __ARCH_WANT_SYS_EXECVE
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
index 9cd7cb6041c..7f72401b4f4 100644
--- a/arch/tile/kernel/compat.c
+++ b/arch/tile/kernel/compat.c
@@ -76,24 +76,6 @@ long compat_sys_fallocate(int fd, int mode,
76 ((loff_t)len_hi << 32) | len_lo); 76 ((loff_t)len_hi << 32) | len_lo);
77} 77}
78 78
79
80
81long 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/* Provide the compat syscall number to call mapping. */ 79/* Provide the compat syscall number to call mapping. */
98#undef __SYSCALL 80#undef __SYSCALL
99#define __SYSCALL(nr, call) [nr] = (call), 81#define __SYSCALL(nr, call) [nr] = (call),
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 784ebfe63c4..e4920bd58a4 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -588,6 +588,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
588asmlinkage long compat_sys_sendfile(int out_fd, int in_fd, 588asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
589 compat_off_t __user *offset, compat_size_t count); 589 compat_off_t __user *offset, compat_size_t count);
590 590
591asmlinkage long compat_sys_sched_rr_get_interval(compat_pid_t pid,
592 struct compat_timespec __user *interval);
593
591#else 594#else
592 595
593#define is_compat_task() (0) 596#define is_compat_task() (0)
diff --git a/kernel/compat.c b/kernel/compat.c
index c28a306ae05..f6150e92dfc 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -1215,6 +1215,23 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
1215 return 0; 1215 return 0;
1216} 1216}
1217 1217
1218#ifdef __ARCH_WANT_COMPAT_SYS_SCHED_RR_GET_INTERVAL
1219asmlinkage 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 * Allocate user-space memory for the duration of a single system call, 1236 * Allocate user-space memory for the duration of a single system call,
1220 * in order to marshall parameters inside a compat thunk. 1237 * in order to marshall parameters inside a compat thunk.