Merge branch 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 9 Aug 2014 16:58:12 +0000 (09:58 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 9 Aug 2014 16:58:12 +0000 (09:58 -0700)
Pull arch signal handling cleanup from Richard Weinberger:
 "This patch series moves all remaining archs to the get_signal(),
  signal_setup_done() and sigsp() functions.

  Currently these archs use open coded variants of the said functions.
  Further, unused parameters get removed from get_signal_to_deliver(),
  tracehook_signal_handler() and signal_delivered().

  At the end of the day we save around 500 lines of code."

* 'signal-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc: (43 commits)
  powerpc: Use sigsp()
  openrisc: Use sigsp()
  mn10300: Use sigsp()
  mips: Use sigsp()
  microblaze: Use sigsp()
  metag: Use sigsp()
  m68k: Use sigsp()
  m32r: Use sigsp()
  hexagon: Use sigsp()
  frv: Use sigsp()
  cris: Use sigsp()
  c6x: Use sigsp()
  blackfin: Use sigsp()
  avr32: Use sigsp()
  arm64: Use sigsp()
  arc: Use sigsp()
  sas_ss_flags: Remove nested ternary if
  Rip out get_signal_to_deliver()
  Clean up signal_delivered()
  tracehook_signal_handler: Remove sig, info, ka and regs
  ...

46 files changed:
arch/arc/kernel/signal.c
arch/arm64/include/asm/signal32.h
arch/arm64/kernel/signal.c
arch/arm64/kernel/signal32.c
arch/avr32/kernel/signal.c
arch/blackfin/kernel/signal.c
arch/c6x/kernel/signal.c
arch/cris/arch-v10/kernel/signal.c
arch/cris/arch-v32/kernel/signal.c
arch/frv/kernel/signal.c
arch/hexagon/kernel/signal.c
arch/ia64/kernel/signal.c
arch/m32r/kernel/signal.c
arch/m68k/kernel/signal.c
arch/metag/kernel/signal.c
arch/microblaze/kernel/signal.c
arch/mips/include/asm/abi.h
arch/mips/kernel/signal-common.h
arch/mips/kernel/signal.c
arch/mips/kernel/signal32.c
arch/mips/kernel/signal_n32.c
arch/mn10300/kernel/signal.c
arch/openrisc/kernel/signal.c
arch/parisc/kernel/signal.c
arch/powerpc/kernel/signal.c
arch/powerpc/kernel/signal.h
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/entry.h
arch/s390/kernel/signal.c
arch/score/kernel/signal.c
arch/sh/kernel/signal_32.c
arch/sh/kernel/signal_64.c
arch/tile/include/asm/compat.h
arch/tile/kernel/compat_signal.c
arch/tile/kernel/signal.c
arch/um/include/shared/frame_kern.h
arch/um/kernel/signal.c
arch/unicore32/kernel/signal.c
arch/x86/um/signal.c
arch/xtensa/kernel/signal.c
include/linux/sched.h
include/linux/signal.h
include/linux/tracehook.h
kernel/signal.c

index 7e95e1a86510fee2f2e1511f8bc7b63f8fb48122..cb3142a2d40b2bd3c85a6c86741debab6a1cf334 100644 (file)
@@ -141,17 +141,13 @@ badframe:
 /*
  * Determine which stack to use..
  */
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
                                        struct pt_regs *regs,
                                        unsigned long framesize)
 {
-       unsigned long sp = regs->sp;
+       unsigned long sp = sigsp(regs->sp, ksig);
        void __user *frame;
 
-       /* This is the X/Open sanctioned signal stack switching */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
-               sp = current->sas_ss_sp + current->sas_ss_size;
-
        /* No matter what happens, 'sp' must be word
         * aligned otherwise nasty things could happen
         */
@@ -179,14 +175,13 @@ static inline int map_sig(int sig)
 }
 
 static int
-setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
-              sigset_t *set, struct pt_regs *regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *sf;
        unsigned int magic = 0;
        int err = 0;
 
-       sf = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+       sf = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
        if (!sf)
                return 1;
 
@@ -205,8 +200,8 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
         *  #2: struct siginfo
         *  #3: struct ucontext (completely populated)
         */
-       if (unlikely(ka->sa.sa_flags & SA_SIGINFO)) {
-               err |= copy_siginfo_to_user(&sf->info, info);
+       if (unlikely(ksig->ka.sa.sa_flags & SA_SIGINFO)) {
+               err |= copy_siginfo_to_user(&sf->info, &ksig->info);
                err |= __put_user(0, &sf->uc.uc_flags);
                err |= __put_user(NULL, &sf->uc.uc_link);
                err |= __save_altstack(&sf->uc.uc_stack, regs->sp);
@@ -227,16 +222,16 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info,
                return err;
 
        /* #1 arg to the user Signal handler */
-       regs->r0 = map_sig(signo);
+       regs->r0 = map_sig(ksig->sig);
 
        /* setup PC of user space signal handler */
-       regs->ret = (unsigned long)ka->sa.sa_handler;
+       regs->ret = (unsigned long)ksig->ka.sa.sa_handler;
 
        /*
         * handler returns using sigreturn stub provided already by userpsace
         */
-       BUG_ON(!(ka->sa.sa_flags & SA_RESTORER));
-       regs->blink = (unsigned long)ka->sa.sa_restorer;
+       BUG_ON(!(ksig->ka.sa.sa_flags & SA_RESTORER));
+       regs->blink = (unsigned long)ksig->ka.sa.sa_restorer;
 
        /* User Stack for signal handler will be above the frame just carved */
        regs->sp = (unsigned long)sf;
@@ -298,38 +293,30 @@ static void arc_restart_syscall(struct k_sigaction *ka, struct pt_regs *regs)
  * OK, we're invoking a handler
  */
 static void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
-             struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
 
        /* Set up the stack frame */
-       ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       ret = setup_rt_frame(ksig, oldset, regs);
 
-       if (ret)
-               force_sigsegv(sig, current);
-       else
-               signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 void do_signal(struct pt_regs *regs)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
+       struct ksignal ksig;
        int restart_scall;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
        restart_scall = in_syscall(regs) && syscall_restartable(regs);
 
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                if (restart_scall) {
-                       arc_restart_syscall(&ka, regs);
+                       arc_restart_syscall(&ksig.ka, regs);
                        syscall_wont_restart(regs);     /* No more restarts */
                }
-               handle_signal(signr, &ka, &info, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
index 7c275e3b640f7d15478345c731b739bbe3e1d64c..eeaa97559babffa2fa3e4cf74d084789e59cbf5e 100644 (file)
 
 extern const compat_ulong_t aarch32_sigret_code[6];
 
-int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
+int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
                       struct pt_regs *regs);
-int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs *regs);
+int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs);
 
 void compat_setup_restart_syscall(struct pt_regs *regs);
 #else
 
-static inline int compat_setup_frame(int usid, struct k_sigaction *ka,
+static inline int compat_setup_frame(int usid, struct ksignal *ksig,
                                     sigset_t *set, struct pt_regs *regs)
 {
        return -ENOSYS;
 }
 
-static inline int compat_setup_rt_frame(int usig, struct k_sigaction *ka,
-                                       siginfo_t *info, sigset_t *set,
+static inline int compat_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
                                        struct pt_regs *regs)
 {
        return -ENOSYS;
index 6357b9c6c90e7c72ef20e97c6459113c11cc53cf..6fa792137eda6ad5014dc195b7fc2f98ed01b3bd 100644 (file)
@@ -209,19 +209,13 @@ static int setup_sigframe(struct rt_sigframe __user *sf,
        return err;
 }
 
-static struct rt_sigframe __user *get_sigframe(struct k_sigaction *ka,
+static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig,
                                               struct pt_regs *regs)
 {
        unsigned long sp, sp_top;
        struct rt_sigframe __user *frame;
 
-       sp = sp_top = regs->sp;
-
-       /*
-        * This is the X/Open sanctioned signal stack switching.
-        */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
-               sp = sp_top = current->sas_ss_sp + current->sas_ss_size;
+       sp = sp_top = sigsp(regs->sp, ksig);
 
        sp = (sp - sizeof(struct rt_sigframe)) & ~15;
        frame = (struct rt_sigframe __user *)sp;
@@ -253,13 +247,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
        regs->regs[30] = (unsigned long)sigtramp;
 }
 
-static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs);
+       frame = get_sigframe(ksig, regs);
        if (!frame)
                return 1;
 
@@ -269,9 +263,9 @@ static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
        err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
        err |= setup_sigframe(frame, regs, set);
        if (err == 0) {
-               setup_return(regs, ka, frame, usig);
-               if (ka->sa.sa_flags & SA_SIGINFO) {
-                       err |= copy_siginfo_to_user(&frame->info, info);
+               setup_return(regs, &ksig->ka, frame, usig);
+               if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+                       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
                        regs->regs[1] = (unsigned long)&frame->info;
                        regs->regs[2] = (unsigned long)&frame->uc;
                }
@@ -291,13 +285,12 @@ static void setup_restart_syscall(struct pt_regs *regs)
 /*
  * OK, we're invoking a handler
  */
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
-                         siginfo_t *info, struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        struct thread_info *thread = current_thread_info();
        struct task_struct *tsk = current;
        sigset_t *oldset = sigmask_to_save();
-       int usig = sig;
+       int usig = ksig->sig;
        int ret;
 
        /*
@@ -310,13 +303,12 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
         * Set up the stack frame
         */
        if (is_compat_task()) {
-               if (ka->sa.sa_flags & SA_SIGINFO)
-                       ret = compat_setup_rt_frame(usig, ka, info, oldset,
-                                                   regs);
+               if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+                       ret = compat_setup_rt_frame(usig, ksig, oldset, regs);
                else
-                       ret = compat_setup_frame(usig, ka, oldset, regs);
+                       ret = compat_setup_frame(usig, ksig, oldset, regs);
        } else {
-               ret = setup_rt_frame(usig, ka, info, oldset, regs);
+               ret = setup_rt_frame(usig, ksig, oldset, regs);
        }
 
        /*
@@ -324,18 +316,14 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
         */
        ret |= !valid_user_regs(&regs->user_regs);
 
-       if (ret != 0) {
-               force_sigsegv(sig, tsk);
-               return;
-       }
-
        /*
         * Fast forward the stepping logic so we step into the signal
         * handler.
         */
-       user_fastforward_single_step(tsk);
+       if (!ret)
+               user_fastforward_single_step(tsk);
 
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -350,10 +338,9 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
 static void do_signal(struct pt_regs *regs)
 {
        unsigned long continue_addr = 0, restart_addr = 0;
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr, retval = 0;
+       int retval = 0;
        int syscall = (int)regs->syscallno;
+       struct ksignal ksig;
 
        /*
         * If we were from a system call, check for system call restarting...
@@ -387,8 +374,7 @@ static void do_signal(struct pt_regs *regs)
         * Get the signal to deliver. When running under ptrace, at this point
         * the debugger may change all of our registers.
         */
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /*
                 * Depending on the signal settings, we may need to revert the
                 * decision to restart the system call, but skip this if a
@@ -398,12 +384,12 @@ static void do_signal(struct pt_regs *regs)
                    (retval == -ERESTARTNOHAND ||
                     retval == -ERESTART_RESTARTBLOCK ||
                     (retval == -ERESTARTSYS &&
-                     !(ka.sa.sa_flags & SA_RESTART)))) {
+                     !(ksig.ka.sa.sa_flags & SA_RESTART)))) {
                        regs->regs[0] = -EINTR;
                        regs->pc = continue_addr;
                }
 
-               handle_signal(signr, &ka, &info, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
index c5ee208321c3cf91ccbf81609cbbec00ae4b0663..1b9ad02837cfcafd4ecbc87f3e10aafe504ac0de 100644 (file)
@@ -407,19 +407,13 @@ badframe:
        return 0;
 }
 
-static void __user *compat_get_sigframe(struct k_sigaction *ka,
+static void __user *compat_get_sigframe(struct ksignal *ksig,
                                        struct pt_regs *regs,
                                        int framesize)
 {
-       compat_ulong_t sp = regs->compat_sp;
+       compat_ulong_t sp = sigsp(regs->compat_sp, ksig);
        void __user *frame;
 
-       /*
-        * This is the X/Open sanctioned signal stack switching.
-        */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
-               sp = current->sas_ss_sp + current->sas_ss_size;
-
        /*
         * ATPCS B01 mandates 8-byte alignment
         */
@@ -520,18 +514,18 @@ static int compat_setup_sigframe(struct compat_sigframe __user *sf,
 /*
  * 32-bit signal handling routines called from signal.c
  */
-int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
+int compat_setup_rt_frame(int usig, struct ksignal *ksig,
                          sigset_t *set, struct pt_regs *regs)
 {
        struct compat_rt_sigframe __user *frame;
        int err = 0;
 
-       frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+       frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!frame)
                return 1;
 
-       err |= copy_siginfo_to_user32(&frame->info, info);
+       err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
 
        __put_user_error(0, &frame->sig.uc.uc_flags, err);
        __put_user_error(0, &frame->sig.uc.uc_link, err);
@@ -541,7 +535,7 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
        err |= compat_setup_sigframe(&frame->sig, regs, set);
 
        if (err == 0) {
-               compat_setup_return(regs, ka, frame->sig.retcode, frame, usig);
+               compat_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
                regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
                regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
        }
@@ -549,13 +543,13 @@ int compat_setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
        return err;
 }
 
-int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
+int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
                       struct pt_regs *regs)
 {
        struct compat_sigframe __user *frame;
        int err = 0;
 
-       frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+       frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!frame)
                return 1;
@@ -564,7 +558,7 @@ int compat_setup_frame(int usig, struct k_sigaction *ka, sigset_t *set,
 
        err |= compat_setup_sigframe(frame, regs, set);
        if (err == 0)
-               compat_setup_return(regs, ka, frame->retcode, frame, usig);
+               compat_setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
 
        return err;
 }
index b80c0b3d2babd316798c036b1e7247b48448ea9d..d309fbcc3bd641b6b5e92f070c4aa786c5577e2e 100644 (file)
@@ -127,24 +127,20 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
 }
 
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
+get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize)
 {
-       unsigned long sp = regs->sp;
-
-       if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
-               sp = current->sas_ss_sp + current->sas_ss_size;
+       unsigned long sp = sigsp(regs->sp, ksig);
 
        return (void __user *)((sp - framesize) & ~3);
 }
 
 static int
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-              sigset_t *set, struct pt_regs *regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
        err = -EFAULT;
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
                goto out;
@@ -164,7 +160,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20),
                         &frame->retcode);
 
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Set up the ucontext */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -176,12 +172,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (err)
                goto out;
 
-       regs->r12 = sig;
+       regs->r12 = ksig->sig;
        regs->r11 = (unsigned long) &frame->info;
        regs->r10 = (unsigned long) &frame->uc;
        regs->sp = (unsigned long) frame;
-       if (ka->sa.sa_flags & SA_RESTORER)
-               regs->lr = (unsigned long)ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
+               regs->lr = (unsigned long)ksig->ka.sa.sa_restorer;
        else {
                printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n",
                       current->comm, current->pid);
@@ -189,10 +185,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n",
-                current->comm, current->pid, sig, regs->sp,
-                regs->pc, ka->sa.sa_handler, regs->lr);
+                current->comm, current->pid, ksig->sig, regs->sp,
+                regs->pc, ksig->ka.sa.sa_handler, regs->lr);
 
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
 out:
        return err;
@@ -208,15 +204,14 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
 }
 
 static inline void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
