Commit 6b14e4198c729b748a7f6d22059e6a101d2b241a
Committed by
Al Viro
1 parent
530550651f
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
arch/tile: eliminate pt_regs trampolines for syscalls
Using the new current_pt_regs() model, we can remove some trampolines from assembly code and call directly to the C syscall implementations. rt_sigreturn() and clone() still need some assembly wrapping, but no longer are passed a pt_regs pointer. sigaltstack() and the tilepro-specific cmpxchg_badaddr() syscalls are now just straight C. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Showing 10 changed files with 39 additions and 57 deletions Side-by-side Diff
arch/tile/include/asm/compat.h
... | ... | @@ -280,10 +280,9 @@ |
280 | 280 | size_t sigsetsize); |
281 | 281 | long compat_sys_rt_sigqueueinfo(int pid, int sig, |
282 | 282 | struct compat_siginfo __user *uinfo); |
283 | -long compat_sys_rt_sigreturn(struct pt_regs *); | |
283 | +long compat_sys_rt_sigreturn(void); | |
284 | 284 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
285 | - struct compat_sigaltstack __user *uoss_ptr, | |
286 | - struct pt_regs *); | |
285 | + struct compat_sigaltstack __user *uoss_ptr); | |
287 | 286 | long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high); |
288 | 287 | long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high); |
289 | 288 | long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count, |
... | ... | @@ -300,9 +299,7 @@ |
300 | 299 | long compat_sys_sched_rr_get_interval(compat_pid_t pid, |
301 | 300 | struct compat_timespec __user *interval); |
302 | 301 | |
303 | -/* These are the intvec_64.S trampolines. */ | |
304 | -long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | |
305 | - struct compat_sigaltstack __user *uoss_ptr); | |
302 | +/* Assembly trampoline to avoid clobbering r0. */ | |
306 | 303 | long _compat_sys_rt_sigreturn(void); |
307 | 304 | |
308 | 305 | #endif /* _ASM_TILE_COMPAT_H */ |
arch/tile/include/asm/syscalls.h
... | ... | @@ -51,8 +51,7 @@ |
51 | 51 | |
52 | 52 | #ifndef __tilegx__ |
53 | 53 | /* mm/fault.c */ |
54 | -long sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *); | |
55 | -long _sys_cmpxchg_badaddr(unsigned long address); | |
54 | +long sys_cmpxchg_badaddr(unsigned long address); | |
56 | 55 | #endif |
57 | 56 | |
58 | 57 | #ifdef CONFIG_COMPAT |
59 | 58 | |
60 | 59 | |
... | ... | @@ -63,15 +62,23 @@ |
63 | 62 | long sys_ftruncate64(unsigned int fd, loff_t length); |
64 | 63 | #endif |
65 | 64 | |
66 | -/* These are the intvec*.S trampolines. */ | |
67 | -long _sys_sigaltstack(const stack_t __user *, stack_t __user *); | |
68 | -long _sys_rt_sigreturn(void); | |
69 | -long _sys_clone(unsigned long clone_flags, unsigned long newsp, | |
65 | +/* Provide versions of standard syscalls that use current_pt_regs(). */ | |
66 | +long sys_clone(unsigned long clone_flags, unsigned long newsp, | |
70 | 67 | void __user *parent_tid, void __user *child_tid); |
71 | 68 | long sys_execve(const char __user *filename, |
72 | 69 | const char __user *const __user *argv, |
73 | 70 | const char __user *const __user *envp); |
71 | +long sys_rt_sigreturn(void); | |
72 | +long sys_sigaltstack(const stack_t __user *, stack_t __user *); | |
73 | +#define sys_clone sys_clone | |
74 | 74 | #define sys_execve sys_execve |
75 | +#define sys_rt_sigreturn sys_rt_sigreturn | |
76 | +#define sys_sigaltstack sys_sigaltstack | |
77 | + | |
78 | +/* These are the intvec*.S trampolines. */ | |
79 | +long _sys_rt_sigreturn(void); | |
80 | +long _sys_clone(unsigned long clone_flags, unsigned long newsp, | |
81 | + void __user *parent_tid, void __user *child_tid); | |
75 | 82 | |
76 | 83 | #include <asm-generic/syscalls.h> |
77 | 84 |
arch/tile/kernel/compat.c
... | ... | @@ -102,9 +102,9 @@ |
102 | 102 | #define compat_sys_fadvise64_64 sys32_fadvise64_64 |
103 | 103 | #define compat_sys_readahead sys32_readahead |
104 | 104 | |
105 | -/* Call the trampolines to manage pt_regs where necessary. */ | |
106 | -#define compat_sys_sigaltstack _compat_sys_sigaltstack | |
105 | +/* Call the assembly trampolines where necessary. */ | |
107 | 106 | #define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn |
107 | +#undef sys_clone | |
108 | 108 | #define sys_clone _sys_clone |
109 | 109 | |
110 | 110 | /* |
arch/tile/kernel/compat_signal.c
... | ... | @@ -197,8 +197,7 @@ |
197 | 197 | } |
198 | 198 | |
199 | 199 | long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, |
200 | - struct compat_sigaltstack __user *uoss_ptr, | |
201 | - struct pt_regs *regs) | |
200 | + struct compat_sigaltstack __user *uoss_ptr) | |
202 | 201 | { |
203 | 202 | stack_t uss, uoss; |
204 | 203 | int ret; |
... | ... | @@ -219,7 +218,7 @@ |
219 | 218 | set_fs(KERNEL_DS); |
220 | 219 | ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL, |
221 | 220 | (stack_t __user __force *)&uoss, |
222 | - (unsigned long)compat_ptr(regs->sp)); | |
221 | + (unsigned long)compat_ptr(current_pt_regs()->sp)); | |
223 | 222 | set_fs(seg); |
224 | 223 | if (ret >= 0 && uoss_ptr) { |
225 | 224 | if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) || |
226 | 225 | |
... | ... | @@ -232,8 +231,9 @@ |
232 | 231 | } |
233 | 232 | |
234 | 233 | /* The assembly shim for this function arranges to ignore the return value. */ |
235 | -long compat_sys_rt_sigreturn(struct pt_regs *regs) | |
234 | +long compat_sys_rt_sigreturn(void) | |
236 | 235 | { |
236 | + struct pt_regs *regs = current_pt_regs(); | |
237 | 237 | struct compat_rt_sigframe __user *frame = |
238 | 238 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); |
239 | 239 | sigset_t set; |
... | ... | @@ -248,7 +248,7 @@ |
248 | 248 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
249 | 249 | goto badframe; |
250 | 250 | |
251 | - if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) | |
251 | + if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL) != 0) | |
252 | 252 | goto badframe; |
253 | 253 | |
254 | 254 | return 0; |
arch/tile/kernel/intvec_32.S
... | ... | @@ -1452,15 +1452,6 @@ |
1452 | 1452 | panic "Unhandled interrupt %#x: PC %#lx" |
1453 | 1453 | STD_ENDPROC(bad_intr) |
1454 | 1454 | |
1455 | -/* Put address of pt_regs in reg and jump. */ | |
1456 | -#define PTREGS_SYSCALL(x, reg) \ | |
1457 | - STD_ENTRY(_##x); \ | |
1458 | - { \ | |
1459 | - PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \ | |
1460 | - j x \ | |
1461 | - }; \ | |
1462 | - STD_ENDPROC(_##x) | |
1463 | - | |
1464 | 1455 | /* |
1465 | 1456 | * Special-case sigreturn to not write r0 to the stack on return. |
1466 | 1457 | * This is technically more efficient, but it also avoids difficulties |
1467 | 1458 | |
1468 | 1459 | |
... | ... | @@ -1476,11 +1467,9 @@ |
1476 | 1467 | }; \ |
1477 | 1468 | STD_ENDPROC(_##x) |
1478 | 1469 | |
1479 | -PTREGS_SYSCALL(sys_sigaltstack, r2) | |
1480 | 1470 | PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0) |
1481 | -PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) | |
1482 | 1471 | |
1483 | -/* Save additional callee-saves to pt_regs, put address in r4 and jump. */ | |
1472 | +/* Save additional callee-saves to pt_regs and jump to standard function. */ | |
1484 | 1473 | STD_ENTRY(_sys_clone) |
1485 | 1474 | push_extra_callee_saves r4 |
1486 | 1475 | j sys_clone |
arch/tile/kernel/intvec_64.S
... | ... | @@ -1181,15 +1181,6 @@ |
1181 | 1181 | panic "Unhandled interrupt %#x: PC %#lx" |
1182 | 1182 | STD_ENDPROC(bad_intr) |
1183 | 1183 | |
1184 | -/* Put address of pt_regs in reg and jump. */ | |
1185 | -#define PTREGS_SYSCALL(x, reg) \ | |
1186 | - STD_ENTRY(_##x); \ | |
1187 | - { \ | |
1188 | - PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \ | |
1189 | - j x \ | |
1190 | - }; \ | |
1191 | - STD_ENDPROC(_##x) | |
1192 | - | |
1193 | 1184 | /* |
1194 | 1185 | * Special-case sigreturn to not write r0 to the stack on return. |
1195 | 1186 | * This is technically more efficient, but it also avoids difficulties |
1196 | 1187 | |
1197 | 1188 | |
... | ... | @@ -1205,14 +1196,12 @@ |
1205 | 1196 | }; \ |
1206 | 1197 | STD_ENDPROC(_##x) |
1207 | 1198 | |
1208 | -PTREGS_SYSCALL(sys_sigaltstack, r2) | |
1209 | 1199 | PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0) |
1210 | 1200 | #ifdef CONFIG_COMPAT |
1211 | -PTREGS_SYSCALL(compat_sys_sigaltstack, r2) | |
1212 | 1201 | PTREGS_SYSCALL_SIGRETURN(compat_sys_rt_sigreturn, r0) |
1213 | 1202 | #endif |
1214 | 1203 | |
1215 | -/* Save additional callee-saves to pt_regs, put address in r4 and jump. */ | |
1204 | +/* Save additional callee-saves to pt_regs and jump to standard function. */ | |
1216 | 1205 | STD_ENTRY(_sys_clone) |
1217 | 1206 | push_extra_callee_saves r4 |
1218 | 1207 | j sys_clone |
arch/tile/kernel/process.c
... | ... | @@ -584,10 +584,10 @@ |
584 | 584 | } |
585 | 585 | |
586 | 586 | /* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */ |
587 | -SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | |
588 | - void __user *, parent_tidptr, void __user *, child_tidptr, | |
589 | - struct pt_regs *, regs) | |
587 | +SYSCALL_DEFINE4(clone, unsigned long, clone_flags, unsigned long, newsp, | |
588 | + void __user *, parent_tidptr, void __user *, child_tidptr) | |
590 | 589 | { |
590 | + struct pt_regs *regs = current_pt_regs(); | |
591 | 591 | if (!newsp) |
592 | 592 | newsp = regs->sp; |
593 | 593 | return do_fork(clone_flags, newsp, regs, 0, |
arch/tile/kernel/signal.c
... | ... | @@ -37,10 +37,10 @@ |
37 | 37 | |
38 | 38 | #define DEBUG_SIG 0 |
39 | 39 | |
40 | -SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, | |
41 | - stack_t __user *, uoss, struct pt_regs *, regs) | |
40 | +SYSCALL_DEFINE2(sigaltstack, const stack_t __user *, uss, | |
41 | + stack_t __user *, uoss) | |
42 | 42 | { |
43 | - return do_sigaltstack(uss, uoss, regs->sp); | |
43 | + return do_sigaltstack(uss, uoss, current_pt_regs()->sp); | |
44 | 44 | } |
45 | 45 | |
46 | 46 | |
47 | 47 | |
... | ... | @@ -83,8 +83,9 @@ |
83 | 83 | } |
84 | 84 | |
85 | 85 | /* The assembly shim for this function arranges to ignore the return value. */ |
86 | -SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | |
86 | +SYSCALL_DEFINE0(rt_sigreturn) | |
87 | 87 | { |
88 | + struct pt_regs *regs = current_pt_regs(); | |
88 | 89 | struct rt_sigframe __user *frame = |
89 | 90 | (struct rt_sigframe __user *)(regs->sp); |
90 | 91 | sigset_t set; |
arch/tile/kernel/sys.c
... | ... | @@ -106,13 +106,11 @@ |
106 | 106 | #define sys_readahead sys32_readahead |
107 | 107 | #endif |
108 | 108 | |
109 | -/* Call the trampolines to manage pt_regs where necessary. */ | |
110 | -#define sys_sigaltstack _sys_sigaltstack | |
109 | +/* Call the assembly trampolines where necessary. */ | |
110 | +#undef sys_rt_sigreturn | |
111 | 111 | #define sys_rt_sigreturn _sys_rt_sigreturn |
112 | +#undef sys_clone | |
112 | 113 | #define sys_clone _sys_clone |
113 | -#ifndef __tilegx__ | |
114 | -#define sys_cmpxchg_badaddr _sys_cmpxchg_badaddr | |
115 | -#endif | |
116 | 114 | |
117 | 115 | /* |
118 | 116 | * Note that we can't include <linux/unistd.h> here since the header |
arch/tile/mm/fault.c
... | ... | @@ -70,9 +70,10 @@ |
70 | 70 | * Synthesize the fault a PL0 process would get by doing a word-load of |
71 | 71 | * an unaligned address or a high kernel address. |
72 | 72 | */ |
73 | -SYSCALL_DEFINE2(cmpxchg_badaddr, unsigned long, address, | |
74 | - struct pt_regs *, regs) | |
73 | +SYSCALL_DEFINE1(cmpxchg_badaddr, unsigned long, address) | |
75 | 74 | { |
75 | + struct pt_regs *regs = current_pt_regs(); | |
76 | + | |
76 | 77 | if (address >= PAGE_OFFSET) |
77 | 78 | force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR, |
78 | 79 | address, INT_DTLB_MISS, current, regs); |