TIF_RESTORE_SIGMASK can be set only when TIF_SIGPENDING is set
[deliverable/linux.git] / arch / parisc / kernel / signal.c
index 12c1ed33dc18b92f1bc4b0f1eaa4b5ee54b0cfc8..7f3c8f2c962d1aa832d12b56e524d1f11fb786f1 100644 (file)
@@ -109,6 +109,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
                sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 #endif
 
+       current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
        /* Unwind the user stack to get the rt_sigframe structure. */
        frame = (struct rt_sigframe __user *)
@@ -131,10 +132,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
        }
                
        sigdelsetmask(&set, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       current->blocked = set;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       set_current_blocked(&set);
 
        /* Good thing we saved the old gr[30], eh? */
 #ifdef CONFIG_64BIT
@@ -445,8 +443,9 @@ give_sigsegv:
 
 static long
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
-               sigset_t *oldset, struct pt_regs *regs, int in_syscall)
+               struct pt_regs *regs, int in_syscall)
 {
+       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);
        
@@ -454,17 +453,15 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
        if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
                return 0;
 
-       spin_lock_irq(&current->sighand->siglock);
-       sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
-       if (!(ka->sa.sa_flags & SA_NODEFER))
-               sigaddset(&current->blocked,sig);
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
+       block_sigmask(ka, sig);
 
        tracehook_signal_handler(sig, info, ka, regs, 
                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]);
+
        return 1;
 }
 
@@ -474,8 +471,6 @@ syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
        /* Check the return code */
        switch (regs->gr[28]) {
        case -ERESTART_RESTARTBLOCK:
-               current_thread_info()->restart_block.fn =
-                       do_no_restart_syscall;
        case -ERESTARTNOHAND:
                DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
                regs->gr[28] = -EINTR;
@@ -577,28 +572,17 @@ do_signal(struct pt_regs *regs, long in_syscall)
        siginfo_t info;
        struct k_sigaction ka;
        int signr;
-       sigset_t *oldset;
 
-       DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
-              oldset, regs, regs->sr[7], in_syscall);
+       DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
+              regs, regs->sr[7], in_syscall);
 
        /* Everyone else checks to see if they are in kernel mode at
           this point and exits if that's the case.  I'm not sure why
           we would be called in that case, but for some reason we
           are. */
 
-       if (test_thread_flag(TIF_RESTORE_SIGMASK))
-               oldset = &current->saved_sigmask;
-       else
-               oldset = &current->blocked;
-
-       DBG(1,"do_signal: oldset %08lx / %08lx\n", 
-               oldset->sig[0], oldset->sig[1]);
-
-
        /* May need to force signal if handle_signal failed to deliver */
        while (1) {
-         
                signr = get_signal_to_deliver(&info, &ka, regs, NULL);
                DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
        
@@ -612,14 +596,8 @@ do_signal(struct pt_regs *regs, 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, &info, &ka, oldset,
-                                 regs, in_syscall)) {
-                       DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
-                               regs->gr[28]);
-                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
-                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               if (handle_signal(signr, &info, &ka, regs, in_syscall))
                        return;
-               }
        }
        /* end of while(1) looping forever if we can't force a signal */
 
@@ -630,24 +608,16 @@ do_signal(struct pt_regs *regs, long in_syscall)
        DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
                regs->gr[28]);
 
-       if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
-               clear_thread_flag(TIF_RESTORE_SIGMASK);
-               sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
-       }
-
-       return;
+       restore_saved_sigmask();
 }
 
 void do_notify_resume(struct pt_regs *regs, long in_syscall)
 {
-       if (test_thread_flag(TIF_SIGPENDING) ||
-           test_thread_flag(TIF_RESTORE_SIGMASK))
+       if (test_thread_flag(TIF_SIGPENDING))
                do_signal(regs, in_syscall);
 
        if (test_thread_flag(TIF_NOTIFY_RESUME)) {
                clear_thread_flag(TIF_NOTIFY_RESUME);
                tracehook_notify_resume(regs);
-               if (current->replacement_session_keyring)
-                       key_replace_session_keyring();
        }
 }
This page took 0.079874 seconds and 5 git commands to generate.