-             struct pt_regs *regs, int syscall)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall)
 {
        int ret;
 
        /*
         * Set up the stack frame
         */
-       ret = setup_rt_frame(sig, ka, info, sigmask_to_save(), regs);
+       ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
 
        /*
         * Check that the resulting registers are sane
@@ -226,10 +221,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
        /*
         * Block the signal if we were successful.
         */
-       if (ret != 0)
-               force_sigsegv(sig, current);
-       else
-               signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -239,9 +231,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
  */
 static void do_signal(struct pt_regs *regs, int syscall)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which is why we may in
@@ -251,18 +241,18 @@ static void do_signal(struct pt_regs *regs, int syscall)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+       get_signal(&ksig);
        if (syscall) {
                switch (regs->r12) {
                case -ERESTART_RESTARTBLOCK:
                case -ERESTARTNOHAND:
-                       if (signr > 0) {
+                       if (ksig.sig > 0) {
                                regs->r12 = -EINTR;
                                break;
                        }
                        /* fall through */
                case -ERESTARTSYS:
-                       if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) {
+                       if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) {
                                regs->r12 = -EINTR;
                                break;
                        }
@@ -272,13 +262,13 @@ static void do_signal(struct pt_regs *regs, int syscall)
                }
        }
 
-       if (signr == 0) {
+       if (!ksig.sig) {
                /* No signal to deliver -- put the saved sigmask back */
                restore_saved_sigmask();
                return;
        }
 
-       handle_signal(signr, &ka, &info, regs, syscall);
+       handle_signal(&ksig, regs, syscall);
 }
 
 asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
index b022af6c48f85ad91bb69ed66dbaa283cb0b6db7..ef275571d88533da4c1c4fabdc2314fa71b2eea1 100644 (file)
@@ -135,40 +135,31 @@ static inline int rt_setup_sigcontext(struct sigcontext *sc, struct pt_regs *reg
        return err;
 }
 
-static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+static inline void *get_sigframe(struct ksignal *ksig,
                                 size_t frame_size)
 {
-       unsigned long usp;
+       unsigned long usp = sigsp(rdusp(), ksig);
 
-       /* Default to using normal stack.  */
-       usp = rdusp();
-
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (!on_sig_stack(usp))
-                       usp = current->sas_ss_sp + current->sas_ss_size;
-       }
        return (void *)((usp - frame_size) & -8UL);
 }
 
 static int
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
-              sigset_t * set, struct pt_regs *regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        err |= __put_user((current_thread_info()->exec_domain
                           && current_thread_info()->exec_domain->signal_invmap
-                          && sig < 32
+                          && ksig->sig < 32
                           ? current_thread_info()->exec_domain->
-                          signal_invmap[sig] : sig), &frame->sig);
+                          signal_invmap[ksig->sig] : ksig->sig), &frame->sig);
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -183,7 +174,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
        /* Set up registers for signal handler */
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
-                       (struct fdpic_func_descriptor *) ka->sa.sa_handler;
+                       (struct fdpic_func_descriptor *) ksig->ka.sa.sa_handler;
                u32 pc, p3;
                err |= __get_user(pc, &funcptr->text);
                err |= __get_user(p3, &funcptr->GOT);
@@ -192,7 +183,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
                regs->pc = pc;
                regs->p3 = p3;
        } else
-               regs->pc = (unsigned long)ka->sa.sa_handler;
+               regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
        wrusp((unsigned long)frame);
        regs->rets = SIGRETURN_STUB;
 
@@ -237,20 +228,19 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
  * OK, we're invoking a handler
  */
 static void
-handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
-             struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
+       int ret;
+
        /* are we from a system call? to see pt_regs->orig_p0 */
        if (regs->orig_p0 >= 0)
                /* If so, check system call restarting.. */
-               handle_restart(regs, ka, 1);
+               handle_restart(regs, &ksig->ka, 1);
 
        /* set up the stack frame */
-       if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
-               force_sigsegv(sig, current);
-       else 
-               signal_delivered(sig, info, ka, regs,
-                               test_thread_flag(TIF_SINGLESTEP));
+       ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
+
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
@@ -264,16 +254,13 @@ handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
  */
 asmlinkage void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        current->thread.esp0 = (unsigned long)regs;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &info, &ka, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
