]> err.no Git - linux-2.6/blob - arch/powerpc/kernel/signal.c
[POWERPC] Consolidate restore_sigmask
[linux-2.6] / arch / powerpc / kernel / signal.c
1 /*
2  * Common signal handling code for both 32 and 64 bits
3  *
4  *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Coproration
5  *    Extracted from signal_32.c and signal_64.c
6  *
7  * This file is subject to the terms and conditions of the GNU General
8  * Public License.  See the file README.legal in the main directory of
9  * this archive for more details.
10  */
11
12 #include <linux/ptrace.h>
13 #include <linux/signal.h>
14 #include <asm/unistd.h>
15
16 #include "signal.h"
17
18
19 /*
20  * Restore the user process's signal mask
21  */
22 void restore_sigmask(sigset_t *set)
23 {
24         sigdelsetmask(set, ~_BLOCKABLE);
25         spin_lock_irq(&current->sighand->siglock);
26         current->blocked = *set;
27         recalc_sigpending();
28         spin_unlock_irq(&current->sighand->siglock);
29 }
30
31 void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
32                            int has_handler)
33 {
34         unsigned long ret = regs->gpr[3];
35         int restart = 1;
36
37         /* syscall ? */
38         if (TRAP(regs) != 0x0C00)
39                 return;
40
41         /* error signalled ? */
42         if (!(regs->ccr & 0x10000000))
43                 return;
44
45         switch (ret) {
46         case ERESTART_RESTARTBLOCK:
47         case ERESTARTNOHAND:
48                 /* ERESTARTNOHAND means that the syscall should only be
49                  * restarted if there was no handler for the signal, and since
50                  * we only get here if there is a handler, we dont restart.
51                  */
52                 restart = !has_handler;
53                 break;
54         case ERESTARTSYS:
55                 /* ERESTARTSYS means to restart the syscall if there is no
56                  * handler or the handler was registered with SA_RESTART
57                  */
58                 restart = !has_handler || (ka->sa.sa_flags & SA_RESTART) != 0;
59                 break;
60         case ERESTARTNOINTR:
61                 /* ERESTARTNOINTR means that the syscall should be
62                  * called again after the signal handler returns.
63                  */
64                 break;
65         default:
66                 return;
67         }
68         if (restart) {
69                 if (ret == ERESTART_RESTARTBLOCK)
70                         regs->gpr[0] = __NR_restart_syscall;
71                 else
72                         regs->gpr[3] = regs->orig_gpr3;
73                 regs->nip -= 4;
74                 regs->result = 0;
75         } else {
76                 regs->result = -EINTR;
77                 regs->gpr[3] = EINTR;
78                 regs->ccr |= 0x10000000;
79         }
80 }
81
82 long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
83                 unsigned long r5, unsigned long r6, unsigned long r7,
84                 unsigned long r8, struct pt_regs *regs)
85 {
86         return do_sigaltstack(uss, uoss, regs->gpr[1]);
87 }