sparc: switch to generic sigaltstack
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 23 Dec 2012 08:41:17 +0000 (03:41 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 3 Feb 2013 23:16:17 +0000 (18:16 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/sparc/Kconfig
arch/sparc/include/asm/compat_signal.h
arch/sparc/kernel/entry.S
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_32.c
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/syscalls.S
arch/sparc/kernel/systbls_64.S

index 89dde2f0653a5058cf5060bcb5b611422be22cc7..3274f5dc8deb4952bd5e096ec1e8101506e0c666 100644 (file)
@@ -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
index b759eab9b51c1e05ecc414bfbf2a21486fe6e179..9ed1f128b4d1c0f562fb9cd67cc66beef6d17d67 100644 (file)
@@ -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) */
index 21fd1a8f47d2c57c3f403a7a5ab47eeb88d6cf54..e2a030045089f8c06acc55167e332e4ab13a1da5 100644 (file)
@@ -819,14 +819,6 @@ sys_sparc_pipe:
        call    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:
index 53e48f721ce3e0ceb122ac42550178e74886ad0e..9d9eb91d0de1114ea7632db4bb74e54775397c7d 100644 (file)
@@ -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;
-}
index 68f9c8650af47b2731c622cc8ada8768b63d90cb..7391fa89651fe92e38777941d701ae69347bb057 100644 (file)
@@ -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],
index 689e1ba628097e12ab95496d60df2225817483d3..176e0e7b8f606fe3c2d0141ee9a59cc241ecab97 100644 (file)
@@ -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));
 
index e0fed7711a940b6ec991ad11da63d0356556b5cd..22a1098961f54a5f15c9ed87ec7d2c3ff3920e85 100644 (file)
@@ -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
index 1009ecb92678185a388d708e8b28be070669524d..83ec8d4670833241ef5976e591e400e3af820ef5 100644 (file)
@@ -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