index 3998b24e26f2d7d3bfef802389c90617a2961b49..fe68226f6c4d6080393e6bf3473fe586cb199a1b 100644 (file)
@@ -127,17 +127,11 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        return err;
 }
 
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
                                        struct pt_regs *regs,
                                        unsigned long framesize)
 {
-       unsigned long sp = regs->sp;
-
-       /*
-        * This is the X/Open sanctioned signal stack switching.
-        */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
-               sp = current->sas_ss_sp + current->sas_ss_size;
+       unsigned long sp = sigsp(regs->sp, ksig);
 
        /*
         * No matter what happens, 'sp' must be dword
@@ -146,21 +140,21 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
        return (void __user *)((sp - framesize) & ~7);
 }
 
-static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        unsigned long __user *retcode;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto segv_and_exit;
+               return -EFAULT;
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Clear all the bits of the ucontext we don't use.  */
        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -188,7 +182,7 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
 #undef COPY
 
        if (err)
-               goto segv_and_exit;
+               return -EFAULT;
 
        flush_icache_range((unsigned long) &frame->retcode,
                           (unsigned long) &frame->retcode + RETCODE_SIZE);
@@ -198,10 +192,10 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
        /* Change user context to branch to signal handler */
        regs->sp = (unsigned long) frame - 8;
        regs->b3 = (unsigned long) retcode;
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
 
        /* Give the signal number to the handler */
-       regs->a4 = signr;
+       regs->a4 = ksig->sig;
 
        /*
         * For realtime signals we must also set the second and third
@@ -212,10 +206,6 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
        regs->a6 = (unsigned long)&frame->uc;
 
        return 0;
-
-segv_and_exit:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
 static inline void
@@ -245,10 +235,11 @@ do_restart:
 /*
  * handle the actual delivery of a signal to userspace
  */
-static void handle_signal(int sig,
-                        siginfo_t *info, struct k_sigaction *ka,
-                        struct pt_regs *regs, int syscall)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
+                         int syscall)
 {
+       int ret;
+
        /* Are we from a system call? */
        if (syscall) {
                /* If so, check system call restarting.. */
@@ -259,7 +250,7 @@ static void handle_signal(int sig,
                        break;
 
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->a4 = -EINTR;
                                break;
                        }
@@ -272,9 +263,8 @@ static void handle_signal(int sig,
        }
 
        /* Set up the stack frame */
-       if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
-               return;
-       signal_delivered(sig, info, ka, regs, 0);
+       ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -282,18 +272,15 @@ static void handle_signal(int sig,
  */
 static void do_signal(struct pt_regs *regs, int syscall)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
+       struct ksignal ksig;
 
        /* we want the common case to go fast, which is why we may in certain
         * cases get here from kernel mode */
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
-               handle_signal(signr, &info, &ka, regs, syscall);
+       if (get_signal(&ksig)) {
+               handle_signal(&ksig, regs, syscall);
                return;
        }
 
index 61ce6273a8952ed6b6986b2dbadf651c0c9c5d47..9b32d338838b75935277165034a8de309412cde6 100644 (file)
@@ -203,15 +203,9 @@ static int setup_sigcontext(struct sigcontext __user *sc,
  * - usually on the stack. */
 
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, size_t frame_size)
 {
-       unsigned long sp = rdusp();
-
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (! on_sig_stack(sp))
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
+       unsigned long sp = sigsp(rdusp(), ksig);
 
        /* make sure the frame is dword-aligned */
 
@@ -228,33 +222,33 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
  * user-mode trampoline.
  */
 
-static int setup_frame(int sig, struct k_sigaction *ka,
-                      sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+                      struct pt_regs *regs)
 {
        struct sigframe __user *frame;
        unsigned long return_ip;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (_NSIG_WORDS > 1) {
                err |= __copy_to_user(frame->extramask, &set->sig[1],
                                      sizeof(frame->extramask));
        }
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               return_ip = (unsigned long)ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
        } else {
                /* trampoline - the desired return ip is the retcode itself */
                return_ip = (unsigned long)&frame->retcode;
@@ -265,42 +259,38 @@ static int setup_frame(int sig, struct k_sigaction *ka,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
 
-       regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
+       regs->irp = (unsigned long) ksig->ka.sa.sa_handler;  /* what we enter NOW   */
        regs->srp = return_ip;                          /* what we enter LATER */
-       regs->r10 = sig;                                /* first argument is signo */
+       regs->r10 = ksig->sig;                                /* first argument is signo */
 
        /* actually move the usp to reflect the stacked frame */
 
        wrusp((unsigned long)frame);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-       sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        unsigned long return_ip;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Clear all the bits of the ucontext we don't use.  */
         err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -312,12 +302,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= __save_altstack(&frame->uc.uc_stack, rdusp());
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               return_ip = (unsigned long)ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
        } else {
                /* trampoline - the desired return ip is the retcode itself */
                return_ip = (unsigned long)&frame->retcode;
@@ -329,18 +319,18 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* TODO what is the current->exec_domain stuff and invmap ? */
 
        /* Set up registers for signal handler */
 
        /* What we enter NOW   */
-       regs->irp = (unsigned long) ka->sa.sa_handler;
+       regs->irp = (unsigned long) ksig->ka.sa.sa_handler;
        /* What we enter LATER */
        regs->srp = return_ip;
        /* First argument is signo */
-       regs->r10 = sig;
+       regs->r10 = ksig->sig;
        /* Second argument is (siginfo_t *) */
        regs->r11 = (unsigned long)&frame->info;
        /* Third argument is unused */
@@ -350,19 +340,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        wrusp((unsigned long)frame);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /*
  * OK, we're invoking a handler
  */
 
-static inline void handle_signal(int canrestart, unsigned long sig,
-       siginfo_t *info, struct k_sigaction *ka,
-       struct pt_regs *regs)
+static inline void handle_signal(int canrestart, struct ksignal *ksig,
+                                struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
@@ -383,7 +368,7 @@ static inline void handle_signal(int canrestart, unsigned long sig,
                        /* ERESTARTSYS means to restart the syscall if
                         * there is no handler or the handler was
                         * registered with SA_RESTART */
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->r10 = -EINTR;
                                break;
                        }
@@ -396,13 +381,12 @@ static inline void handle_signal(int canrestart, unsigned long sig,
        }
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
+               ret = setup_frame(ksig, oldset, regs);
 
-       if (ret == 0)
-               signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -419,9 +403,7 @@ static inline void handle_signal(int canrestart, unsigned long sig,
 
 void do_signal(int canrestart, struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-        struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which
@@ -432,10 +414,9 @@ void do_signal(int canrestart, struct pt_regs *regs)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(canrestart, signr, &info, &ka, regs);
+               handle_signal(canrestart, &ksig, regs);
                return;
        }
 
index 01d1375c9004cdaa89dc867c5b00c303ac618ff5..78ce3b1c9bcb05748f59b1e574e1d41b245fd25b 100644 (file)
@@ -189,17 +189,9 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 
 /* Figure out where to put the new signal frame - usually on the stack. */
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, size_t frame_size)
 {
-       unsigned long sp;
-
-       sp = rdusp();
-
-       /* This is the X/Open sanctioned signal stack switching. */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (!on_sig_stack(sp))
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
+       unsigned long sp = sigsp(rdusp(), ksig);
 
        /* Make sure the frame is dword-aligned. */
        sp &= ~3;
@@ -215,23 +207,22 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
  * trampoline.
   */
 static int
-setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
-           struct pt_regs * regs)
+setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        int err;
        unsigned long return_ip;
        struct signal_frame __user *frame;
 
        err = 0;
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (_NSIG_WORDS > 1) {
                err |= __copy_to_user(frame->extramask, &set->sig[1],
@@ -239,14 +230,14 @@ setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Set up to return from user-space. If provided, use a stub
         * already located in user-space.
         */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               return_ip = (unsigned long)ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               return_ip = (unsigned long)ksig->ka.sa.sa_restorer;
        } else {
                /* Trampoline - the desired return ip is in the signal return page. */
                return_ip = cris_signal_return_page;
@@ -264,7 +255,7 @@ setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Set up registers for signal handler.
@@ -273,42 +264,37 @@ setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
         * Where the code enter later.
         * First argument, signo.
         */
-       regs->erp = (unsigned long) ka->sa.sa_handler;
+       regs->erp = (unsigned long) ksig->ka.sa.sa_handler;
        regs->srp = return_ip;
-       regs->r10 = sig;
+       regs->r10 = ksig->sig;
 
        /* Actually move the USP to reflect the stacked frame. */
        wrusp((unsigned long)frame);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 static int
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-              sigset_t *set, struct pt_regs * regs)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        int err;
        unsigned long return_ip;
        struct rt_signal_frame __user *frame;
 
        err = 0;
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* TODO: what is the current->exec_domain stuff and invmap ? */
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Clear all the bits of the ucontext we don't use.  */
        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
@@ -317,14 +303,14 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= __save_altstack(&frame->uc.uc_stack, rdusp());
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Set up to return from user-space. If provided, use a stub
         * already located in user-space.
         */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               return_ip = (unsigned long) ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               return_ip = (unsigned long) ksig->ka.sa.sa_restorer;
        } else {
                /* Trampoline - the desired return ip is in the signal return page. */
                return_ip = cris_signal_return_page + 6;
@@ -345,7 +331,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Set up registers for signal handler.
@@ -356,9 +342,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
         * Second argument is (siginfo_t *).
         * Third argument is unused.
         */
-       regs->erp = (unsigned long) ka->sa.sa_handler;
+       regs->erp = (unsigned long) ksig->ka.sa.sa_handler;
        regs->srp = return_ip;
-       regs->r10 = sig;
+       regs->r10 = ksig->sig;
        regs->r11 = (unsigned long) &frame->info;
        regs->r12 = 0;
 
@@ -366,17 +352,11 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        wrusp((unsigned long)frame);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /* Invoke a signal handler to, well, handle the signal. */
 static inline void
-handle_signal(int canrestart, unsigned long sig,
-             siginfo_t *info, struct k_sigaction *ka,
-              struct pt_regs * regs)
+handle_signal(int canrestart, struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
@@ -404,7 +384,7 @@ handle_signal(int canrestart, unsigned long sig,
                                  * there is no handler, or the handler
                                  * was registered with SA_RESTART.
                                 */
-                               if (!(ka->sa.sa_flags & SA_RESTART)) {
+                               if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                        regs->r10 = -EINTR;
                                        break;
                                }
@@ -423,13 +403,12 @@ handle_signal(int canrestart, unsigned long sig,
         }
 
        /* Set up the stack frame. */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
+               ret = setup_frame(ksig, oldset, regs);
 
-       if (ret == 0)
-               signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -446,9 +425,7 @@ handle_signal(int canrestart, unsigned long sig,
 void
 do_signal(int canrestart, struct pt_regs *regs)
 {
-       int signr;
-       siginfo_t info;
-        struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * The common case should go fast, which is why this point is
@@ -458,11 +435,9 @@ do_signal(int canrestart, struct pt_regs *regs)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(canrestart, signr, &info, &ka, regs);
+               handle_signal(canrestart, &ksig, regs);
                return;
        }
 
index d822700d4f15dacf49d96c612bc1ea6ac65c3c4b..dc3d59de08704636d44672b4c81e3b8d544292b7 100644 (file)
@@ -158,19 +158,10 @@ static int setup_sigcontext(struct sigcontext __user *sc, unsigned long mask)
 /*
  * Determine which stack to use..
  */
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
                                        size_t frame_size)
 {
-       unsigned long sp;
-
-       /* Default to using normal stack */
-       sp = __frame->sp;
-
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (! sas_ss_flags(sp))
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
+       unsigned long sp = sigsp(__frame->sp, ksig);
 
        return (void __user *) ((sp - frame_size) & ~7UL);
 
@@ -180,17 +171,17 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
 /*
  *
  */
-static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
+static int setup_frame(struct ksignal *ksig, sigset_t *set)
 {
        struct sigframe __user *frame;
-       int rsig;
+       int rsig, sig = ksig->sig;
 
        set_fs(USER_DS);
 
-       frame = get_sigframe(ka, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        rsig = sig;
        if (sig < 32 &&
@@ -199,22 +190,22 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
                rsig = __current_thread_info->exec_domain->signal_invmap[sig];
 
        if (__put_user(rsig, &frame->sig) < 0)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (setup_sigcontext(&frame->sc, set->sig[0]))
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (_NSIG_WORDS > 1) {
                if (__copy_to_user(frame->extramask, &set->sig[1],
                                   sizeof(frame->extramask)))
-                       goto give_sigsegv;
+                       return -EFAULT;
        }
 
        /* Set up to return from userspace.  If provided, use a stub
         * already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               if (__put_user(ka->sa.sa_restorer, &frame->pretcode) < 0)
-                       goto give_sigsegv;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode) < 0)
+                       return -EFAULT;
        }
        else {
                /* Set up the following code on the stack:
@@ -224,7 +215,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
                if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
                    __put_user(0x8efc0000|__NR_sigreturn, &frame->retcode[0]) ||
                    __put_user(0xc0700000, &frame->retcode[1]))
-                       goto give_sigsegv;
+                       return -EFAULT;
 
                flush_icache_range((unsigned long) frame->retcode,
                                   (unsigned long) (frame->retcode + 2));
@@ -233,14 +224,14 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
        /* Set up registers for the signal handler */
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
-                       (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
+                       (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
                struct fdpic_func_descriptor desc;
                if (copy_from_user(&desc, funcptr, sizeof(desc)))
-                       goto give_sigsegv;
+                       return -EFAULT;
                __frame->pc = desc.text;
                __frame->gr15 = desc.GOT;
        } else {
-               __frame->pc   = (unsigned long) ka->sa.sa_handler;
+               __frame->pc   = (unsigned long) ksig->ka.sa.sa_handler;
                __frame->gr15 = 0;
        }
 
@@ -255,29 +246,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set)
 #endif
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
-
 } /* end setup_frame() */
 
 /*****************************************************************************/
 /*
  *
  */
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set)
 {
        struct rt_sigframe __user *frame;
-       int rsig;
+       int rsig, sig = ksig->sig;
 
        set_fs(USER_DS);
 
-       frame = get_sigframe(ka, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        rsig = sig;
        if (sig < 32 &&
@@ -288,28 +273,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (__put_user(rsig,            &frame->sig) ||
            __put_user(&frame->info,    &frame->pinfo) ||
            __put_user(&frame->uc,      &frame->puc))
-               goto give_sigsegv;
+               return -EFAULT;
 
-       if (copy_siginfo_to_user(&frame->info, info))
-               goto give_sigsegv;
+       if (copy_siginfo_to_user(&frame->info, &ksig->info))
+               return -EFAULT;
 
        /* Create the ucontext.  */
        if (__put_user(0, &frame->uc.uc_flags) ||
            __put_user(NULL, &frame->uc.uc_link) ||
            __save_altstack(&frame->uc.uc_stack, __frame->sp))
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (setup_sigcontext(&frame->uc.uc_mcontext, set->sig[0]))
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (__copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
         * already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
-                       goto give_sigsegv;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
+                       return -EFAULT;
        }
        else {
                /* Set up the following code on the stack:
@@ -319,7 +304,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                if (__put_user((__sigrestore_t)frame->retcode, &frame->pretcode) ||
                    __put_user(0x8efc0000|__NR_rt_sigreturn, &frame->retcode[0]) ||
                    __put_user(0xc0700000, &frame->retcode[1]))
-                       goto give_sigsegv;
+                       return -EFAULT;
 
                flush_icache_range((unsigned long) frame->retcode,
                                   (unsigned long) (frame->retcode + 2));
@@ -328,14 +313,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        /* Set up registers for signal handler */
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
-                       (struct fdpic_func_descriptor __user *) ka->sa.sa_handler;
+                       (struct fdpic_func_descriptor __user *) ksig->ka.sa.sa_handler;
                struct fdpic_func_descriptor desc;
                if (copy_from_user(&desc, funcptr, sizeof(desc)))
-                       goto give_sigsegv;
+                       return -EFAULT;
                __frame->pc = desc.text;
                __frame->gr15 = desc.GOT;
        } else {
-               __frame->pc   = (unsigned long) ka->sa.sa_handler;
+               __frame->pc   = (unsigned long) ksig->ka.sa.sa_handler;
                __frame->gr15 = 0;
        }
 
@@ -349,21 +334,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
               sig, current->comm, current->pid, frame, __frame->pc,
               frame->pretcode);
 #endif
-
        return 0;
 
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
-
 } /* end setup_rt_frame() */
 
 /*****************************************************************************/
 /*
  * OK, we're invoking a handler
  */
-static void handle_signal(unsigned long sig, siginfo_t *info,
-                        struct k_sigaction *ka)
+static void handle_signal(struct ksignal *ksig)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
@@ -378,7 +357,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
                        break;
 
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                __frame->gr8 = -EINTR;
                                break;
                        }
@@ -392,16 +371,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
        }
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset);
        else
-               ret = setup_frame(sig, ka, oldset);
-
-       if (ret)
-               return;
+               ret = setup_frame(ksig, oldset);
 
-       signal_delivered(sig, info, ka, __frame,
-                                test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 } /* end handle_signal() */
 
 /*****************************************************************************/
@@ -412,13 +387,10 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
  */
 static void do_signal(void)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
+       struct ksignal ksig;
 
-       signr = get_signal_to_deliver(&info, &ka, __frame, NULL);
-       if (signr > 0) {
-               handle_signal(signr, &info, &ka);
+       if (get_signal(&ksig)) {
+               handle_signal(&ksig);
                return;
        }
 
index d7c73874b5150312196e484bc294b02e14bc7558..eadd70e47e7edd9f52994c9aad79d326ff6f15e6 100644 (file)
@@ -36,18 +36,10 @@ struct rt_sigframe {
        struct ucontext uc;
 };
 
-static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
                          size_t frame_size)
 {
-       unsigned long sp = regs->r29;
-
-       /* check if we would overflow the alt stack */
-       if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
-               return (void __user __force *)-1UL;
-
-       /* Switch to signal stack if appropriate */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
-               sp = current->sas_ss_sp + current->sas_ss_size;
+       unsigned long sp = sigsp(regs->r29, ksig);
 
        return (void __user *)((sp - frame_size) & ~(sizeof(long long) - 1));
 }
@@ -112,20 +104,20 @@ static int restore_sigcontext(struct pt_regs *regs,
 /*
  * Setup signal stack frame with siginfo structure
  */
-static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set,  struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        int err = 0;
        struct rt_sigframe __user *frame;
        struct hexagon_vdso *vdso = current->mm->context.vdso;
 
-       frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe));
+       frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe)))
-               goto    sigsegv;
+               return -EFAULT;
 
-       if (copy_siginfo_to_user(&frame->info, info))
-               goto    sigsegv;
+       if (copy_siginfo_to_user(&frame->info, &ksig->info))
+               return -EFAULT;
 
        /* The on-stack signal trampoline is no longer executed;
         * however, the libgcc signal frame unwinding code checks for
@@ -137,29 +129,26 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs));
        if (err)
-               goto sigsegv;
+               return -EFAULT;
 
        /* Load r0/r1 pair with signumber/siginfo pointer... */
        regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32)
-               | (unsigned long long)signr;
+               | (unsigned long long)ksig->sig;
        regs->r02 = (unsigned long) &frame->uc;
        regs->r31 = (unsigned long) vdso->rt_signal_trampoline;
        pt_psp(regs) = (unsigned long) frame;
-       pt_set_elr(regs, (unsigned long)ka->sa.sa_handler);
+       pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler);
 
        return 0;
-
-sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
 /*
  * Setup invocation of signal handler
  */
-static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
-                        struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
+       int ret;
+
        /*
         * If we're handling a signal that aborted a system call,
         * set up the error return value before adding the signal
@@ -173,7 +162,7 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
                        regs->r00 = -EINTR;
                        break;
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->r00 = -EINTR;
                                break;
                        }
@@ -193,11 +182,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
         * only set up the rt_frame flavor.
         */
        /* If there was an error on setup, no signal was delivered. */
-       if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0)
-               return;
+       ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
 
-       signal_delivered(sig, info, ka, regs,
-                       test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
@@ -205,17 +192,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
  */
 void do_signal(struct pt_regs *regs)
 {
-       struct k_sigaction sigact;
-       siginfo_t info;
-       int signo;
+       struct ksignal ksig;
 
        if (!user_mode(regs))
                return;
 
-       signo = get_signal_to_deliver(&info, &sigact, regs, NULL);
-
-       if (signo > 0) {
-               handle_signal(signo, &info, &sigact, regs);
+       if (get_signal(&ksig)) {
+               handle_signal(&ksig, regs);
                return;
        }
 
index 33cab9a8adffa029e4905a151163580d6b657c18..6d92170be4579cd6b52b8dc2c417bb5f1a9bd040 100644 (file)
@@ -309,12 +309,11 @@ force_sigsegv_info (int sig, void __user *addr)
        si.si_uid = from_kuid_munged(current_user_ns(), current_uid());
        si.si_addr = addr;
        force_sig_info(SIGSEGV, &si, current);
-       return 0;
+       return 1;
 }
 
 static long
-setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
-            struct sigscratch *scr)
+setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr)
 {
        extern char __kernel_sigtramp[];
        unsigned long tramp_addr, new_rbs = 0, new_sp;
@@ -323,7 +322,7 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
 
        new_sp = scr->pt.r12;
        tramp_addr = (unsigned long) __kernel_sigtramp;
-       if (ka->sa.sa_flags & SA_ONSTACK) {
+       if (ksig->ka.sa.sa_flags & SA_ONSTACK) {
                int onstack = sas_ss_flags(new_sp);
 
                if (onstack == 0) {
@@ -347,29 +346,29 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
                         */
                        check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN;
                        if (!likely(on_sig_stack(check_sp)))
-                               return force_sigsegv_info(sig, (void __user *)
+                               return force_sigsegv_info(ksig->sig, (void __user *)
                                                          check_sp);
                }
        }
        frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN);
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               return force_sigsegv_info(sig, frame);
+               return force_sigsegv_info(ksig->sig, frame);
 
-       err  = __put_user(sig, &frame->arg0);
+       err  = __put_user(ksig->sig, &frame->arg0);
        err |= __put_user(&frame->info, &frame->arg1);
        err |= __put_user(&frame->sc, &frame->arg2);
        err |= __put_user(new_rbs, &frame->sc.sc_rbs_base);
        err |= __put_user(0, &frame->sc.sc_loadrs);     /* initialize to zero */
-       err |= __put_user(ka->sa.sa_handler, &frame->handler);
+       err |= __put_user(ksig->ka.sa.sa_handler, &frame->handler);
 
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12);
        err |= setup_sigcontext(&frame->sc, set, scr);
 
        if (unlikely(err))
-               return force_sigsegv_info(sig, frame);
+               return force_sigsegv_info(ksig->sig, frame);
 
        scr->pt.r12 = (unsigned long) frame - 16;       /* new stack pointer */
        scr->pt.ar_fpsr = FPSR_DEFAULT;                 /* reset fpsr for signal handler */
@@ -394,22 +393,20 @@ setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
 
 #if DEBUG_SIG
        printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n",
-              current->comm, current->pid, sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
+              current->comm, current->pid, ksig->sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
 #endif
-       return 1;
+       return 0;
 }
 
 static long
-handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
-              struct sigscratch *scr)
+handle_signal (struct ksignal *ksig, struct sigscratch *scr)
 {
-       if (!setup_frame(sig, ka, info, sigmask_to_save(), scr))
-               return 0;
+       int ret = setup_frame(ksig, sigmask_to_save(), scr);
 
-       signal_delivered(sig, info, ka, &scr->pt,
-                                test_thread_flag(TIF_SINGLESTEP));
+       if (!ret)
+               signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 
-       return 1;
+       return ret;
 }
 
 /*
@@ -419,17 +416,16 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
 void
 ia64_do_signal (struct sigscratch *scr, long in_syscall)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
        long restart = in_syscall;
        long errno = scr->pt.r8;
+       struct ksignal ksig;
 
        /*
         * This only loops in the rare cases of handle_signal() failing, in which case we
         * need to push through a forced SIGSEGV.
         */
        while (1) {
-               int signr = get_signal_to_deliver(&info, &ka, &scr->pt, NULL);
+               get_signal(&ksig);
 
                /*
                 * get_signal_to_deliver() may have run a debugger (via notify_parent())
@@ -446,7 +442,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
                         */
                        restart = 0;
 
-               if (signr <= 0)
+               if (ksig.sig <= 0)
                        break;
 
                if (unlikely(restart)) {
@@ -458,7 +454,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
                                break;
 
                              case ERESTARTSYS:
-                               if ((ka.sa.sa_flags & SA_RESTART) == 0) {
+                               if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) {
                                        scr->pt.r8 = EINTR;
                                        /* note: scr->pt.r10 is already -1 */
                                        break;
@@ -473,7 +469,7 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
                 * Whee!  Actually deliver the signal.  If the delivery failed, we need to
                 * continue to iterate in this loop so we can deliver the SIGSEGV...
                 */
-               if (handle_signal(signr, &ka, &info, scr))
+               if (handle_signal(&ksig, scr))
                        return;
        }
 
index d503568cb75354102dadf3cac8b9407118e438c3..95408b8f130af6264ecf5d949de470a5557ef585 100644 (file)
@@ -162,28 +162,22 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
  * Determine which stack to use..
  */
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
+get_sigframe(struct ksignal *ksig, unsigned long sp, size_t frame_size)
 {
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (sas_ss_flags(sp) == 0)
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
-
-       return (void __user *)((sp - frame_size) & -8ul);
+       return (void __user *)((sigsp(sp, ksig) - frame_size) & -8ul);
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
-       int signal;
+       int signal, sig = ksig->sig;
 
-       frame = get_sigframe(ka, regs->spu, sizeof(*frame));
+       frame = get_sigframe(ksig, regs->spu, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -193,13 +187,13 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        err |= __put_user(signal, &frame->sig);
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -208,17 +202,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  */
-       regs->lr = (unsigned long)ka->sa.sa_restorer;
+       regs->lr = (unsigned long)ksig->ka.sa.sa_restorer;
 
        /* Set up registers for signal handler */
        regs->spu = (unsigned long)frame;
        regs->r0 = signal;      /* Arg for signal handler */
        regs->r1 = (unsigned long)&frame->info;
        regs->r2 = (unsigned long)&frame->uc;
-       regs->bpc = (unsigned long)ka->sa.sa_handler;
+       regs->bpc = (unsigned long)ksig->ka.sa.sa_handler;
 
        set_fs(USER_DS);
 
@@ -228,10 +222,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 #endif
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 static int prev_insn(struct pt_regs *regs)
@@ -252,9 +242,10 @@ static int prev_insn(struct pt_regs *regs)
  */
 
 static void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
-             struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
+       int ret;
+
        /* Are we from a system call? */
        if (regs->syscall_nr >= 0) {
                /* If so, check system call restarting.. */
@@ -265,7 +256,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
                                break;
 
                        case -ERESTARTSYS:
-                               if (!(ka->sa.sa_flags & SA_RESTART)) {
+                               if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                        regs->r0 = -EINTR;
                                        break;
                                }
@@ -278,10 +269,9 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        /* Set up the stack frame */
-       if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs))
-               return;
+       ret = setup_rt_frame(ksig, sigmask_to_save(), regs);
 
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -291,9 +281,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
  */
 static void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which
@@ -304,8 +292,7 @@ static void do_signal(struct pt_regs *regs)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Re-enable any watchpoints before delivering the
                 * signal to user space. The processor register will
                 * have been cleared if the watchpoint triggered
@@ -313,7 +300,7 @@ static void do_signal(struct pt_regs *regs)
                 */
 
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &ka, &info, regs);
+               handle_signal(&ksig, regs);
 
                return;
        }
index 57fd286e4b0b410fe93cb0596c93488afa8b4b4e..967a8b7e152727d24339529e660d85d7eb8348dc 100644 (file)
@@ -835,38 +835,30 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
 }
 
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, size_t frame_size)
 {
-       unsigned long usp;
-
-       /* Default to using normal stack.  */
-       usp = rdusp();
+       unsigned long usp = sigsp(rdusp(), ksig);
 
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (!sas_ss_flags(usp))
-                       usp = current->sas_ss_sp + current->sas_ss_size;
-       }
        return (void __user *)((usp - frame_size) & -8UL);
 }
 
