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 | |
parent | 0aa0203fb43f04714004b2c4ad33b858e240555d (diff) |
sparc: switch to generic sigaltstack
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/Kconfig | 1 | ||||
-rw-r--r-- | arch/sparc/include/asm/compat_signal.h | 6 | ||||
-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 |
8 files changed, 11 insertions, 84 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 89dde2f0653..3274f5dc8de 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -42,6 +42,7 @@ config SPARC select GENERIC_STRNLEN_USER select MODULES_USE_ELF_RELA select ODD_RT_SIGACTION + select GENERIC_SIGALTSTACK config SPARC32 def_bool !64BIT diff --git a/arch/sparc/include/asm/compat_signal.h b/arch/sparc/include/asm/compat_signal.h index b759eab9b51..9ed1f128b4d 100644 --- a/arch/sparc/include/asm/compat_signal.h +++ b/arch/sparc/include/asm/compat_signal.h @@ -18,12 +18,6 @@ struct __old_sigaction32 { unsigned int sa_flags; unsigned sa_restorer; /* not used by Linux/SPARC yet */ }; - -typedef struct sigaltstack32 { - u32 ss_sp; - int ss_flags; - compat_size_t ss_size; -} stack_t32; #endif #endif /* !(_COMPAT_SIGNAL_H) */ diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 21fd1a8f47d..e2a03004508 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -820,14 +820,6 @@ sys_sparc_pipe: mov %l5, %o7 .align 4 - .globl sys_sigaltstack -sys_sigaltstack: - mov %o7, %l5 - mov %fp, %o2 - call do_sigaltstack - mov %l5, %o7 - - .align 4 .globl sys_sigstack sys_sigstack: mov %o7, %l5 diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 53e48f721ce..9d9eb91d0de 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -61,7 +61,7 @@ struct rt_signal_frame32 { compat_sigset_t mask; /* __siginfo_fpu_t * */ u32 fpu_save; unsigned int insns[2]; - stack_t32 stack; + compat_stack_t stack; unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */ /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */ siginfo_extra_v8plus_t v8plus; @@ -230,13 +230,11 @@ segv: asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) { struct rt_signal_frame32 __user *sf; - unsigned int psr, pc, npc, u_ss_sp; + unsigned int psr, pc, npc; compat_uptr_t fpu_save; compat_uptr_t rwin_save; - mm_segment_t old_fs; sigset_t set; compat_sigset_t seta; - stack_t st; int err, i; /* Always make any pending restarted system calls return -EINTR */ @@ -295,20 +293,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) if (!err && fpu_save) err |= restore_fpu_state(regs, compat_ptr(fpu_save)); err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t)); - err |= __get_user(u_ss_sp, &sf->stack.ss_sp); - st.ss_sp = compat_ptr(u_ss_sp); - err |= __get_user(st.ss_flags, &sf->stack.ss_flags); - err |= __get_user(st.ss_size, &sf->stack.ss_size); + err |= compat_restore_altstack(&sf->stack); if (err) goto segv; - /* It is more difficult to avoid calling this function than to - call it and ignore errors. */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - do_sigaltstack((stack_t __user *) &st, NULL, (unsigned long)sf); - set_fs(old_fs); - err |= __get_user(rwin_save, &sf->rwin_save); if (!err && rwin_save) { 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, err |= copy_siginfo_to_user32(&sf->info, info); /* Setup sigaltstack */ - err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); - err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); + err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]); switch (_NSIG_WORDS) { 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) out: return ret; } - -asmlinkage long do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp) -{ - stack_t uss, uoss; - u32 u_ss_sp = 0; - int ret; - mm_segment_t old_fs; - stack_t32 __user *uss32 = compat_ptr(ussa); - stack_t32 __user *uoss32 = compat_ptr(uossa); - - if (ussa && (get_user(u_ss_sp, &uss32->ss_sp) || - __get_user(uss.ss_flags, &uss32->ss_flags) || - __get_user(uss.ss_size, &uss32->ss_size))) - return -EFAULT; - uss.ss_sp = compat_ptr(u_ss_sp); - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = do_sigaltstack(ussa ? (stack_t __user *) &uss : NULL, - uossa ? (stack_t __user *) &uoss : NULL, sp); - set_fs(old_fs); - if (!ret && uossa && (put_user(ptr_to_compat(uoss.ss_sp), &uoss32->ss_sp) || - __put_user(uoss.ss_flags, &uoss32->ss_flags) || - __put_user(uoss.ss_size, &uoss32->ss_size))) - return -EFAULT; - return ret; -} diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 68f9c8650af..7391fa89651 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) unsigned int psr, pc, npc; __siginfo_fpu_t __user *fpu_save; __siginfo_rwin_t __user *rwin_save; - mm_segment_t old_fs; sigset_t set; - stack_t st; int err; synchronize_user_stack(); @@ -171,8 +169,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) if (!err && fpu_save) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - - err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t)); + err |= restore_altstack(&sf->stack); if (err) goto segv; @@ -180,14 +177,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) regs->pc = pc; regs->npc = npc; - /* It is more difficult to avoid calling this function than to - * call it and ignore errors. - */ - old_fs = get_fs(); - set_fs(KERNEL_DS); - do_sigaltstack((const stack_t __user *) &st, NULL, (unsigned long)sf); - set_fs(old_fs); - err |= __get_user(rwin_save, &sf->rwin_save); if (!err && rwin_save) { if (restore_rwin_state(rwin_save)) @@ -391,9 +380,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t)); /* Setup sigaltstack */ - err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); - err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); + err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); if (!wsaved) { 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 689e1ba6280..176e0e7b8f6 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) err |= restore_fpu_state(regs, fpu_save); err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t)); - if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT) + err |= restore_altstack(&sf->stack); + if (err) goto segv; err |= __get_user(rwin_save, &sf->rwin_save); @@ -403,9 +404,7 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, } /* Setup sigaltstack */ - err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp); - err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags); - err |= __put_user(current->sas_ss_size, &sf->stack.ss_size); + err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]); err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t)); diff --git a/arch/sparc/kernel/syscalls.S b/arch/sparc/kernel/syscalls.S index e0fed7711a9..22a1098961f 100644 --- a/arch/sparc/kernel/syscalls.S +++ b/arch/sparc/kernel/syscalls.S @@ -25,16 +25,10 @@ sys_nis_syscall: sys_memory_ordering: ba,pt %xcc, sparc_memory_ordering add %sp, PTREGS_OFF, %o1 -sys_sigaltstack: - ba,pt %xcc, do_sigaltstack - add %i6, STACK_BIAS, %o2 #ifdef CONFIG_COMPAT sys32_sigstack: ba,pt %xcc, do_sys32_sigstack mov %i6, %o2 -sys32_sigaltstack: - ba,pt %xcc, do_sys32_sigaltstack - mov %i6, %o2 #endif .align 32 #ifdef CONFIG_COMPAT diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index 1009ecb9267..83ec8d46708 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -23,7 +23,7 @@ sys_call_table32: /*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys32_mknod /*15*/ .word sys_chmod, sys_lchown16, sys_brk, sys_nis_syscall, sys32_lseek /*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 -/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys_pause +/*25*/ .word sys32_vmsplice, compat_sys_ptrace, sys_alarm, compat_sys_sigaltstack, sys_pause /*30*/ .word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice .word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile /*40*/ .word compat_sys_newlstat, sys_dup, sys_sparc_pipe, compat_sys_times, sys_getuid |