powerpc: switch to generic sigaltstack
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 23 Dec 2012 08:26:46 +0000 (03:26 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 3 Feb 2013 23:16:08 +0000 (18:16 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/powerpc/Kconfig
arch/powerpc/include/asm/syscalls.h
arch/powerpc/kernel/ppc32.h
arch/powerpc/kernel/signal.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c

index 17903f1..dd52bab 100644 (file)
@@ -144,6 +144,7 @@ config PPC
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
        select CLONE_BACKWARDS
+       select GENERIC_SIGALTSTACK
 
 config EARLY_PRINTK
        bool
index 6949c42..01d240d 100644 (file)
@@ -22,9 +22,5 @@ asmlinkage long ppc64_personality(unsigned long personality);
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
 asmlinkage time_t sys64_time(time_t __user * tloc);
 
-asmlinkage long sys_sigaltstack(const stack_t __user *uss,
-               stack_t __user *uoss, unsigned long r5, unsigned long r6,
-               unsigned long r7, unsigned long r8, struct pt_regs *regs);
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_POWERPC_SYSCALLS_H */
index 02fb0ee..f6bee3e 100644 (file)
@@ -34,12 +34,6 @@ struct sigaction32 {
        compat_sigset_t sa_mask;                /* A 32 bit mask */
 };
 
-typedef struct sigaltstack_32 {
-       unsigned int ss_sp;
-       int ss_flags;
-       compat_size_t ss_size;
-} stack_32_t;
-
 struct pt_regs32 {
        unsigned int gpr[32];
        unsigned int nip;
@@ -75,7 +69,7 @@ struct mcontext32 {
 struct ucontext32 { 
        unsigned int            uc_flags;
        unsigned int            uc_link;
-       stack_32_t              uc_stack;
+       compat_stack_t          uc_stack;
        int                     uc_pad[7];
        compat_uptr_t           uc_regs;        /* points to uc_mcontext field */
        compat_sigset_t         uc_sigmask;     /* mask last for extensibility */
index 3b99711..fa99dc5 100644 (file)
@@ -169,10 +169,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
                tracehook_notify_resume(regs);
        }
 }
-
-long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
-               unsigned long r5, unsigned long r6, unsigned long r7,
-               unsigned long r8, struct pt_regs *regs)
-{
-       return do_sigaltstack(uss, uoss, regs->gpr[1]);
-}
index 9ec3fed..0ea248c 100644 (file)
@@ -67,6 +67,8 @@
 #define mcontext       mcontext32
 #define ucontext       ucontext32
 
+#define __save_altstack __compat_save_altstack
+
 /*
  * Userspace code may pass a ucontext which doesn't include VSX added
  * at the end.  We need to check for this case.
@@ -763,55 +765,6 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo
        set_fs (old_fs);
        return ret;
 }
-/*
- *  Start Alternate signal stack support
- *
- *  System Calls
- *       sigaltatck               compat_sys_sigaltstack
- */
-
-int compat_sys_sigaltstack(u32 __new, u32 __old, int r5,
-                     int r6, int r7, int r8, struct pt_regs *regs)
-{
-       stack_32_t __user * newstack = compat_ptr(__new);
-       stack_32_t __user * oldstack = compat_ptr(__old);
-       stack_t uss, uoss;
-       int ret;
-       mm_segment_t old_fs;
-       unsigned long sp;
-       compat_uptr_t ss_sp;
-
-       /*
-        * set sp to the user stack on entry to the system call
-        * the system call router sets R9 to the saved registers
-        */
-       sp = regs->gpr[1];
-
-       /* Put new stack info in local 64 bit stack struct */
-       if (newstack) {
-               if (get_user(ss_sp, &newstack->ss_sp) ||
-                   __get_user(uss.ss_flags, &newstack->ss_flags) ||
-                   __get_user(uss.ss_size, &newstack->ss_size))
-                       return -EFAULT;
-               uss.ss_sp = compat_ptr(ss_sp);
-       }
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       /* The __user pointer casts are valid because of the set_fs() */
-       ret = do_sigaltstack(
-               newstack ? (stack_t __user *) &uss : NULL,
-               oldstack ? (stack_t __user *) &uoss : NULL,
-               sp);
-       set_fs(old_fs);
-       /* Copy the stack information to the user output buffer */
-       if (!ret && oldstack  &&
-               (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) ||
-                __put_user(uoss.ss_flags, &oldstack->ss_flags) ||
-                __put_user(uoss.ss_size, &oldstack->ss_size)))
-               return -EFAULT;
-       return ret;
-}
 #endif /* CONFIG_PPC64 */
 
 /*
@@ -838,10 +791,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
        if (copy_siginfo_to_user(&rt_sf->info, info)
            || __put_user(0, &rt_sf->uc.uc_flags)
            || __put_user(0, &rt_sf->uc.uc_link)
-           || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
-           || __put_user(sas_ss_flags(regs->gpr[1]),
-                         &rt_sf->uc.uc_stack.ss_flags)
-           || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
+           || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
            || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
                    &rt_sf->uc.uc_regs)
            || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
@@ -1038,14 +988,11 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8,
         * change it.  -- paulus
         */
 #ifdef CONFIG_PPC64
-       /*
-        * We use the compat_sys_ version that does the 32/64 bits conversion
-        * and takes userland pointer directly. What about error checking ?
-        * nobody does any...
-        */
-       compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs);
+       if (compat_restore_altstack(&rt_sf->uc.uc_stack))
+               goto bad;
 #else
-       do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]);
+       if (restore_altstack(&rt_sf->uc.uc_stack))
+               goto bad;
 #endif
        set_thread_flag(TIF_RESTOREALL);
        return 0;
@@ -1161,7 +1108,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
         * always done it up until now so it is probably better not to
         * change it.  -- paulus
         */
-       do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]);
+       restore_altstack(&ctx->uc_stack);
 
        set_thread_flag(TIF_RESTOREALL);
  out:
index 1ca045d..807b5b1 100644 (file)
@@ -368,10 +368,8 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
        if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
                goto badframe;
 
-       /* do_sigaltstack expects a __user pointer and won't modify
-        * what's in there anyway
-        */
-       do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]);
+       if (restore_altstack(&uc->uc_stack))
+               goto badframe;
 
        set_thread_flag(TIF_RESTOREALL);
        return 0;
@@ -416,10 +414,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
        err |= __put_user(0, &frame->uc.uc_link);
-       err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
-       err |= __put_user(sas_ss_flags(regs->gpr[1]),
-                         &frame->uc.uc_stack.ss_flags);
-       err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+       err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]);
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr, NULL,
                                (unsigned long)ka->sa.sa_handler, 1);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));