-static int setup_frame (int sig, struct k_sigaction *ka,
-                        sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+                       struct pt_regs *regs)
 {
        struct sigframe __user *frame;
        int fsize = frame_extra_sizes(regs->format);
        struct sigcontext context;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
 
        if (fsize < 0) {
 #ifdef DEBUG
                printk ("setup_frame: Unknown frame format %#x\n",
                        regs->format);
 #endif
-               goto give_sigsegv;
+               return -EFAULT;
        }
 
-       frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
+       frame = get_sigframe(ksig, sizeof(*frame) + fsize);
 
        if (fsize)
                err |= copy_to_user (frame + 1, regs + 1, fsize);
@@ -899,7 +891,7 @@ static int setup_frame (int sig, struct k_sigaction *ka,
 #endif
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        push_cache ((unsigned long) &frame->retcode);
 
@@ -908,7 +900,7 @@ static int setup_frame (int sig, struct k_sigaction *ka,
         * to destroy is successfully copied to sigframe.
         */
        wrusp ((unsigned long) frame);
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
        adjustformat(regs);
 
        /*
@@ -934,28 +926,24 @@ static int setup_frame (int sig, struct k_sigaction *ka,
                tregs->sr = regs->sr;
        }
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return err;
 }
 
-static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
-                           sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                          struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        int fsize = frame_extra_sizes(regs->format);
-       int err = 0;
+       int err = 0, sig = ksig->sig;
 
        if (fsize < 0) {
 #ifdef DEBUG
                printk ("setup_frame: Unknown frame format %#x\n",
                        regs->format);
 #endif
-               goto give_sigsegv;
+               return -EFAULT;
        }
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, sizeof(*frame));
 
        if (fsize)
                err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
@@ -968,7 +956,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
                          &frame->sig);
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -996,7 +984,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
 #endif /* CONFIG_MMU */
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        push_cache ((unsigned long) &frame->retcode);
 
@@ -1005,7 +993,7 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
         * to destroy is successfully copied to sigframe.
         */
        wrusp ((unsigned long) frame);
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
        adjustformat(regs);
 
        /*
@@ -1031,10 +1019,6 @@ static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
                tregs->sr = regs->sr;
        }
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return err;
 }
 
 static inline void
@@ -1074,26 +1058,22 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
  * OK, we're invoking a handler
  */
 static void
-handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
-             struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int err;
        /* are we from a system call? */
        if (regs->orig_d0 >= 0)
                /* If so, check system call restarting.. */
-               handle_restart(regs, ka, 1);
+               handle_restart(regs, &ksig->ka, 1);
 
        /* set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               err = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               err = setup_rt_frame(ksig, oldset, regs);
        else
-               err = setup_frame(sig, ka, oldset, regs);
-
-       if (err)
-               return;
+               err = setup_frame(ksig, oldset, regs);
 
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(err, ksig, 0);
 
        if (test_thread_flag(TIF_DELAYED_TRACE)) {
                regs->sr &= ~0x8000;
@@ -1108,16 +1088,13 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
  */
 static void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       struct k_sigaction ka;
-       int signr;
+       struct ksignal ksig;
 
        current->thread.esp0 = (unsigned long) regs;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &ka, &info, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
index b9e4a82d2bd4414a31ece43450e21966d6c8ce1c..0d100d5c140713de744deea8780094412e8335da 100644 (file)
@@ -140,13 +140,9 @@ static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 /*
  * Determine which stack to use..
  */
-static void __user *get_sigframe(struct k_sigaction *ka, unsigned long sp,
-                                size_t frame_size)
+static void __user *get_sigframe(struct ksignal *ksig, unsigned long sp)
 {
-       /* Meta stacks grows upwards */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
-               sp = current->sas_ss_sp;
-
+       sp = sigsp(sp, ksig);
        sp = (sp + 7) & ~7;                     /* 8byte align stack */
 
        return (void __user *)sp;
@@ -159,7 +155,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
        int err;
        unsigned long code;
 
-       frame = get_sigframe(&ksig->ka, regs->REG_SP, sizeof(*frame));
+       frame = get_sigframe(ksig, regs->REG_SP);
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                return -EFAULT;
 
index 49a07a4d76d0ecb0a88e6a0b07c2664ebdae537b..8955a3829cf059ebabd3d007fada0471d6d109b8 100644 (file)
@@ -145,22 +145,19 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
  * Determine which stack to use..
  */
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size)
 {
        /* Default to using normal stack */
-       unsigned long sp = regs->r1;
-
-       if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && !on_sig_stack(sp))
-               sp = current->sas_ss_sp + current->sas_ss_size;
+       unsigned long sp = sigsp(regs->r1, ksig);
 
        return (void __user *)((sp - frame_size) & -8UL);
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                       sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int signal;
        unsigned long address = 0;
 #ifdef CONFIG_MMU
@@ -168,10 +165,10 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        pte_t *ptep;
 #endif
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -179,8 +176,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                ? current_thread_info()->exec_domain->signal_invmap[sig]
                : sig;
 
-       if (info)
-               err |= copy_siginfo_to_user(&frame->info, info);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Create the ucontext. */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -227,7 +224,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        flush_dcache_range(address, address + 8);
 #endif
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->r1 = (unsigned long) frame;
@@ -237,7 +234,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->r6 = (unsigned long) &frame->info; /* arg 1: siginfo */
        regs->r7 = (unsigned long) &frame->uc; /* arg2: ucontext */
        /* Offset to handle microblaze rtid r14, 0 */
-       regs->pc = (unsigned long)ka->sa.sa_handler;
+       regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
        set_fs(USER_DS);
 
@@ -247,10 +244,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 #endif
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /* Handle restarting system calls */
@@ -283,23 +276,15 @@ do_restart:
  */
 
 static void
-handle_signal(unsigned long sig, struct k_sigaction *ka,
-               siginfo_t *info, struct pt_regs *regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
-       else
-               ret = setup_rt_frame(sig, ka, NULL, oldset, regs);
+       ret = setup_rt_frame(ksig, oldset, regs);
 
-       if (ret)
-               return;
-
-       signal_delivered(sig, info, ka, regs,
-                       test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
@@ -313,21 +298,19 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
  */
 static void do_signal(struct pt_regs *regs, int in_syscall)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
+
 #ifdef DEBUG_SIG
        pr_info("do signal: %p %d\n", regs, in_syscall);
        pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
                        regs->r12, current_thread_info()->flags);
 #endif
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee! Actually deliver the signal. */
                if (in_syscall)
-                       handle_restart(regs, &ka, 1);
-               handle_signal(signr, &ka, &info, regs);
+                       handle_restart(regs, &ksig.ka, 1);
+               handle_signal(&ksig, regs);
                return;
        }
 
index 909bb69848666dafbd0f48e2ca32ada5cf2de60f..7186bb51b89b2adea15bced173787c2513b924af 100644 (file)
 #include <asm/siginfo.h>
 
 struct mips_abi {
-       int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
-                                 struct pt_regs *regs, int signr,
-                                 sigset_t *set);
+       int (* const setup_frame)(void *sig_return, struct ksignal *ksig,
+                                 struct pt_regs *regs, sigset_t *set);
        const unsigned long     signal_return_offset;
-       int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
-                              struct pt_regs *regs, int signr,
-                              sigset_t *set, siginfo_t *info);
+       int (* const setup_rt_frame)(void *sig_return, struct ksignal *ksig,
+                                    struct pt_regs *regs, sigset_t *set);
        const unsigned long     rt_signal_return_offset;
        const unsigned long     restart;
 };
index 9c60d09e62a71521007c3cae0894cdcf09f01424..06805e09bcd35751857a6f4a1d367d6796163c1b 100644 (file)
@@ -22,7 +22,7 @@
 /*
  * Determine which stack to use..
  */
-extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+extern void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
                                 size_t frame_size);
 /* Check and clear pending FPU exceptions in saved CSR */
 extern int fpcsr_pending(unsigned int __user *fpcsr);
index 9e60d117e41e174842935ee13b8b524e4d8f49ec..1d57605e4615288a604403de1a7071d7112b20c0 100644 (file)
@@ -280,7 +280,7 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
        return err;
 }
 
-void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
+void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
                          size_t frame_size)
 {
        unsigned long sp;
@@ -295,9 +295,7 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
         */
        sp -= 32;
 
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
-               sp = current->sas_ss_sp + current->sas_ss_size;
+       sp = sigsp(sp, ksig);
 
        return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 }
@@ -428,20 +426,20 @@ badframe:
 }
 
 #ifdef CONFIG_TRAD_SIGNALS
-static int setup_frame(void *sig_return, struct k_sigaction *ka,
-                      struct pt_regs *regs, int signr, sigset_t *set)
+static int setup_frame(void *sig_return, struct ksignal *ksig,
+                      struct pt_regs *regs, sigset_t *set)
 {
        struct sigframe __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        err |= setup_sigcontext(regs, &frame->sf_sc);
        err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Arguments to signal handler:
@@ -453,37 +451,32 @@ static int setup_frame(void *sig_return, struct k_sigaction *ka,
         * $25 and c0_epc point to the signal handler, $29 points to the
         * struct sigframe.
         */
-       regs->regs[ 4] = signr;
+       regs->regs[ 4] = ksig->sig;
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
        regs->regs[31] = (unsigned long) sig_return;
-       regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+       regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
        return 0;
-
-give_sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 #endif
 
-static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
-                         struct pt_regs *regs, int signr, sigset_t *set,
-                         siginfo_t *info)
+static int setup_rt_frame(void *sig_return, struct ksignal *ksig,
+                         struct pt_regs *regs, sigset_t *set)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Create siginfo.  */
-       err |= copy_siginfo_to_user(&frame->rs_info, info);
+       err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -493,7 +486,7 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
        err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Arguments to signal handler:
@@ -505,22 +498,18 @@ static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
         * $25 and c0_epc point to the signal handler, $29 points to
         * the struct rt_sigframe.
         */
-       regs->regs[ 4] = signr;
+       regs->regs[ 4] = ksig->sig;
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
        regs->regs[31] = (unsigned long) sig_return;
-       regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+       regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
 struct mips_abi mips_abi = {
@@ -534,8 +523,7 @@ struct mips_abi mips_abi = {
        .restart        = __NR_restart_syscall
 };
 
-static void handle_signal(unsigned long sig, siginfo_t *info,
-       struct k_sigaction *ka, struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
@@ -557,7 +545,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
                        regs->regs[2] = EINTR;
                        break;
                case ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->regs[2] = EINTR;
                                break;
                        }
@@ -571,29 +559,23 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
                regs->regs[0] = 0;              /* Don't deal with this again.  */
        }
 
-       if (sig_uses_siginfo(ka))
+       if (sig_uses_siginfo(&ksig->ka))
                ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
-                                         ka, regs, sig, oldset, info);
+                                         ksig, regs, oldset);
        else
-               ret = abi->setup_frame(vdso + abi->signal_return_offset,
-                                      ka, regs, sig, oldset);
-
-       if (ret)
-               return;
+               ret = abi->setup_frame(vdso + abi->signal_return_offset, ksig,
+                                      regs, oldset);
 
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 static void do_signal(struct pt_regs *regs)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
+       struct ksignal ksig;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &info, &ka, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
index bae2e6ee2109f484e079faa21d774a18f0f2f678..d69179c0d49d4f9b6d56d129acc01f6c4c206fd4 100644 (file)
@@ -490,21 +490,21 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
-                         struct pt_regs *regs, int signr, sigset_t *set)
+static int setup_frame_32(void *sig_return, struct ksignal *ksig,
+                         struct pt_regs *regs, sigset_t *set)
 {
        struct sigframe32 __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        err |= setup_sigcontext32(regs, &frame->sf_sc);
        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Arguments to signal handler:
@@ -516,37 +516,32 @@ static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
         * $25 and c0_epc point to the signal handler, $29 points to the
         * struct sigframe.
         */
-       regs->regs[ 4] = signr;
+       regs->regs[ 4] = ksig->sig;
        regs->regs[ 5] = 0;
        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
        regs->regs[29] = (unsigned long) frame;
        regs->regs[31] = (unsigned long) sig_return;
-       regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+       regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
-static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
-                            struct pt_regs *regs, int signr, sigset_t *set,
-                            siginfo_t *info)
+static int setup_rt_frame_32(void *sig_return, struct ksignal *ksig,
+                            struct pt_regs *regs, sigset_t *set)
 {
        struct rt_sigframe32 __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
-       err |= copy_siginfo_to_user32(&frame->rs_info, info);
+       err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -556,7 +551,7 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
        err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Arguments to signal handler:
@@ -568,22 +563,18 @@ static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
         * $25 and c0_epc point to the signal handler, $29 points to
         * the struct rt_sigframe32.
         */
-       regs->regs[ 4] = signr;
+       regs->regs[ 4] = ksig->sig;
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
        regs->regs[31] = (unsigned long) sig_return;
-       regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+       regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
 /*
index b2241bb9cac1c16d69c9a2c4ce8d53749eff3d54..f1d4751eead09875c9746163267d93a57abea416 100644 (file)
@@ -102,18 +102,18 @@ badframe:
        force_sig(SIGSEGV, current);
 }
 
-static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
-       struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame_n32(void *sig_return, struct ksignal *ksig,
+                             struct pt_regs *regs, sigset_t *set)
 {
        struct rt_sigframe_n32 __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Create siginfo.  */
-       err |= copy_siginfo_to_user32(&frame->rs_info, info);
+       err |= copy_siginfo_to_user32(&frame->rs_info, &ksig->info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->rs_uc.uc_flags);
@@ -123,7 +123,7 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
        err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Arguments to signal handler:
@@ -135,22 +135,18 @@ static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
         * $25 and c0_epc point to the signal handler, $29 points to
         * the struct rt_sigframe.
         */
-       regs->regs[ 4] = signr;
+       regs->regs[ 4] = ksig->sig;
        regs->regs[ 5] = (unsigned long) &frame->rs_info;
        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
        regs->regs[29] = (unsigned long) frame;
        regs->regs[31] = (unsigned long) sig_return;
-       regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
+       regs->cp0_epc = regs->regs[25] = (unsigned long) ksig->ka.sa.sa_handler;
 
        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
               current->comm, current->pid,
               frame, regs->cp0_epc, regs->regs[31]);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
 struct mips_abi mips_abi_n32 = {
index 9dfac5cd16e67d537ae91d17c38dca84a820d996..a6c0858592c3be2d8732d0551d6331d70642c9b3 100644 (file)
@@ -186,20 +186,11 @@ static int setup_sigcontext(struct sigcontext __user *sc,
 /*
  * determine which stack to use..
  */
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
                                        struct pt_regs *regs,
                                        size_t frame_size)
 {
-       unsigned long sp;
-
-       /* default to using normal stack */
-       sp = regs->sp;
-
-       /* this is the X/Open sanctioned signal stack switching.  */
-       if (ka->sa.sa_flags & SA_ONSTACK) {
-               if (sas_ss_flags(sp) == 0)
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
+       unsigned long sp = sigsp(regs->sp, ksig);
 
        return (void __user *) ((sp - frame_size) & ~7UL);
 }
@@ -207,16 +198,16 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
 /*
  * set up a normal signal frame
  */
-static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
                       struct pt_regs *regs)
 {
        struct sigframe __user *frame;
-       int rsig;
+       int rsig, sig = ksig->sig;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        rsig = sig;
        if (sig < 32 &&
@@ -226,40 +217,40 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 
        if (__put_user(rsig, &frame->sig) < 0 ||
            __put_user(&frame->sc, &frame->psc) < 0)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (_NSIG_WORDS > 1) {
                if (__copy_to_user(frame->extramask, &set->sig[1],
                                   sizeof(frame->extramask)))
-                       goto give_sigsegv;
+                       return -EFAULT;
        }
 
        /* set up to return from userspace.  If provided, use a stub already in
         * userspace */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
-                       goto give_sigsegv;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
+                       return -EFAULT;
        } else {
                if (__put_user((void (*)(void))frame->retcode,
                               &frame->pretcode))
-                       goto give_sigsegv;
+                       return -EFAULT;
                /* this is mov $,d0; syscall 0 */
                if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
                    __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
                    __put_user(0x00, (char *)(frame->retcode + 2)) ||
                    __put_user(0xf0, (char *)(frame->retcode + 3)) ||
                    __put_user(0xe0, (char *)(frame->retcode + 4)))
-                       goto give_sigsegv;
+                       return -EFAULT;
                flush_icache_range((unsigned long) frame->retcode,
                                   (unsigned long) frame->retcode + 5);
        }
 
        /* set up registers for signal handler */
        regs->sp = (unsigned long) frame;
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
        regs->d0 = sig;
        regs->d1 = (unsigned long) &frame->sc;
 
@@ -270,25 +261,21 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 #endif
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /*
  * set up a realtime signal frame
  */
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
-       int rsig;
+       int rsig, sig = ksig->sig;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        rsig = sig;
        if (sig < 32 &&
@@ -299,8 +286,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (__put_user(rsig, &frame->sig) ||
            __put_user(&frame->info, &frame->pinfo) ||
            __put_user(&frame->uc, &frame->puc) ||
-           copy_siginfo_to_user(&frame->info, info))
-               goto give_sigsegv;
+           copy_siginfo_to_user(&frame->info, &ksig->info))
+               return -EFAULT;
 
        /* create the ucontext.  */
        if (__put_user(0, &frame->uc.uc_flags) ||
@@ -309,13 +296,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
            setup_sigcontext(&frame->uc.uc_mcontext,
                             &frame->fpuctx, regs, set->sig[0]) ||
            __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* set up to return from userspace.  If provided, use a stub already in
         * userspace */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
-                       goto give_sigsegv;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
+                       return -EFAULT;
+
        } else {
                if (__put_user((void(*)(void))frame->retcode,
                               &frame->pretcode) ||
@@ -326,7 +314,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                    __put_user(0x00, (char *)(frame->retcode + 2)) ||
                    __put_user(0xf0, (char *)(frame->retcode + 3)) ||
                    __put_user(0xe0, (char *)(frame->retcode + 4)))
-                       goto give_sigsegv;
+                       return -EFAULT;
 
                flush_icache_range((u_long) frame->retcode,
                                   (u_long) frame->retcode + 5);
@@ -334,7 +322,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up registers for signal handler */
        regs->sp = (unsigned long) frame;
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
        regs->d0 = sig;
        regs->d1 = (long) &frame->info;
 
@@ -345,10 +333,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 #endif
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 static inline void stepback(struct pt_regs *regs)
@@ -360,9 +344,7 @@ static inline void stepback(struct pt_regs *regs)
 /*
  * handle the actual delivery of a signal to userspace
  */
-static int handle_signal(int sig,
-                        siginfo_t *info, struct k_sigaction *ka,
-                        struct pt_regs *regs)
+static int handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
@@ -377,7 +359,7 @@ static int handle_signal(int sig,
                        break;
 
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->d0 = -EINTR;
                                break;
                        }
@@ -390,15 +372,12 @@ static int handle_signal(int sig,
        }
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
-       if (ret)
-               return ret;
+               ret = setup_frame(ksig, oldset, regs);
 
-       signal_delivered(sig, info, ka, regs,
-                        test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
        return 0;
 }
 
@@ -407,15 +386,10 @@ static int handle_signal(int sig,
  */
 static void do_signal(struct pt_regs *regs)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
-
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
-               if (handle_signal(signr, &info, &ka, regs) == 0) {
-               }
+       struct ksignal ksig;
 
+       if (get_signal(&ksig)) {
+               handle_signal(&ksig, regs);
                return;
        }
 
index 66775bc07a8eeb780e65a290247b3156f0a44ccd..7d1b8235bf90a9b2172654325e2bee576d3a4163 100644 (file)
@@ -132,30 +132,16 @@ static inline unsigned long align_sigframe(unsigned long sp)
  * or the alternate stack.
  */
 
-static inline void __user *get_sigframe(struct k_sigaction *ka,
+static inline void __user *get_sigframe(struct ksignal *ksig,
                                        struct pt_regs *regs, size_t frame_size)
 {
        unsigned long sp = regs->sp;
-       int onsigstack = on_sig_stack(sp);
 
        /* redzone */
        sp -= STACK_FRAME_OVERHEAD;
-
-       /* This is the X/Open sanctioned signal stack switching.  */
-       if ((ka->sa.sa_flags & SA_ONSTACK) && !onsigstack) {
-               if (current->sas_ss_size)
-                       sp = current->sas_ss_sp + current->sas_ss_size;
-       }
-
+       sp = sigsp(sp, ksig);
        sp = align_sigframe(sp - frame_size);
 
-       /*
-        * If we are on the alternate signal stack and would overflow it, don't.
-        * Return an always-bogus address instead so we will die with SIGSEGV.
-        */
-       if (onsigstack && !likely(on_sig_stack(sp)))
-               return (void __user *)-1L;
-
        return (void __user *)sp;
 }
 
@@ -173,7 +159,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
        unsigned long return_ip;
        int err = 0;
 
-       frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
+       frame = get_sigframe(ksig, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                return -EFAULT;
index 1cba8f29bb492326b156423f8dd12805221dbfc5..012d4fa63d9763550930a4abbd4b890f9b1e2216 100644 (file)
@@ -227,8 +227,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_sysc
 }
 
 static long
-setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-              sigset_t *set, struct pt_regs *regs, int in_syscall)
+setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
+              int in_syscall)
 {
        struct rt_sigframe __user *frame;
        unsigned long rp, usp;
@@ -241,10 +241,10 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        
        usp = (regs->gr[30] & ~(0x01UL));
        /*FIXME: frame_size parameter is unused, remove it. */
-       frame = get_sigframe(ka, usp, sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
 
        DBG(1,"SETUP_RT_FRAME: START\n");
-       DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
+       DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
 
        
 #ifdef CONFIG_64BIT
@@ -253,7 +253,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        
        if (is_compat_task()) {
                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
-               err |= copy_siginfo_to_user32(&compat_frame->info, info);
+               err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
                err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
@@ -265,7 +265,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 #endif
        {       
                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
-               err |= copy_siginfo_to_user(&frame->info, info);
+               err |= copy_siginfo_to_user(&frame->info, &ksig->info);
                err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
@@ -275,7 +275,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
        
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace. The first words of tramp are used to
@@ -312,9 +312,9 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
-       haddr = A(ka->sa.sa_handler);
+       haddr = A(ksig->ka.sa.sa_handler);
        /* The sa_handler may be a pointer to a function descriptor */
 #ifdef CONFIG_64BIT
        if (is_compat_task()) {
@@ -326,7 +326,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                        err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 
                        if (err)
-                               goto give_sigsegv;
+                               return -EFAULT;
 
                        haddr = fdesc.addr;
                        regs->gr[19] = fdesc.gp;
@@ -339,7 +339,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
                
                if (err)
-                       goto give_sigsegv;
+                       return -EFAULT;
                
                haddr = fdesc.addr;
                regs->gr[19] = fdesc.gp;
@@ -386,7 +386,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        regs->gr[2]  = rp;                /* userland return pointer */
-       regs->gr[26] = sig;               /* signal number */
+       regs->gr[26] = ksig->sig;               /* signal number */
        
 #ifdef CONFIG_64BIT
        if (is_compat_task()) {
@@ -410,11 +410,6 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
               current->comm, current->pid, frame, regs->gr[30],
               regs->iaoq[0], regs->iaoq[1], rp);
 
-       return 1;
-
-give_sigsegv:
-       DBG(1,"setup_rt_frame: sending SIGSEGV\n");
-       force_sigsegv(sig, current);
        return 0;
 }
 
@@ -423,20 +418,19 @@ give_sigsegv:
  */    
 
 static void
-handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
-               struct pt_regs *regs, int in_syscall)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
 {
+       int ret;
        sigset_t *oldset = sigmask_to_save();
+
        DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
-              sig, ka, info, oldset, regs);
+              ksig->sig, ksig->ka, ksig->info, oldset, regs);
        
        /* Set up the stack frame */
-       if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
-               return;
+       ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
 
-       signal_delivered(sig, info, ka, regs, 
-               test_thread_flag(TIF_SINGLESTEP) ||
-               test_thread_flag(TIF_BLOCKSTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
+                         test_thread_flag(TIF_BLOCKSTEP));
 
        DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
                regs->gr[28]);
@@ -544,22 +538,18 @@ insert_restart_trampoline(struct pt_regs *regs)
 asmlinkage void
 do_signal(struct pt_regs *regs, long in_syscall)
 {
-       siginfo_t info;
-       struct k_sigaction ka;
-       int signr;
+       struct ksignal ksig;
 
        DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
               regs, regs->sr[7], in_syscall);
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
-       
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
+               DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
                /* Restart a system call if necessary. */
                if (in_syscall)
-                       syscall_restart(regs, &ka);
+                       syscall_restart(regs, &ksig.ka);
 
-               handle_signal(signr, &info, &ka, regs, in_syscall);
+               handle_signal(&ksig, regs, in_syscall);
                return;
        }
 
index 1c794cef2883ea314b205c8f0aa01a89b54e806a..cf8c7e4e0b21bb519f0098bd5a72622233dcd358 100644 (file)
@@ -31,20 +31,14 @@ int show_unhandled_signals = 1;
 /*
  * Allocate space for the signal frame
  */
-void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
+void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
                           size_t frame_size, int is_32)
 {
         unsigned long oldsp, newsp;
 
         /* Default to using normal stack */
         oldsp = get_clean_sp(sp, is_32);
-
-       /* Check for alt stack */
-       if ((ka->sa.sa_flags & SA_ONSTACK) &&
-           current->sas_ss_size && !on_sig_stack(oldsp))
-               oldsp = (current->sas_ss_sp + current->sas_ss_size);
-
-       /* Get aligned frame */
+       oldsp = sigsp(oldsp, ksig);
        newsp = (oldsp - frame_size) & ~0xFUL;
 
        /* Check access */
@@ -105,25 +99,23 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
        }
 }
 
-static int do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
        int ret;
        int is32 = is_32bit_task();
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+       get_signal(&ksig);
 
        /* Is there any syscall restart business here ? */
-       check_syscall_restart(regs, &ka, signr > 0);
+       check_syscall_restart(regs, &ksig.ka, ksig.sig > 0);
 
-       if (signr <= 0) {
+       if (ksig.sig <= 0) {
                /* No signal to deliver -- put the saved sigmask back */
                restore_saved_sigmask();
                regs->trap = 0;
-               return 0;               /* no signals delivered */
+               return;               /* no signals delivered */
        }
 
 #ifndef CONFIG_PPC_ADV_DEBUG_REGS
@@ -140,23 +132,16 @@ static int do_signal(struct pt_regs *regs)
        thread_change_pc(current, regs);
 
        if (is32) {
-               if (ka.sa.sa_flags & SA_SIGINFO)
-                       ret = handle_rt_signal32(signr, &ka, &info, oldset,
-                                       regs);
+               if (ksig.ka.sa.sa_flags & SA_SIGINFO)
+                       ret = handle_rt_signal32(&ksig, oldset, regs);
                else
-                       ret = handle_signal32(signr, &ka, &info, oldset,
-                                       regs);
+                       ret = handle_signal32(&ksig, oldset, regs);
        } else {
-               ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
+               ret = handle_rt_signal64(&ksig, oldset, regs);
        }
 
        regs->trap = 0;
-       if (ret) {
-               signal_delivered(signr, &info, &ka, regs,
-                                        test_thread_flag(TIF_SINGLESTEP));
-       }
-
-       return ret;
+       signal_setup_done(ret, &ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
index c69b9aeb9f236646c06ef3f2cfc320ecc00cdcd9..51b274199dd9f318c4adf6e6a2a122acb6caa054 100644 (file)
 
 extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags);
 
-extern void __user * get_sigframe(struct k_sigaction *ka, unsigned long sp,
+extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
                                  size_t frame_size, int is_32);
 
-extern int handle_signal32(unsigned long sig, struct k_sigaction *ka,
-                          siginfo_t *info, sigset_t *oldset,
+extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
                           struct pt_regs *regs);
 
-extern int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
-                             siginfo_t *info, sigset_t *oldset,
+extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
                              struct pt_regs *regs);
 
 extern unsigned long copy_fpr_to_user(void __user *to,
@@ -44,14 +42,12 @@ extern unsigned long copy_transact_vsx_from_user(struct task_struct *task,
 
 #ifdef CONFIG_PPC64
 
-extern int handle_rt_signal64(int signr, struct k_sigaction *ka,
-                             siginfo_t *info, sigset_t *set,
+extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
                              struct pt_regs *regs);
 
 #else /* CONFIG_PPC64 */
 
-static inline int handle_rt_signal64(int signr, struct k_sigaction *ka,
-                                    siginfo_t *info, sigset_t *set,
+static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
                                     struct pt_regs *regs)
 {
        return -EFAULT;
index 1bc5a1755ed4648cfc5658e650e59dda772264b6..b171001698ff32f256e4298c9f7fdfda2ddeef39 100644 (file)
@@ -981,9 +981,8 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
  * Set up a signal frame for a "real-time" signal handler
  * (one which gets siginfo).
  */
-int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
-               siginfo_t *info, sigset_t *oldset,
-               struct pt_regs *regs)
+int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
+                      struct pt_regs *regs)
 {
        struct rt_sigframe __user *rt_sf;
        struct mcontext __user *frame;
@@ -995,13 +994,13 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
 
        /* Set up Signal Frame */
        /* Put a Real Time Context onto stack */
-       rt_sf = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
+       rt_sf = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*rt_sf), 1);
        addr = rt_sf;
        if (unlikely(rt_sf == NULL))
                goto badframe;
 
        /* Put the siginfo & fill in most of the ucontext */
-       if (copy_siginfo_to_user(&rt_sf->info, info)
+       if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)
            || __put_user(0, &rt_sf->uc.uc_flags)
            || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
            || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
@@ -1051,15 +1050,15 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
 
        /* Fill registers for signal handler */
        regs->gpr[1] = newsp;
-       regs->gpr[3] = sig;
+       regs->gpr[3] = ksig->sig;
        regs->gpr[4] = (unsigned long) &rt_sf->info;
        regs->gpr[5] = (unsigned long) &rt_sf->uc;
        regs->gpr[6] = (unsigned long) rt_sf;
-       regs->nip = (unsigned long) ka->sa.sa_handler;
+       regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
        /* enter the signal handler in native-endian mode */
        regs->msr &= ~MSR_LE;
        regs->msr |= (MSR_KERNEL & MSR_LE);
-       return 1;
+       return 0;
 
 badframe:
        if (show_unhandled_signals)
@@ -1069,8 +1068,7 @@ badframe:
                                   current->comm, current->pid,
                                   addr, regs->nip, regs->link);
 
-       force_sigsegv(sig, current);
-       return 0;
+       return 1;
 }
 
 static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
@@ -1409,8 +1407,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
 /*
  * OK, we're invoking a handler
  */
-int handle_signal32(unsigned long sig, struct k_sigaction *ka,
-                   siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+int handle_signal32(struct ksignal *ksig, sigset_t *oldset, struct pt_regs *regs)
 {
        struct sigcontext __user *sc;
        struct sigframe __user *frame;
@@ -1420,7 +1417,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
        unsigned long tramp;
 
        /* Set up Signal Frame */
-       frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 1);
+       frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 1);
        if (unlikely(frame == NULL))
                goto badframe;
        sc = (struct sigcontext __user *) &frame->sctx;
@@ -1428,7 +1425,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
 #if _NSIG != 64
 #error "Please adjust handle_signal()"
 #endif
-       if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler)
+       if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler)
            || __put_user(oldset->sig[0], &sc->oldmask)
 #ifdef CONFIG_PPC64
            || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
@@ -1436,7 +1433,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
            || __put_user(oldset->sig[1], &sc->_unused[3])
 #endif
            || __put_user(to_user_ptr(&frame->mctx), &sc->regs)
-           || __put_user(sig, &sc->signal))
+           || __put_user(ksig->sig, &sc->signal))
                goto badframe;
 
        if (vdso32_sigtramp && current->mm->context.vdso_base) {
@@ -1471,12 +1468,12 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
                goto badframe;
 
        regs->gpr[1] = newsp;
-       regs->gpr[3] = sig;
+       regs->gpr[3] = ksig->sig;
        regs->gpr[4] = (unsigned long) sc;
-       regs->nip = (unsigned long) ka->sa.sa_handler;
+       regs->nip = (unsigned long) (unsigned long)ksig->ka.sa.sa_handler;
        /* enter the signal handler in big-endian mode */
        regs->msr &= ~MSR_LE;
-       return 1;
+       return 0;
 
 badframe:
        if (show_unhandled_signals)
@@ -1486,8 +1483,7 @@ badframe:
                                   current->comm, current->pid,
                                   frame, regs->nip, regs->link);
 
