diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-12-23 03:41:17 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-02-03 18:16:17 -0500 |
commit | 99b06feb0f7c99f171cb962d0e6a17f81625abd3 (patch) | |
tree | e2d184a61dcf5b0317bfbc204c1e9e4256649b7f /arch/sparc/kernel | |
parent | 0aa0203fb43f04714004b2c4ad33b858e240555d (diff) |
sparc: switch to generic sigaltstack
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/entry.S | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/signal32.c | 48 | ||||
-rw-r--r-- | arch/sparc/kernel/signal_32.c | 17 | ||||
-rw-r--r-- | arch/sparc/kernel/signal_64.c | 7 | ||||
-rw-r--r-- | arch/sparc/kernel/syscalls.S | 6 | ||||
-rw-r--r-- | arch/sparc/kernel/systbls_64.S | 2 |
6 files changed, 10 insertions, 78 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 21fd1a8f47d2..e2a030045089 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -820,14 +820,6 @@ sys_sparc_pipe: | |||
820 | mov %l5, %o7 | 820 | mov %l5, %o7 |
821 | 821 | ||
822 | .align 4 | 822 | .align 4 |
823 | .globl sys_sigaltstack | ||
824 | sys_sigaltstack: | ||
825 | mov %o7, %l5 | ||
826 | mov %fp, %o2 | ||
827 | call do_sigaltstack | ||
828 | mov %l5, %o7 | ||
829 | |||
830 | .align 4 | ||
831 | .globl sys_sigstack | 823 | .globl sys_sigstack |
832 | sys_sigstack: | 824 | sys_sigstack: |
833 | mov %o7, %l5 | 825 | mov %o7, %l5 |
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 53e48f721ce3..9d9eb91d0de1 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -61,7 +61,7 @@ struct rt_signal_frame32 { | |||
61 | compat_sigset_t mask; | 61 | compat_sigset_t mask; |
62 | /* __siginfo_fpu_t * */ u32 fpu_save; | 62 | /* __siginfo_fpu_t * */ u32 fpu_save; |
63 | unsigned int insns[2]; | 63 | unsigned int insns[2]; |
64 | stack_t32 stack; | 64 | compat_stack_t stack; |
65 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ | 65 | unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ |
66 | /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ | 66 | /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ |
67 | siginfo_extra_v8plus_t v8plus; | 67 | siginfo_extra_v8plus_t v8plus; |
@@ -230,13 +230,11 @@ segv: | |||
230 | asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | 230 | asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) |
231 | { | 231 | { |
232 | struct rt_signal_frame32 __user *sf; | 232 | struct rt_signal_frame32 __user *sf; |
233 | unsigned int psr, pc, npc, u_ss_sp; | 233 | unsigned int psr, pc, npc; |
234 | compat_uptr_t fpu_save; | 234 | compat_uptr_t fpu_save; |
235 | compat_uptr_t rwin_save; | 235 | compat_uptr_t rwin_save; |
236 | mm_segment_t old_fs; | ||
237 | sigset_t set; | 236 | sigset_t set; |
238 | compat_sigset_t seta; | 237 | compat_sigset_t seta; |
239 | stack_t st; | ||
240 | int err, i; | 238 | int err, i; |
241 | 239 | ||
242 | /* Always make any pending restarted system calls return -EINTR */ | 240 | /* Always make any pending restarted system calls return -EINTR */ |
@@ -295,20 +293,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) | |||
295 | if (!err && fpu_save) | 293 | if (!err && fpu_save) |
296 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); | 294 | err |= restore_fpu_state(regs, compat_ptr(fpu_save)); |
297 | err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); | 295 | err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); |
298 | err |= __get_user(u_ss_sp, &sf->stack.ss_sp); | 296 | err |= compat_restore_altstack(&sf->stack); |
299 | st.ss_sp = compat_ptr(u_ss_sp); | ||
300 | err |= __get_user(st.ss_flags, &sf->stack.ss_flags); | ||
301 | err |= __get_user(st.ss_size, &sf->stack.ss_size); | ||
302 | if (err) | 297 | if (err) |
303 | goto segv; | 298 | goto segv; |
304 | 299 | ||
305 | /* It is more difficult to avoid calling this function than to | ||
306 | call it and ignore errors. */ | ||
307 | old_fs = get_fs(); | ||
308 | set_fs(KERNEL_DS); | ||
309 | do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); | ||
310 | set_fs(old_fs); | ||
311 | |||
312 | err |= __get_user(rwin_save, &sf->rwin_save); | 300 | err |= __get_user(rwin_save, &sf->rwin_save); |
313 | if (!err && rwin_save) { | 301 | if (!err && rwin_save) { |
314 | if (restore_rwin_state(compat_ptr(rwin_save))) | 302 | if (restore_rwin_state(compat_ptr(rwin_save))) |
@@ -642,9 +630,7 @@ static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
642 | err |= copy_siginfo_to_user32(&sf->info, info); | 630 | err |= copy_siginfo_to_user32(&sf->info, info); |
643 | 631 | ||
644 | /* Setup sigaltstack */ | 632 | /* Setup sigaltstack */ |
645 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 633 | err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]); |
646 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | ||
647 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | ||
648 | 634 | ||
649 | switch (_NSIG_WORDS) { | 635 | switch (_NSIG_WORDS) { |
650 | case 4: seta.sig[7] = (oldset->sig[3] >> 32); | 636 | case 4: seta.sig[7] = (oldset->sig[3] >> 32); |
@@ -856,29 +842,3 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp) | |||
856 | out: | 842 | out: |
857 | return ret; | 843 | return ret; |
858 | } | 844 | } |
859 | |||
860 | asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) | ||
861 | { | ||
862 | stack_t uss, uoss; | ||
863 | u32 u_ss_sp = 0; | ||
864 | int ret; | ||
865 | mm_segment_t old_fs; | ||
866 | stack_t32 __user *uss32 = compat_ptr(ussa); | ||
867 | stack_t32 __user *uoss32 = compat_ptr(uossa); | ||
868 | |||
869 | if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) || | ||
870 | __get_user(uss.ss_flags, &uss32->ss_flags) || | ||
871 | __get_user(uss.ss_size, &uss32->ss_size))) | ||
872 | return -EFAULT; | ||
873 | uss.ss_sp = compat_ptr(u_ss_sp); | ||
874 | old_fs = get_fs(); | ||
875 | set_fs(KERNEL_DS); | ||
876 | ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL, | ||
877 | uossa ? (stack_t __user *) &uoss : NULL, sp); | ||
878 | set_fs(old_fs); | ||
879 | if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) || | ||
880 | __put_user(uoss.ss_flags, &uoss32->ss_flags) || | ||
881 | __put_user(uoss.ss_size, &uoss32->ss_size))) | ||
882 | return -EFAULT; | ||
883 | return ret; | ||
884 | } | ||
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 68f9c8650af4..7391fa89651f 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
@@ -141,9 +141,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
141 | unsigned int psr, pc, npc; | 141 | unsigned int psr, pc, npc; |
142 | __siginfo_fpu_t __user *fpu_save; | 142 | __siginfo_fpu_t __user *fpu_save; |
143 | __siginfo_rwin_t __user *rwin_save; | 143 | __siginfo_rwin_t __user *rwin_save; |
144 | mm_segment_t old_fs; | ||
145 | sigset_t set; | 144 | sigset_t set; |
146 | stack_t st; | ||
147 | int err; | 145 | int err; |
148 | 146 | ||
149 | synchronize_user_stack(); | 147 | synchronize_user_stack(); |
@@ -171,8 +169,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
171 | if (!err && fpu_save) | 169 | if (!err && fpu_save) |
172 | err |= restore_fpu_state(regs, fpu_save); | 170 | err |= restore_fpu_state(regs, fpu_save); |
173 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); | 171 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
174 | 172 | err |= restore_altstack(&sf->stack); | |
175 | err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t)); | ||
176 | 173 | ||
177 | if (err) | 174 | if (err) |
178 | goto segv; | 175 | goto segv; |
@@ -180,14 +177,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) | |||
180 | regs->pc = pc; | 177 | regs->pc = pc; |
181 | regs->npc = npc; | 178 | regs->npc = npc; |
182 | 179 | ||
183 | /* It is more difficult to avoid calling this function than to | ||
184 | * call it and ignore errors. | ||
185 | */ | ||
186 | old_fs = get_fs(); | ||
187 | set_fs(KERNEL_DS); | ||
188 | do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf); | ||
189 | set_fs(old_fs); | ||
190 | |||
191 | err |= __get_user(rwin_save, &sf->rwin_save); | 180 | err |= __get_user(rwin_save, &sf->rwin_save); |
192 | if (!err && rwin_save) { | 181 | if (!err && rwin_save) { |
193 | if (restore_rwin_state(rwin_save)) | 182 | if (restore_rwin_state(rwin_save)) |
@@ -391,9 +380,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
391 | err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); | 380 | err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); |
392 | 381 | ||
393 | /* Setup sigaltstack */ | 382 | /* Setup sigaltstack */ |
394 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 383 | err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); |
395 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | ||
396 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | ||
397 | 384 | ||
398 | if (!wsaved) { | 385 | if (!wsaved) { |
399 | err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], | 386 | err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP], |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 689e1ba62809..176e0e7b8f60 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -295,7 +295,8 @@ void do_rt_sigreturn(struct pt_regs *regs) | |||
295 | err |= restore_fpu_state(regs, fpu_save); | 295 | err |= restore_fpu_state(regs, fpu_save); |
296 | 296 | ||
297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); | 297 | err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); |
298 | if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) | 298 | err |= restore_altstack(&sf->stack); |
299 | if (err) | ||
299 | goto segv; | 300 | goto segv; |
300 | 301 | ||
301 | err |= __get_user(rwin_save, &sf->rwin_save); | 302 | err |= __get_user(rwin_save, &sf->rwin_save); |
@@ -403,9 +404,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
403 | } | 404 | } |
404 | 405 | ||
405 | /* Setup sigaltstack */ | 406 | /* Setup sigaltstack */ |
406 | err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); | 407 | err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); |
407 | err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); | ||
408 | err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); | ||
409 | 408 | ||
410 | err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); | 409 | err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); |
411 | 410 | ||
diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index e0fed7711a94..22a1098961f5 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S | |||
@@ -25,16 +25,10 @@ sys_nis_syscall: | |||
25 | sys_memory_ordering: | 25 | sys_memory_ordering: |
26 | ba,pt %xcc, sparc_memory_ordering | 26 | ba,pt %xcc, sparc_memory_ordering |
27 | add %sp, PTREGS_OFF, %o1 | 27 | add %sp, PTREGS_OFF, %o1 |
28 | sys_sigaltstack: | ||
29 | ba,pt %xcc, do_sigaltstack | ||
30 | add %i6, STACK_BIAS, %o2 | ||
31 | #ifdef CONFIG_COMPAT | 28 | #ifdef CONFIG_COMPAT |
32 | sys32_sigstack: | 29 | sys32_sigstack: |
33 | ba,pt %xcc, do_sys32_sigstack | 30 | ba,pt %xcc, do_sys32_sigstack |
34 | mov %i6, %o2 | 31 | mov %i6, %o2 |
35 | sys32_sigaltstack: | ||
36 | ba,pt %xcc, do_sys32_sigaltstack | ||
37 | mov %i6, %o2 | ||
38 | #endif | 32 | #endif |
39 | .align 32 | 33 | .align 32 |
40 | #ifdef CONFIG_COMPAT | 34 | #ifdef CONFIG_COMPAT |
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 1009ecb92678..83ec8d467083 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S | |||
@@ -23,7 +23,7 @@ sys_call_table32: | |||
23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod | 23 | /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod |
24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek | 24 | /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek |
25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 | 25 | /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 |
26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause | 26 | /*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause |
27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice | 27 | /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice |
28 | .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile | 28 | .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile |
29 | /*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid | 29 | /*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid |