most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set
[pandora-kernel.git] / arch / s390 / kernel / signal.c
index 8a4e2b7..8332a69 100644 (file)
@@ -33,9 +33,6 @@
 #include <asm/switch_to.h>
 #include "entry.h"
 
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-
 typedef struct 
 {
        __u8 callee_used_stack[__SIGNAL_FRAMESIZE];
@@ -59,15 +56,8 @@ typedef struct
 SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
 {
        sigset_t blocked;
-
-       current->saved_sigmask = current->blocked;
-       mask &= _BLOCKABLE;
        siginitset(&blocked, mask);
-       set_current_blocked(&blocked);
-       set_current_state(TASK_INTERRUPTIBLE);
-       schedule();
-       set_restore_sigmask();
-       return -ERESTARTNOHAND;
+       return sigsuspend(&blocked);
 }
 
 SYSCALL_DEFINE3(sigaction, int, sig, const struct old_sigaction __user *, act,
@@ -176,7 +166,6 @@ SYSCALL_DEFINE0(sigreturn)
                goto badframe;
        if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE))
                goto badframe;
-       sigdelsetmask(&set, ~_BLOCKABLE);
        set_current_blocked(&set);
        if (restore_sigregs(regs, &frame->sregs))
                goto badframe;
@@ -196,7 +185,6 @@ SYSCALL_DEFINE0(rt_sigreturn)
                goto badframe;
        if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set)))
                goto badframe;
-       sigdelsetmask(&set, ~_BLOCKABLE);
        set_current_blocked(&set);
        if (restore_sigregs(regs, &frame->uc.uc_mcontext))
                goto badframe;
@@ -374,7 +362,7 @@ give_sigsegv:
        return -EFAULT;
 }
 
-static int handle_signal(unsigned long sig, struct k_sigaction *ka,
+static void handle_signal(unsigned long sig, struct k_sigaction *ka,
                         siginfo_t *info, sigset_t *oldset,
                         struct pt_regs *regs)
 {
@@ -386,9 +374,13 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka,
        else
                ret = setup_frame(sig, ka, oldset, regs);
        if (ret)
-               return ret;
+               return;
        block_sigmask(ka, sig);
-       return 0;
+       /*
+        * Let tracing know that we've done the handler setup.
+        */
+       tracehook_signal_handler(sig, info, ka, regs,
+                                test_thread_flag(TIF_SINGLE_STEP));
 }
 
 /*
@@ -405,12 +397,7 @@ void do_signal(struct pt_regs *regs)
        siginfo_t info;
        int signr;
        struct k_sigaction ka;
-       sigset_t *oldset;
-
-       if (test_thread_flag(TIF_RESTORE_SIGMASK))
-               oldset = &current->saved_sigmask;
-       else
-               oldset = &current->blocked;
+       sigset_t *oldset = sigmask_to_save();
 
        /*
         * Get signal to deliver. When running under ptrace, at this point
@@ -448,24 +435,10 @@ void do_signal(struct pt_regs *regs)
                /* No longer in a system call */
                clear_thread_flag(TIF_SYSCALL);
 
-               if ((is_compat_task() ?
-                    handle_signal32(signr, &ka, &info, oldset, regs) :
-                    handle_signal(signr, &ka, &info, oldset, regs)) == 0) {
-                       /*
-                        * A signal was successfully delivered; the saved
-                        * sigmask will have been stored in the signal frame,
-                        * and will be restored by sigreturn, so we can simply
-                        * clear the TIF_RESTORE_SIGMASK flag.
-                        */
-                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
-                               clear_thread_flag(TIF_RESTORE_SIGMASK);
-
-                       /*
-                        * Let tracing know that we've done the handler setup.
-                        */
-                       tracehook_signal_handler(signr, &info, &ka, regs,
-                                        test_thread_flag(TIF_SINGLE_STEP));
-               }
+               if (is_compat_task())
+                       handle_signal32(signr, &ka, &info, oldset, regs);
+               else
+                       handle_signal(signr, &ka, &info, oldset, regs);
                return;
        }
 
@@ -491,16 +464,11 @@ void do_signal(struct pt_regs *regs)
        /*
         * If there's no signal to deliver, we just put the saved sigmask back.
         */
-       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)
 {
        clear_thread_flag(TIF_NOTIFY_RESUME);
        tracehook_notify_resume(regs);
-       if (current->replacement_session_keyring)
-               key_replace_session_keyring();
 }