-       force_sigsegv(sig, current);
-       return 0;
+       return 1;
 }
 
 /*
index 97c1e4b683fcb4cfdbe871b51ae8b5c23bb72a49..2cb0c94cafa5ef9e883b33136db22dcad1a7728b 100644 (file)
@@ -708,20 +708,19 @@ badframe:
        return 0;
 }
 
-int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
-               sigset_t *set, struct pt_regs *regs)
+int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
        unsigned long newsp = 0;
        long err = 0;
 
-       frame = get_sigframe(ka, get_tm_stackpointer(regs), sizeof(*frame), 0);
+       frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 0);
        if (unlikely(frame == NULL))
                goto badframe;
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
        if (err)
                goto badframe;
 
@@ -736,15 +735,15 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
                err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
                err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
                                            &frame->uc_transact.uc_mcontext,
-                                           regs, signr,
+                                           regs, ksig->sig,
                                            NULL,
-                                           (unsigned long)ka->sa.sa_handler);
+                                           (unsigned long)ksig->ka.sa.sa_handler);
        } else
 #endif
        {
                err |= __put_user(0, &frame->uc.uc_link);
-               err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, signr,
-                                       NULL, (unsigned long)ka->sa.sa_handler,
+               err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, ksig->sig,
+                                       NULL, (unsigned long)ksig->ka.sa.sa_handler,
                                        1);
        }
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
@@ -770,7 +769,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up "regs" so we "return" to the signal handler. */
        if (is_elf2_task()) {
-               regs->nip = (unsigned long) ka->sa.sa_handler;
+               regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
                regs->gpr[12] = regs->nip;
        } else {
                /* Handler is *really* a pointer to the function descriptor for
@@ -779,7 +778,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
                 * entry is the TOC value we need to use.
                 */
                func_descr_t __user *funct_desc_ptr =
-                       (func_descr_t __user *) ka->sa.sa_handler;
+                       (func_descr_t __user *) ksig->ka.sa.sa_handler;
 
                err |= get_user(regs->nip, &funct_desc_ptr->entry);
                err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
@@ -789,9 +788,9 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
        regs->msr &= ~MSR_LE;
        regs->msr |= (MSR_KERNEL & MSR_LE);
        regs->gpr[1] = newsp;
-       regs->gpr[3] = signr;
+       regs->gpr[3] = ksig->sig;
        regs->result = 0;
-       if (ka->sa.sa_flags & SA_SIGINFO) {
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
                err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
                err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
                regs->gpr[6] = (unsigned long) frame;
@@ -801,7 +800,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
        if (err)
                goto badframe;
 
-       return 1;
+       return 0;
 
 badframe:
        if (show_unhandled_signals)
@@ -809,6 +808,5 @@ badframe:
                                   current->comm, current->pid, "setup_rt_frame",
                                   (long)frame, regs->nip, regs->link);
 
-       force_sigsegv(signr, current);
-       return 0;
+       return 1;
 }
index f204d6920368366feeda238c782cf0fead4a29f3..598b0b42668bfc81eb6e2c5293a337e838717bbc 100644 (file)
@@ -320,38 +320,39 @@ static inline int map_signal(int sig)
                return sig;
 }
 
-static int setup_frame32(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs * regs)
+static int setup_frame32(struct ksignal *ksig, sigset_t *set,
+                        struct pt_regs *regs)
 {
-       sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
+       int sig = ksig->sig;
+       sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(sigframe32));
 
        if (frame == (void __user *) -1UL)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (save_sigregs32(regs, &frame->sregs))
-               goto give_sigsegv;
+               return -EFAULT;
        if (save_sigregs_gprs_high(regs, frame->gprs_high))
-               goto give_sigsegv;
+               return -EFAULT;
        if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
        } else {
                regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
                               (u16 __force __user *)(frame->retcode)))
-                       goto give_sigsegv;
+                       return -EFAULT;
         }
 
        /* Set up backchain. */
        if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->gprs[15] = (__force __u64) frame;
@@ -359,7 +360,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
        regs->psw.mask = PSW_MASK_BA |
                (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
-       regs->psw.addr = (__force __u64) ka->sa.sa_handler;
+       regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
 
        regs->gprs[2] = map_signal(sig);
        regs->gprs[3] = (__force __u64) &frame->sc;
@@ -376,25 +377,21 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
 
        /* Place signal number on stack to allow backtrace from handler.  */
        if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
-               goto give_sigsegv;
+               return -EFAULT;
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
-static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
+                           struct pt_regs *regs)
 {
        int err = 0;
-       rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
+       rt_sigframe32 __user *frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe32));
 
        if (frame == (void __user *) -1UL)
-               goto give_sigsegv;
+               return -EFAULT;
 
-       if (copy_siginfo_to_user32(&frame->info, info))
-               goto give_sigsegv;
+       if (copy_siginfo_to_user32(&frame->info, &ksig->info))
+               return -EFAULT;
 
        /* Create the ucontext.  */
        err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
@@ -404,22 +401,22 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= save_sigregs_gprs_high(regs, frame->gprs_high);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               regs->gprs[14] = (__u64 __force) ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
        } else {
                regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE;
                if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
                               (u16 __force __user *)(frame->retcode)))
-                       goto give_sigsegv;
+                       return -EFAULT;
        }
 
        /* Set up backchain. */
        if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->gprs[15] = (__force __u64) frame;
@@ -427,36 +424,30 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->psw.mask = PSW_MASK_BA |
                (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
-       regs->psw.addr = (__u64 __force) ka->sa.sa_handler;
+       regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
 
-       regs->gprs[2] = map_signal(sig);
+       regs->gprs[2] = map_signal(ksig->sig);
        regs->gprs[3] = (__force __u64) &frame->info;
        regs->gprs[4] = (__force __u64) &frame->uc;
        regs->gprs[5] = task_thread_info(current)->last_break;
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /*
  * OK, we're invoking a handler
  */    
 
-void handle_signal32(unsigned long sig, struct k_sigaction *ka,
-                   siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
+void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
+                    struct pt_regs *regs)
 {
        int ret;
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame32(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame32(ksig, oldset, regs);
        else
-               ret = setup_frame32(sig, ka, oldset, regs);
-       if (ret)
-               return;
-       signal_delivered(sig, info, ka, regs,
-                                test_thread_flag(TIF_SINGLE_STEP));
+               ret = setup_frame32(ksig, oldset, regs);
+
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
 }
 
index 6ac78192455f386aa72a15bdd2b73c55f844a5b5..1aad48398d06124541ef7936aacdb8d08f26c038 100644 (file)
@@ -48,8 +48,8 @@ void do_per_trap(struct pt_regs *regs);
 void syscall_trace(struct pt_regs *regs, int entryexit);
 void kernel_stack_overflow(struct pt_regs * regs);
 void do_signal(struct pt_regs *regs);
-void handle_signal32(unsigned long sig, struct k_sigaction *ka,
-                   siginfo_t *info, sigset_t *oldset, struct pt_regs *regs);
+void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
+                    struct pt_regs *regs);
 void do_notify_resume(struct pt_regs *regs);
 
 void __init init_IRQ(void);
index 42b49f9e19bf844dead561e546a160f35d1407bb..469c4c6d91822f32c2512551d6c8c29026ff8462 100644 (file)
@@ -200,15 +200,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
        frame = get_sigframe(ka, regs, sizeof(sigframe));
 
        if (frame == (void __user *) -1UL)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE))
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (save_sigregs(regs, &frame->sregs))
-               goto give_sigsegv;
+               return -EFAULT;
        if (__put_user(&frame->sregs, &frame->sc.sregs))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
@@ -220,12 +220,12 @@ static int setup_frame(int sig, struct k_sigaction *ka,
                        frame->retcode | PSW_ADDR_AMODE;
                if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
                               (u16 __user *)(frame->retcode)))
-                       goto give_sigsegv;
+                       return -EFAULT;
        }
 
        /* Set up backchain. */
        if (__put_user(regs->gprs[15], (addr_t __user *) frame))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->gprs[15] = (unsigned long) frame;
@@ -250,27 +250,23 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 
        /* Place signal number on stack to allow backtrace from handler.  */
        if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
-               goto give_sigsegv;
+               return -EFAULT;
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs * regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        int err = 0;
        rt_sigframe __user *frame;
 
-       frame = get_sigframe(ka, regs, sizeof(rt_sigframe));
+       frame = get_sigframe(&ksig->ka, regs, sizeof(rt_sigframe));
 
        if (frame == (void __user *) -1UL)
-               goto give_sigsegv;
+               return -EFAULT;
 
-       if (copy_siginfo_to_user(&frame->info, info))
-               goto give_sigsegv;
+       if (copy_siginfo_to_user(&frame->info, &ksig->info))
+               return -EFAULT;
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -279,24 +275,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= save_sigregs(regs, &frame->uc.uc_mcontext);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
                 regs->gprs[14] = (unsigned long)
-                       ka->sa.sa_restorer | PSW_ADDR_AMODE;
+                       ksig->ka.sa.sa_restorer | PSW_ADDR_AMODE;
        } else {
                 regs->gprs[14] = (unsigned long)
                        frame->retcode | PSW_ADDR_AMODE;
                if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
                               (u16 __user *)(frame->retcode)))
-                       goto give_sigsegv;
+                       return -EFAULT;
        }
 
        /* Set up backchain. */
        if (__put_user(regs->gprs[15], (addr_t __user *) frame))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->gprs[15] = (unsigned long) frame;
@@ -304,34 +300,27 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->psw.mask = PSW_MASK_EA | PSW_MASK_BA |
                (PSW_USER_BITS & PSW_MASK_ASC) |
                (regs->psw.mask & ~PSW_MASK_ASC);
-       regs->psw.addr = (unsigned long) ka->sa.sa_handler | PSW_ADDR_AMODE;
+       regs->psw.addr = (unsigned long) ksig->ka.sa.sa_handler | PSW_ADDR_AMODE;
 
-       regs->gprs[2] = map_signal(sig);
+       regs->gprs[2] = map_signal(ksig->sig);
        regs->gprs[3] = (unsigned long) &frame->info;
        regs->gprs[4] = (unsigned long) &frame->uc;
        regs->gprs[5] = task_thread_info(current)->last_break;
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
-                        siginfo_t *info, sigset_t *oldset,
-                        struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, sigset_t *oldset,
+                         struct pt_regs *regs)
 {
        int ret;
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
-       if (ret)
-               return;
-       signal_delivered(sig, info, ka, regs,
-                                test_thread_flag(TIF_SINGLE_STEP));
+               ret = setup_frame(ksig->sig, &ksig->ka, oldset, regs);
+
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
 }
 
 /*
@@ -345,9 +334,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
  */
 void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
        sigset_t *oldset = sigmask_to_save();
 
        /*
@@ -357,9 +344,8 @@ void do_signal(struct pt_regs *regs)
         */
        current_thread_info()->system_call =
                test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee!  Actually deliver the signal.  */
                if (current_thread_info()->system_call) {
                        regs->int_code = current_thread_info()->system_call;
@@ -370,7 +356,7 @@ void do_signal(struct pt_regs *regs)
                                regs->gprs[2] = -EINTR;
                                break;
                        case -ERESTARTSYS:
-                               if (!(ka.sa.sa_flags & SA_RESTART)) {
+                               if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
                                        regs->gprs[2] = -EINTR;
                                        break;
                                }
@@ -387,9 +373,9 @@ void do_signal(struct pt_regs *regs)
                clear_pt_regs_flag(regs, PIF_SYSCALL);
 
                if (is_compat_task())
-                       handle_signal32(signr, &ka, &info, oldset, regs);
+                       handle_signal32(&ksig, oldset, regs);
                else
-                       handle_signal(signr, &ka, &info, oldset, regs);
+                       handle_signal(&ksig, oldset, regs);
                return;
        }
 
index a00fba32b0ebe4fb414a8f21b4ab326b3980149b..1651807774ad10d677a8b43467b8d91940eba127 100644 (file)
@@ -173,15 +173,15 @@ badframe:
        return 0;
 }
 
-static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
-               int signr, sigset_t *set, siginfo_t *info)
+static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
+                         sigset_t *set)
 {
        struct rt_sigframe __user *frame;
        int err = 0;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        /*
         * Set up the return code ...
@@ -194,7 +194,7 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        err |= __put_user(0x80008002, frame->rs_code + 1);
        flush_cache_sigtramp((unsigned long) frame->rs_code);
 
-       err |= copy_siginfo_to_user(&frame->rs_info, info);
+       err |= copy_siginfo_to_user(&frame->rs_info, &ksig->info);
        err |= __put_user(0, &frame->rs_uc.uc_flags);
        err |= __put_user(NULL, &frame->rs_uc.uc_link);
        err |= __save_altstack(&frame->rs_uc.uc_stack, regs->regs[0]);
@@ -202,26 +202,23 @@ static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
        err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        regs->regs[0] = (unsigned long) frame;
        regs->regs[3] = (unsigned long) frame->rs_code;
-       regs->regs[4] = signr;
+       regs->regs[4] = ksig->sig;
        regs->regs[5] = (unsigned long) &frame->rs_info;
        regs->regs[6] = (unsigned long) &frame->rs_uc;
-       regs->regs[29] = (unsigned long) ka->sa.sa_handler;
-       regs->cp0_epc = (unsigned long) ka->sa.sa_handler;
+       regs->regs[29] = (unsigned long) ksig->ka.sa.sa_handler;
+       regs->cp0_epc = (unsigned long) ksig->ka.sa.sa_handler;
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(signr, current);
-       return -EFAULT;
 }
 
-static void handle_signal(unsigned long sig, siginfo_t *info,
-       struct k_sigaction *ka, struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
+       int ret;
+
        if (regs->is_syscall) {
                switch (regs->regs[4]) {
                case ERESTART_RESTARTBLOCK:
@@ -229,7 +226,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
                        regs->regs[4] = EINTR;
                        break;
                case ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->regs[4] = EINTR;
                                break;
                        }
@@ -245,17 +242,14 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
        /*
         * Set up the stack frame
         */
-       if (setup_rt_frame(ka, regs, sig, sigmask_to_save(), info) < 0)
-               return;
+       ret = setup_rt_frame(ksig, regs, sigmask_to_save());
 
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 static void do_signal(struct pt_regs *regs)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which is why we may in certain
@@ -265,10 +259,9 @@ static void do_signal(struct pt_regs *regs)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Actually deliver the signal.  */
-               handle_signal(signr, &info, &ka, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
index 594cd371aa280593b77e7b5cf582a16e4ad948ab..2f002b24fb92f4b9db193f953c311b9ebdc4b8ef 100644 (file)
@@ -262,17 +262,17 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 extern void __kernel_sigreturn(void);
 extern void __kernel_rt_sigreturn(void);
 
-static int setup_frame(int sig, struct k_sigaction *ka,
-                       sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+                      struct pt_regs *regs)
 {
        struct sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int signal;
 
-       frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -288,8 +288,8 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               regs->pr = (unsigned long) ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
 #ifdef CONFIG_VSYSCALL
        } else if (likely(current->mm->context.vdso)) {
                regs->pr = VDSO_SYM(&__kernel_sigreturn);
@@ -309,7 +309,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->regs[15] = (unsigned long) frame;
@@ -319,15 +319,15 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
-                       (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
+                       (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
 
                err |= __get_user(regs->pc, &funcptr->text);
                err |= __get_user(regs->regs[12], &funcptr->GOT);
        } else
-               regs->pc = (unsigned long)ka->sa.sa_handler;
+               regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        set_fs(USER_DS);
 
@@ -335,23 +335,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
                 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int signal;
 
-       frame = get_sigframe(ka, regs->regs[15], sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs->regs[15], sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -359,7 +355,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                ? current_thread_info()->exec_domain->signal_invmap[sig]
                : sig;
 
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -371,8 +367,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               regs->pr = (unsigned long) ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               regs->pr = (unsigned long) ksig->ka.sa.sa_restorer;
 #ifdef CONFIG_VSYSCALL
        } else if (likely(current->mm->context.vdso)) {
                regs->pr = VDSO_SYM(&__kernel_rt_sigreturn);
@@ -392,7 +388,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        }
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up registers for signal handler */
        regs->regs[15] = (unsigned long) frame;
@@ -402,15 +398,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        if (current->personality & FDPIC_FUNCPTRS) {
                struct fdpic_func_descriptor __user *funcptr =
-                       (struct fdpic_func_descriptor __user *)ka->sa.sa_handler;
+                       (struct fdpic_func_descriptor __user *)ksig->ka.sa.sa_handler;
 
                err |= __get_user(regs->pc, &funcptr->text);
                err |= __get_user(regs->regs[12], &funcptr->GOT);
        } else
-               regs->pc = (unsigned long)ka->sa.sa_handler;
+               regs->pc = (unsigned long)ksig->ka.sa.sa_handler;
 
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        set_fs(USER_DS);
 
@@ -418,10 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 static inline void
@@ -455,22 +447,18 @@ handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
  * OK, we're invoking a handler
  */
 static void
-handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
-             struct pt_regs *regs, unsigned int save_r0)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs, unsigned int save_r0)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
+               ret = setup_frame(ksig, oldset, regs);
 
-       if (ret)
-               return;
-       signal_delivered(sig, info, ka, regs,
-                       test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
@@ -484,9 +472,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
  */
 static void do_signal(struct pt_regs *regs, unsigned int save_r0)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which
@@ -497,12 +483,11 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
-               handle_syscall_restart(save_r0, regs, &ka.sa);
+       if (get_signal(&ksig)) {
+               handle_syscall_restart(save_r0, regs, &ksig.ka.sa);
 
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &ka, &info, regs, save_r0);
+               handle_signal(&ksig, regs, save_r0);
                return;
        }
 
index 23d4c71c91afb032c341b2c3b41da7220ed2f38b..897abe7b871e2daeb9db132930fd0c6c7cb1349e 100644 (file)
@@ -41,8 +41,7 @@
 #define DEBUG_SIG 0
 
 static void
-handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
-               struct pt_regs * regs);
+handle_signal(struct ksignal *ksig, struct pt_regs *regs);
 
 static inline void
 handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
@@ -82,9 +81,7 @@ handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
  */
 static void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which
@@ -95,12 +92,11 @@ static void do_signal(struct pt_regs *regs)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, 0);
-       if (signr > 0) {
-               handle_syscall_restart(regs, &ka.sa);
+       if (get_signal(&ksig)) {
+               handle_syscall_restart(regs, &ksig.ka.sa);
 
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &info, &ka, regs);
+               handle_signal(&ksig, regs);
                return;
        }
 
