most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set
[pandora-kernel.git] / arch / m68k / kernel / signal.c
index 1747c70..c00caad 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/tty.h>
 #include <linux/binfmts.h>
 #include <linux/module.h>
+#include <linux/tracehook.h>
 
 #include <asm/setup.h>
 #include <asm/uaccess.h>
@@ -50,8 +51,6 @@
 #include <asm/traps.h>
 #include <asm/ucontext.h>
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
 #ifdef CONFIG_MMU
 
 /*
@@ -230,18 +229,9 @@ static inline void push_cache(unsigned long vaddr)
 asmlinkage int
 sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
 {
-       mask &= _BLOCKABLE;
-       spin_lock_irq(&current->sighand->siglock);
-       current->saved_sigmask = current->blocked;
-       siginitset(&current->blocked, mask);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-
-       current->state = TASK_INTERRUPTIBLE;
-       schedule();
-       set_restore_sigmask();
-
-       return -ERESTARTNOHAND;
+       sigset_t blocked;
+       siginitset(&blocked, mask);
+       return sigsuspend(&blocked);
 }
 
 asmlinkage int
@@ -803,9 +793,7 @@ asmlinkage int do_sigreturn(unsigned long __unused)
                              sizeof(frame->extramask))))
                goto badframe;
 
-       sigdelsetmask(&set, ~_BLOCKABLE);
-       current->blocked = set;
-       recalc_sigpending();
+       set_current_blocked(&set);
 
        if (restore_sigcontext(regs, &frame->sc, frame + 1))
                goto badframe;
@@ -829,9 +817,7 @@ asmlinkage int do_rt_sigreturn(unsigned long __unused)
        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
                goto badframe;
 
-       sigdelsetmask(&set, ~_BLOCKABLE);
-       current->blocked = set;
-       recalc_sigpending();
+       set_current_blocked(&set);
 
        if (rt_restore_ucontext(regs, sw, &frame->uc))
                goto badframe;
@@ -1133,8 +1119,9 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
  */
 static void
 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
-             sigset_t *oldset, struct pt_regs *regs)
+             struct pt_regs *regs)
 {
+       sigset_t *oldset = sigmask_to_save();
        int err;
        /* are we from a system call? */
        if (regs->orig_d0 >= 0)
@@ -1150,17 +1137,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
        if (err)
                return;
 
-       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-       if (!(ka->sa.sa_flags & SA_NODEFER))
-               sigaddset(&current->blocked,sig);
-       recalc_sigpending();
+       block_sigmask(ka, sig);
 
        if (test_thread_flag(TIF_DELAYED_TRACE)) {
                regs->sr &= ~0x8000;
                send_sig(SIGTRAP, current, 1);
        }
-
-       clear_thread_flag(TIF_RESTORE_SIGMASK);
 }
 
 /*
@@ -1168,24 +1150,18 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
  */
-asmlinkage void do_signal(struct pt_regs *regs)
+static void do_signal(struct pt_regs *regs)
 {
        siginfo_t info;
        struct k_sigaction ka;
        int signr;
-       sigset_t *oldset;
 
        current->thread.esp0 = (unsigned long) regs;
 
-       if (test_thread_flag(TIF_RESTORE_SIGMASK))
-               oldset = &current->saved_sigmask;
-       else
-               oldset = &current->blocked;
-
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
                /* Whee!  Actually deliver the signal.  */
-               handle_signal(signr, &ka, &info, oldset, regs);
+               handle_signal(signr, &ka, &info, regs);
                return;
        }
 
@@ -1195,8 +1171,14 @@ asmlinkage void do_signal(struct pt_regs *regs)
                handle_restart(regs, NULL, 0);
 
        /* If there's no signal to deliver, we just restore the saved mask.  */
-       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-               clear_thread_flag(TIF_RESTORE_SIGMASK);
-               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
-       }
+       restore_saved_sigmask();
+}
+
+void do_notify_resume(struct pt_regs *regs)
+{
+       if (test_thread_flag(TIF_SIGPENDING))
+               do_signal(regs);
+
+       if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME))
+               tracehook_notify_resume(regs);
 }