@@ -378,17 +374,16 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 void sa_default_restorer(void);                /* See comments below */
 void sa_default_rt_restorer(void);     /* See comments below */
 
-static int setup_frame(int sig, struct k_sigaction *ka,
-                      sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 {
        struct sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int signal;
 
-       frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -400,7 +395,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 
        /* Give up earlier as i386, in case */
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        if (_NSIG_WORDS > 1) {
                err |= __copy_to_user(frame->extramask, &set->sig[1],
@@ -408,16 +403,16 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 
        /* Give up earlier as i386, in case */
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
                /*
                 * On SH5 all edited pointers are subject to NEFF
                 */
                DEREF_REG_PR = neff_sign_extend((unsigned long)
-                       ka->sa.sa_restorer | 0x1);
+                       ksig->ka->sa.sa_restorer | 0x1);
        } else {
                /*
                 * Different approach on SH5.
@@ -435,7 +430,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
 
                if (__copy_to_user(frame->retcode,
                        (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
-                       goto give_sigsegv;
+                       return -EFAULT;
 
                /* Cohere the trampoline with the I-cache. */
                flush_cache_sigtramp(DEREF_REG_PR-1);
@@ -460,7 +455,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
        regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
        regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 
-       regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
+       regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
 
        set_fs(USER_DS);
 
@@ -471,23 +466,19 @@ static int setup_frame(int sig, struct k_sigaction *ka,
                 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *kig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int signal;
 
-       frame = get_sigframe(ka, regs->regs[REG_SP], sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               return -EFAULT;
 
        signal = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -497,11 +488,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        /* Give up earlier as i386, in case */
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Create the ucontext.  */
        err |= __put_user(0, &frame->uc.uc_flags);
@@ -513,16 +504,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        /* Give up earlier as i386, in case */
        if (err)
-               goto give_sigsegv;
+               return -EFAULT;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
                /*
                 * On SH5 all edited pointers are subject to NEFF
                 */
                DEREF_REG_PR = neff_sign_extend((unsigned long)
-                       ka->sa.sa_restorer | 0x1);
+                       ksig->ka.sa.sa_restorer | 0x1);
        } else {
                /*
                 * Different approach on SH5.
@@ -540,7 +531,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
                if (__copy_to_user(frame->retcode,
                        (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
-                       goto give_sigsegv;
+                       return -EFAULT;
 
                /* Cohere the trampoline with the I-cache. */
                flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
@@ -554,7 +545,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
        regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
        regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
-       regs->pc = neff_sign_extend((unsigned long)ka->sa.sa_handler);
+       regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
 
        set_fs(USER_DS);
 
@@ -564,33 +555,24 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /*
  * OK, we're invoking a handler
  */
 static void
-handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
-               struct pt_regs * regs)
+handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
 
        /* Set up the stack frame */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(sig, ka, oldset, regs);
-
-       if (ret)
-               return;
+               ret = setup_frame(ksig, oldset, regs);
 
-       signal_delivered(sig, info, ka, regs,
-                       test_thread_flag(TIF_SINGLESTEP));
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
index ffd4493efc7812aa546203c6afdac26532f2f71f..c14e36f008c8f3a047fa4a9a583735a01264bcb3 100644 (file)
@@ -267,8 +267,7 @@ static inline int is_compat_task(void)
        return current_thread_info()->status & TS_COMPAT;
 }
 
-extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
-                                siginfo_t *info, sigset_t *set,
+extern int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
                                 struct pt_regs *regs);
 
 /* Compat syscalls. */
index 19c04b5ce408b2e248fc2d64b2ee8c7a20037fe4..8c5abf2e4794ef269f4ad890902a317dd6b01bb1 100644 (file)
@@ -190,18 +190,18 @@ static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
        return (void __user *) sp;
 }
 
-int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                         sigset_t *set, struct pt_regs *regs)
+int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        unsigned long restorer;
        struct compat_rt_sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int usig;
 
-       frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+       frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               goto err;
 
        usig = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -210,12 +210,12 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                : sig;
 
        /* Always write at least the signal number for the stack backtracer. */
-       if (ka->sa.sa_flags & SA_SIGINFO) {
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
                /* At sigreturn time, restore the callee-save registers too. */
-               err |= copy_siginfo_to_user32(&frame->info, info);
+               err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
                regs->flags |= PT_FLAGS_RESTORE_REGS;
        } else {
-               err |= __put_user(info->si_signo, &frame->info.si_signo);
+               err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
        }
 
        /* Create the ucontext.  */
@@ -226,11 +226,11 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
-               goto give_sigsegv;
+               goto err;
 
        restorer = VDSO_SYM(&__vdso_rt_sigreturn);
-       if (ka->sa.sa_flags & SA_RESTORER)
-               restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
+               restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
 
        /*
         * Set up registers for signal handler.
@@ -239,7 +239,7 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
         * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
         * since some things rely on this (e.g. glibc's debug/segfault.c).
         */
-       regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
+       regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
        regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
        regs->sp = ptr_to_compat_reg(frame);
        regs->lr = restorer;
@@ -249,7 +249,8 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->flags |= PT_FLAGS_CALLER_SAVES;
        return 0;
 
-give_sigsegv:
-       signal_fault("bad setup frame", regs, frame, sig);
+err:
+       trace_unhandled_signal("bad sigreturn frame", regs,
+                             (unsigned long)frame, SIGSEGV);
        return -EFAULT;
 }
index d1d026f0126715d2620c0de1a258f9b806892b4a..7c2fecc52177573ab79194e701d3a7726dc81af6 100644 (file)
@@ -153,18 +153,18 @@ static inline void __user *get_sigframe(struct k_sigaction *ka,
        return (void __user *) sp;
 }
 
-static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                          sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        unsigned long restorer;
        struct rt_sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int usig;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
-               goto give_sigsegv;
+               goto err;
 
        usig = current_thread_info()->exec_domain
                && current_thread_info()->exec_domain->signal_invmap
@@ -173,12 +173,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                : sig;
 
        /* Always write at least the signal number for the stack backtracer. */
-       if (ka->sa.sa_flags & SA_SIGINFO) {
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
                /* At sigreturn time, restore the callee-save registers too. */
-               err |= copy_siginfo_to_user(&frame->info, info);
+               err |= copy_siginfo_to_user(&frame->info, &ksig->info);
                regs->flags |= PT_FLAGS_RESTORE_REGS;
        } else {
-               err |= __put_user(info->si_signo, &frame->info.si_signo);
+               err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
        }
 
        /* Create the ucontext.  */
@@ -189,11 +189,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
-               goto give_sigsegv;
+               goto err;
 
        restorer = VDSO_SYM(&__vdso_rt_sigreturn);
-       if (ka->sa.sa_flags & SA_RESTORER)
-               restorer = (unsigned long) ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
+               restorer = (unsigned long) ksig->ka.sa.sa_restorer;
 
        /*
         * Set up registers for signal handler.
@@ -202,7 +202,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
         * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
         * since some things rely on this (e.g. glibc's debug/segfault.c).
         */
-       regs->pc = (unsigned long) ka->sa.sa_handler;
+       regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
        regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
        regs->sp = (unsigned long) frame;
        regs->lr = restorer;
@@ -212,8 +212,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        regs->flags |= PT_FLAGS_CALLER_SAVES;
        return 0;
 
-give_sigsegv:
-       signal_fault("bad setup frame", regs, frame, sig);
+err:
+       trace_unhandled_signal("bad sigreturn frame", regs,
+                             (unsigned long)frame, SIGSEGV);
        return -EFAULT;
 }
 
@@ -221,9 +222,7 @@ give_sigsegv:
  * OK, we're invoking a handler
  */
 
-static void handle_signal(unsigned long sig, siginfo_t *info,
-                        struct k_sigaction *ka,
-                        struct pt_regs *regs)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int ret;
@@ -238,7 +237,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
                        break;
 
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->regs[0] = -EINTR;
                                break;
                        }
@@ -254,14 +253,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
        /* Set up the stack frame */
 #ifdef CONFIG_COMPAT
        if (is_compat_task())
-               ret = compat_setup_rt_frame(sig, ka, info, oldset, regs);
+               ret = compat_setup_rt_frame(ksig, oldset, regs);
        else
 #endif
-               ret = setup_rt_frame(sig, ka, info, oldset, regs);
-       if (ret)
-               return;
-       signal_delivered(sig, info, ka, regs,
-                       test_thread_flag(TIF_SINGLESTEP));
+               ret = setup_rt_frame(ksig, oldset, regs);
+
+       signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
@@ -271,9 +268,7 @@ static void handle_signal(unsigned long sig, siginfo_t *info,
  */
 void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        /*
         * i386 will check if we're coming from kernel mode and bail out
@@ -282,10 +277,9 @@ void do_signal(struct pt_regs *regs)
         * helpful, we can reinstate the check on "!user_mode(regs)".
         */
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                /* Whee! Actually deliver the signal.  */
-               handle_signal(signr, &info, &ka, regs);
+               handle_signal(&ksig, regs);
                goto done;
        }
 
index f2ca5702a4e2ae2b418382712c93aeed03736450..a5cde5c433b4285d61faa6f01099045f93f421da 100644 (file)
@@ -6,14 +6,10 @@
 #ifndef __FRAME_KERN_H_
 #define __FRAME_KERN_H_
 
-extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
-                                struct k_sigaction *ka,
-                                struct pt_regs *regs,
-                                sigset_t *mask);
-extern int setup_signal_stack_si(unsigned long stack_top, int sig,
-                                struct k_sigaction *ka,
-                                struct pt_regs *regs, struct siginfo *info,
-                                sigset_t *mask);
+extern int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
+                                struct pt_regs *regs, sigset_t *mask);
+extern int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
+                                struct pt_regs *regs, sigset_t *mask);
 
 #endif
 
index f57e02e7910f66a6346d7454f7fd612ec6d0735f..4f60e4aad79091aed4f1f09b2e4d4288e0074cd8 100644 (file)
@@ -18,8 +18,7 @@ EXPORT_SYMBOL(unblock_signals);
 /*
  * OK, we're invoking a handler
  */
-static void handle_signal(struct pt_regs *regs, unsigned long signr,
-                        struct k_sigaction *ka, struct siginfo *info)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
        sigset_t *oldset = sigmask_to_save();
        int singlestep = 0;
@@ -39,7 +38,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
                        break;
 
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                PT_REGS_SYSCALL_RET(regs) = -EINTR;
                                break;
                        }
@@ -52,32 +51,28 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr,
        }
 
        sp = PT_REGS_SP(regs);
-       if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
+       if ((ksig->ka.sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
                sp = current->sas_ss_sp + current->sas_ss_size;
 
 #ifdef CONFIG_ARCH_HAS_SC_SIGNALS
-       if (!(ka->sa.sa_flags & SA_SIGINFO))
-               err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
+       if (!(ksig->ka.sa.sa_flags & SA_SIGINFO))
+               err = setup_signal_stack_sc(sp, ksig, regs, oldset);
        else
 #endif
-               err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
+               err = setup_signal_stack_si(sp, ksig, regs, oldset);
 
-       if (err)
-               force_sigsegv(signr, current);
-       else
-               signal_delivered(signr, info, ka, regs, singlestep);
+       signal_setup_done(err, ksig, singlestep);
 }
 
 static int kern_do_signal(struct pt_regs *regs)
 {
-       struct k_sigaction ka_copy;
-       struct siginfo info;
-       int sig, handled_sig = 0;
+       struct ksignal ksig;
+       int handled_sig = 0;
 
-       while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
+       while (get_signal(&ksig)) {
                handled_sig = 1;
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(regs, sig, &ka_copy, &info);
+               handle_signal(&ksig, regs);
        }
 
        /* Did we come from a system call? */
index 6905f0ebdc77e366d8e7b286800531b66f86f58b..780d77388dec507d7e11bb6f9d8595fe4f64c93d 100644 (file)
@@ -238,10 +238,10 @@ static int setup_return(struct pt_regs *regs, struct k_sigaction *ka,
        return 0;
 }
 
-static int setup_frame(int usig, struct k_sigaction *ka,
-               sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+                      struct pt_regs *regs)
 {
-       struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
+       struct sigframe __user *frame = get_sigframe(&ksig->ka, regs, sizeof(*frame));
        int err = 0;
 
        if (!frame)
@@ -254,29 +254,29 @@ static int setup_frame(int usig, struct k_sigaction *ka,
 
        err |= setup_sigframe(frame, regs, set);
        if (err == 0)
-               err |= setup_return(regs, ka, frame->retcode, frame, usig);
+               err |= setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
 
        return err;
 }
 
-static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
-              sigset_t *set, struct pt_regs *regs)
+static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+                         struct pt_regs *regs)
 {
        struct rt_sigframe __user *frame =
-                       get_sigframe(ka, regs, sizeof(*frame));
+                       get_sigframe(&ksig->ka, regs, sizeof(*frame));
        int err = 0;
 
        if (!frame)
                return 1;
 
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
        err |= __put_user(0, &frame->sig.uc.uc_flags);
        err |= __put_user(NULL, &frame->sig.uc.uc_link);
        err |= __save_altstack(&frame->sig.uc.uc_stack, regs->UCreg_sp);
        err |= setup_sigframe(&frame->sig, regs, set);
        if (err == 0)
-               err |= setup_return(regs, ka, frame->sig.retcode, frame, usig);
+               err |= setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
 
        if (err == 0) {
                /*
@@ -299,13 +299,13 @@ static inline void setup_syscall_restart(struct pt_regs *regs)
 /*
  * OK, we're invoking a handler
  */
-static void handle_signal(unsigned long sig, struct k_sigaction *ka,
-             siginfo_t *info, struct pt_regs *regs, int syscall)
+static void handle_signal(struct ksignal *ksig, struct pt_regs *regs,
+                         int syscall)
 {
        struct thread_info *thread = current_thread_info();
        struct task_struct *tsk = current;
        sigset_t *oldset = sigmask_to_save();
-       int usig = sig;
+       int usig = ksig->sig;
        int ret;
 
        /*
@@ -318,7 +318,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
                        regs->UCreg_00 = -EINTR;
                        break;
                case -ERESTARTSYS:
-                       if (!(ka->sa.sa_flags & SA_RESTART)) {
+                       if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
                                regs->UCreg_00 = -EINTR;
                                break;
                        }
@@ -338,22 +338,17 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
        /*
         * Set up the stack frame
         */
-       if (ka->sa.sa_flags & SA_SIGINFO)
-               ret = setup_rt_frame(usig, ka, info, oldset, regs);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO)
+               ret = setup_rt_frame(ksig, oldset, regs);
        else
-               ret = setup_frame(usig, ka, oldset, regs);
+               ret = setup_frame(ksig, oldset, regs);
 
        /*
         * Check that the resulting registers are actually sane.
         */
        ret |= !valid_user_regs(regs);
 
-       if (ret != 0) {
-               force_sigsegv(sig, tsk);
-               return;
-       }
-
-       signal_delivered(sig, info, ka, regs, 0);
+       signal_setup_done(ret, ksig, 0);
 }
 
 /*
@@ -367,9 +362,7 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
  */
 static void do_signal(struct pt_regs *regs, int syscall)
 {
-       struct k_sigaction ka;
-       siginfo_t info;
-       int signr;
+       struct ksignal ksig;
 
        /*
         * We want the common case to go fast, which
@@ -380,9 +373,8 @@ static void do_signal(struct pt_regs *regs, int syscall)
        if (!user_mode(regs))
                return;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-       if (signr > 0) {
-               handle_signal(signr, &ka, &info, regs, syscall);
+       if (get_signsl(&ksig)) {
+               handle_signal(&ksig, regs, syscall);
                return;
        }
 
index 5e04a1c899fa6563cd8809c84dd41cf02b1a950e..79d824551c1a564dd6b22a31a2319ec980d92ea5 100644 (file)
@@ -370,13 +370,12 @@ struct rt_sigframe
        char retcode[8];
 };
 
-int setup_signal_stack_sc(unsigned long stack_top, int sig,
-                         struct k_sigaction *ka, struct pt_regs *regs,
-                         sigset_t *mask)
+int setup_signal_stack_sc(unsigned long stack_top, struct ksignal *ksig,
+                         struct pt_regs *regs, sigset_t *mask)
 {
        struct sigframe __user *frame;
        void __user *restorer;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
 
        /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
        stack_top = ((stack_top + 4) & -16UL) - 4;
@@ -385,8 +384,8 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
                return 1;
 
        restorer = frame->retcode;
-       if (ka->sa.sa_flags & SA_RESTORER)
-               restorer = ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
+               restorer = ksig->ka.sa.sa_restorer;
 
        err |= __put_user(restorer, &frame->pretcode);
        err |= __put_user(sig, &frame->sig);
@@ -410,20 +409,19 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
                return err;
 
        PT_REGS_SP(regs) = (unsigned long) frame;
-       PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+       PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
        PT_REGS_AX(regs) = (unsigned long) sig;
        PT_REGS_DX(regs) = (unsigned long) 0;
        PT_REGS_CX(regs) = (unsigned long) 0;
        return 0;
 }
 
-int setup_signal_stack_si(unsigned long stack_top, int sig,
-                         struct k_sigaction *ka, struct pt_regs *regs,
-                         siginfo_t *info, sigset_t *mask)
+int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
+                         struct pt_regs *regs, sigset_t *mask)
 {
        struct rt_sigframe __user *frame;
        void __user *restorer;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
 
        stack_top &= -8UL;
        frame = (struct rt_sigframe __user *) stack_top - 1;
@@ -431,14 +429,14 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
                return 1;
 
        restorer = frame->retcode;
-       if (ka->sa.sa_flags & SA_RESTORER)
-               restorer = ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
+               restorer = ksig->ka.sa.sa_restorer;
 
        err |= __put_user(restorer, &frame->pretcode);
        err |= __put_user(sig, &frame->sig);
        err |= __put_user(&frame->info, &frame->pinfo);
        err |= __put_user(&frame->uc, &frame->puc);
-       err |= copy_siginfo_to_user(&frame->info, info);
+       err |= copy_siginfo_to_user(&frame->info, &ksig->info);
        err |= copy_ucontext_to_user(&frame->uc, &frame->fpstate, mask,
                                        PT_REGS_SP(regs));
 
@@ -457,7 +455,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
                return err;
 
        PT_REGS_SP(regs) = (unsigned long) frame;
-       PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+       PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
        PT_REGS_AX(regs) = (unsigned long) sig;
        PT_REGS_DX(regs) = (unsigned long) &frame->info;
        PT_REGS_CX(regs) = (unsigned long) &frame->uc;
@@ -502,12 +500,11 @@ struct rt_sigframe
        struct _fpstate fpstate;
 };
 
-int setup_signal_stack_si(unsigned long stack_top, int sig,
-                         struct k_sigaction *ka, struct pt_regs * regs,
-                         siginfo_t *info, sigset_t *set)
+int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
+                         struct pt_regs *regs, sigset_t *set)
 {
        struct rt_sigframe __user *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
 
        frame = (struct rt_sigframe __user *)
                round_down(stack_top - sizeof(struct rt_sigframe), 16);
@@ -517,8 +514,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto out;
 
-       if (ka->sa.sa_flags & SA_SIGINFO) {
-               err |= copy_siginfo_to_user(&frame->info, info);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+               err |= copy_siginfo_to_user(&frame->info, &ksig->info);
                if (err)
                        goto out;
        }
@@ -543,8 +540,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
         * already in userspace.
         */
        /* x86-64 should always use SA_RESTORER. */
-       if (ka->sa.sa_flags & SA_RESTORER)
-               err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
+               err |= __put_user(ksig->ka.sa.sa_restorer, &frame->pretcode);
        else
                /* could use a vstub here */
                return err;
@@ -570,7 +567,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
         */
        PT_REGS_SI(regs) = (unsigned long) &frame->info;
        PT_REGS_DX(regs) = (unsigned long) &frame->uc;
-       PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
+       PT_REGS_IP(regs) = (unsigned long) ksig->ka.sa.sa_handler;
  out:
        return err;
 }
index 98b67d5f15144659dd9ea6954ab440e964a2aae8..4612321c73cc1d78952e5b89ad74b73973249e39 100644 (file)
@@ -331,17 +331,17 @@ gen_return_code(unsigned char *codemem)
 }
 
 
-static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
-                      sigset_t *set, struct pt_regs *regs)
+static int setup_frame(struct ksignal *ksig, sigset_t *set,
+                      struct pt_regs *regs)
 {
        struct rt_sigframe *frame;
-       int err = 0;
+       int err = 0, sig = ksig->sig;
        int signal;
        unsigned long sp, ra, tp;
 
        sp = regs->areg[1];
 
-       if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
+       if ((ksig->ka.sa.sa_flags & SA_ONSTACK) != 0 && sas_ss_flags(sp) == 0) {
                sp = current->sas_ss_sp + current->sas_ss_size;
        }
 
@@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                panic ("Double exception sys_sigreturn\n");
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) {
-               goto give_sigsegv;
+               return -EFAULT;
        }
 
        signal = current_thread_info()->exec_domain
@@ -360,8 +360,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                ? current_thread_info()->exec_domain->signal_invmap[sig]
                : sig;
 
-       if (ka->sa.sa_flags & SA_SIGINFO) {
-               err |= copy_siginfo_to_user(&frame->info, info);
+       if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
+               err |= copy_siginfo_to_user(&frame->info, &ksig->info);
        }
 
        /* Create the user context.  */
@@ -372,8 +372,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
        err |= setup_sigcontext(frame, regs);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 
-       if (ka->sa.sa_flags & SA_RESTORER) {
-               ra = (unsigned long)ka->sa.sa_restorer;
+       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+               ra = (unsigned long)ksig->ka.sa.sa_restorer;
        } else {
 
                /* Create sys_rt_sigreturn syscall in stack frame */
@@ -381,7 +381,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
                err |= gen_return_code(frame->retcode);
 
                if (err) {
-                       goto give_sigsegv;
+                       return -EFAULT;
                }
                ra = (unsigned long) frame->retcode;
        }
@@ -393,7 +393,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up registers for signal handler; preserve the threadptr */
        tp = regs->threadptr;
-       start_thread(regs, (unsigned long) ka->sa.sa_handler,
+       start_thread(regs, (unsigned long) ksig->ka.sa.sa_handler,
                     (unsigned long) frame);
 
        /* Set up a stack frame for a call4
@@ -416,10 +416,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 #endif
 
        return 0;
-
-give_sigsegv:
-       force_sigsegv(sig, current);
-       return -EFAULT;
 }
 
 /*
@@ -433,15 +429,11 @@ give_sigsegv:
  */
 static void do_signal(struct pt_regs *regs)
 {
-       siginfo_t info;
-       int signr;
-       struct k_sigaction ka;
+       struct ksignal ksig;
 
        task_pt_regs(current)->icountlevel = 0;
 
-       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-
-       if (signr > 0) {
+       if (get_signal(&ksig)) {
                int ret;
 
                /* Are we from a system call? */
@@ -457,7 +449,7 @@ static void do_signal(struct pt_regs *regs)
                                        break;
 
                                case -ERESTARTSYS:
-                                       if (!(ka.sa.sa_flags & SA_RESTART)) {
+                                       if (!(ksig.ka.sa.sa_flags & SA_RESTART)) {
                                                regs->areg[2] = -EINTR;
                                                break;
                                        }
@@ -476,11 +468,8 @@ static void do_signal(struct pt_regs *regs)
 
                /* Whee!  Actually deliver the signal.  */
                /* Set up the stack frame */
-               ret = setup_frame(signr, &ka, &info, sigmask_to_save(), regs);
-               if (ret)
-                       return;
-
-               signal_delivered(signr, &info, &ka, regs, 0);
+               ret = setup_frame(&ksig, sigmask_to_save(), regs);
+               signal_setup_done(ret, &ksig, 0);
                if (current->ptrace & PT_SINGLESTEP)
                        task_pt_regs(current)->icountlevel = 1;
 
index db2f6474e95e84b62b570c014cf569c1d24188bc..857ba40426babdba40b2d81717722fea73c1acad 100644 (file)
@@ -2360,8 +2360,10 @@ static inline int on_sig_stack(unsigned long sp)
 
 static inline int sas_ss_flags(unsigned long sp)
 {
-       return (current->sas_ss_size == 0 ? SS_DISABLE
-               : on_sig_stack(sp) ? SS_ONSTACK : 0);
+       if (!current->sas_ss_size)
+               return SS_DISABLE;
+
+       return on_sig_stack(sp) ? SS_ONSTACK : 0;
 }
 
 static inline unsigned long sigsp(unsigned long sp, struct ksignal *ksig)
index c9e65360c49a7ccf7ffea8195017102f27e1cd7c..750196fcc0a5144aebb1df7f67102502c871a990 100644 (file)
@@ -280,9 +280,8 @@ struct ksignal {
        int sig;
 };
 
-extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie);
+extern int get_signal(struct ksignal *ksig);
 extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping);
-extern void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka, struct pt_regs *regs, int stepping);
 extern void exit_signals(struct task_struct *tsk);
 extern void kernel_sigaction(int, __sighandler_t);
 
@@ -301,18 +300,6 @@ static inline void disallow_signal(int sig)
        kernel_sigaction(sig, SIG_IGN);
 }
 
-/*
- * Eventually that'll replace get_signal_to_deliver(); macro for now,
- * to avoid nastiness with include order.
- */
-#define get_signal(ksig)                                       \
-({                                                             \
-       struct ksignal *p = (ksig);                             \
-       p->sig = get_signal_to_deliver(&p->info, &p->ka,        \
-                                       signal_pt_regs(), NULL);\
-       p->sig > 0;                                             \
-})
-
 extern struct kmem_cache *sighand_cachep;
 
 int unhandled_signal(struct task_struct *tsk, int sig);
index 6f8ab7da27c43c47b82b25eb5198a82ca0d8487e..84d497297c5f44af0bcc1ace0a0584092d77ab92 100644 (file)
@@ -133,10 +133,6 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
 
 /**
  * tracehook_signal_handler - signal handler setup is complete
- * @sig:               number of signal being delivered
- * @info:              siginfo_t of signal being delivered
- * @ka:                        sigaction setting that chose the handler
- * @regs:              user register state
  * @stepping:          nonzero if debugger single-step or block-step in use
  *
  * Called by the arch code after a signal handler has been set up.
@@ -146,9 +142,7 @@ static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
  * Called without locks, shortly before returning to user mode
  * (or handling more signals).
  */
-static inline void tracehook_signal_handler(int sig, siginfo_t *info,
-                                           const struct k_sigaction *ka,
-                                           struct pt_regs *regs, int stepping)
+static inline void tracehook_signal_handler(int stepping)
 {
        if (stepping)
                ptrace_notify(SIGTRAP);
index 40b76e351e64aae9cb92039d3d77332afac50d51..8f0876f9f6dd5deb400a1f3ef071b66da877a363 100644 (file)
@@ -2170,8 +2170,7 @@ static int ptrace_signal(int signr, siginfo_t *info)
        return signr;
 }
 
-int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
-                         struct pt_regs *regs, void *cookie)
+int get_signal(struct ksignal *ksig)
 {
        struct sighand_struct *sighand = current->sighand;
        struct signal_struct *signal = current->signal;
@@ -2241,13 +2240,13 @@ relock:
                        goto relock;
                }
 
-               signr = dequeue_signal(current, &current->blocked, info);
+               signr = dequeue_signal(current, &current->blocked, &ksig->info);
 
                if (!signr)
                        break; /* will return 0 */
 
                if (unlikely(current->ptrace) && signr != SIGKILL) {
-                       signr = ptrace_signal(signr, info);
+                       signr = ptrace_signal(signr, &ksig->info);
                        if (!signr)
                                continue;
                }
@@ -2255,13 +2254,13 @@ relock:
                ka = &sighand->action[signr-1];
 
                /* Trace actually delivered signals. */
-               trace_signal_deliver(signr, info, ka);
+               trace_signal_deliver(signr, &ksig->info, ka);
 
                if (ka->sa.sa_handler == SIG_IGN) /* Do nothing.  */
                        continue;
                if (ka->sa.sa_handler != SIG_DFL) {
                        /* Run the handler.  */
-                       *return_ka = *ka;
+                       ksig->ka = *ka;
 
                        if (ka->sa.sa_flags & SA_ONESHOT)
                                ka->sa.sa_handler = SIG_DFL;
@@ -2311,7 +2310,7 @@ relock:
                                spin_lock_irq(&sighand->siglock);
                        }
 
-                       if (likely(do_signal_stop(info->si_signo))) {
+                       if (likely(do_signal_stop(ksig->info.si_signo))) {
                                /* It released the siglock.  */
                                goto relock;
                        }
@@ -2332,7 +2331,7 @@ relock:
 
                if (sig_kernel_coredump(signr)) {
                        if (print_fatal_signals)
-                               print_fatal_signal(info->si_signo);
+                               print_fatal_signal(ksig->info.si_signo);
                        proc_coredump_connector(current);
                        /*
                         * If it was able to dump core, this kills all
@@ -2342,34 +2341,32 @@ relock:
                         * first and our do_group_exit call below will use
                         * that value and ignore the one we pass it.
                         */
-                       do_coredump(info);
+                       do_coredump(&ksig->info);
                }
 
                /*
                 * Death signals, no core dump.
                 */
-               do_group_exit(info->si_signo);
+               do_group_exit(ksig->info.si_signo);
                /* NOTREACHED */
        }
        spin_unlock_irq(&sighand->siglock);
-       return signr;
+
+       ksig->sig = signr;
+       return ksig->sig > 0;
 }
 
 /**
  * signal_delivered - 
- * @sig:               number of signal being delivered
- * @info:              siginfo_t of signal being delivered
- * @ka:                        sigaction setting that chose the handler
- * @regs:              user register state
+ * @ksig:              kernel signal struct
  * @stepping:          nonzero if debugger single-step or block-step in use
  *
  * This function should be called when a signal has successfully been
- * delivered. It updates the blocked signals accordingly (@ka->sa.sa_mask
+ * delivered. It updates the blocked signals accordingly (@ksig->ka.sa.sa_mask
  * is always blocked, and the signal itself is blocked unless %SA_NODEFER
- * is set in @ka->sa.sa_flags.  Tracing is notified.
+ * is set in @ksig->ka.sa.sa_flags.  Tracing is notified.
  */
-void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka,
-                       struct pt_regs *regs, int stepping)
+static void signal_delivered(struct ksignal *ksig, int stepping)
 {
        sigset_t blocked;
 
@@ -2379,11 +2376,11 @@ void signal_delivered(int sig, siginfo_t *info, struct k_sigaction *ka,
           simply clear the restore sigmask flag.  */
        clear_restore_sigmask();
 
-       sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
-       if (!(ka->sa.sa_flags & SA_NODEFER))
-               sigaddset(&blocked, sig);
+       sigorsets(&blocked, &current->blocked, &ksig->ka.sa.sa_mask);
+       if (!(ksig->ka.sa.sa_flags & SA_NODEFER))
+               sigaddset(&blocked, ksig->sig);
        set_current_blocked(&blocked);
-       tracehook_signal_handler(sig, info, ka, regs, stepping);
+       tracehook_signal_handler(stepping);
 }
 
 void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
@@ -2391,8 +2388,7 @@ void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
        if (failed)
                force_sigsegv(ksig->sig, current);
        else
-               signal_delivered(ksig->sig, &ksig->info, &ksig->ka,
-                       signal_pt_regs(), stepping);
+               signal_delivered(ksig, stepping);
 }
 
 /*