[POWERPC] Consolidate do_signal
[deliverable/linux.git] / arch / powerpc / kernel / signal.c
CommitLineData
22e38f29
BH
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
f478f543 12#include <linux/freezer.h>
22e38f29
BH
13#include <linux/ptrace.h>
14#include <linux/signal.h>
15#include <asm/unistd.h>
16
db277e9a
CH
17#include "signal.h"
18
19
f478f543
CH
20#ifdef CONFIG_PPC64
21static inline int is_32bit_task(void)
22{
23 return test_thread_flag(TIF_32BIT);
24}
25#else
26static inline int is_32bit_task(void)
27{
28 return 1;
29}
30#endif
31
32
db277e9a
CH
33/*
34 * Restore the user process's signal mask
35 */
36void restore_sigmask(sigset_t *set)
37{
38 sigdelsetmask(set, ~_BLOCKABLE);
39 spin_lock_irq(&current->sighand->siglock);
40 current->blocked = *set;
41 recalc_sigpending();
42 spin_unlock_irq(&current->sighand->siglock);
43}
44
f478f543
CH
45static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
46 int has_handler)
22e38f29
BH
47{
48 unsigned long ret = regs->gpr[3];
49 int restart = 1;
50
51 /* syscall ? */
52 if (TRAP(regs) != 0x0C00)
53 return;
54
55 /* error signalled ? */
56 if (!(regs->ccr & 0x10000000))
57 return;
58
59 switch (ret) {
60 case ERESTART_RESTARTBLOCK:
61 case ERESTARTNOHAND:
62 /* ERESTARTNOHAND means that the syscall should only be
63 * restarted if there was no handler for the signal, and since
64 * we only get here if there is a handler, we dont restart.
65 */
66 restart = !has_handler;
67 break;
68 case ERESTARTSYS:
69 /* ERESTARTSYS means to restart the syscall if there is no
70 * handler or the handler was registered with SA_RESTART
71 */
72 restart = !has_handler || (ka->sa.sa_flags & SA_RESTART) != 0;
73 break;
74 case ERESTARTNOINTR:
75 /* ERESTARTNOINTR means that the syscall should be
76 * called again after the signal handler returns.
77 */
78 break;
79 default:
80 return;
81 }
82 if (restart) {
83 if (ret == ERESTART_RESTARTBLOCK)
84 regs->gpr[0] = __NR_restart_syscall;
85 else
86 regs->gpr[3] = regs->orig_gpr3;
87 regs->nip -= 4;
88 regs->result = 0;
89 } else {
90 regs->result = -EINTR;
91 regs->gpr[3] = EINTR;
92 regs->ccr |= 0x10000000;
93 }
94}
69d15f6b 95
f478f543
CH
96int do_signal(sigset_t *oldset, struct pt_regs *regs)
97{
98 siginfo_t info;
99 int signr;
100 struct k_sigaction ka;
101 int ret;
102 int is32 = is_32bit_task();
103
104#ifdef CONFIG_PPC32
105 if (try_to_freeze()) {
106 signr = 0;
107 if (!signal_pending(current))
108 goto no_signal;
109 }
110#endif
111
112 if (test_thread_flag(TIF_RESTORE_SIGMASK))
113 oldset = &current->saved_sigmask;
114 else if (!oldset)
115 oldset = &current->blocked;
116
117 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
118
119#ifdef CONFIG_PPC32
120no_signal:
121#endif
122 /* Is there any syscall restart business here ? */
123 check_syscall_restart(regs, &ka, signr > 0);
124
125 if (signr <= 0) {
126 /* No signal to deliver -- put the saved sigmask back */
127 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
128 clear_thread_flag(TIF_RESTORE_SIGMASK);
129 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
130 }
131 return 0; /* no signals delivered */
132 }
133
134#ifdef CONFIG_PPC64
135 /*
136 * Reenable the DABR before delivering the signal to
137 * user space. The DABR will have been cleared if it
138 * triggered inside the kernel.
139 */
140 if (current->thread.dabr)
141 set_dabr(current->thread.dabr);
142#endif
143
144 if (is32) {
145 unsigned int newsp;
146
147 if ((ka.sa.sa_flags & SA_ONSTACK) &&
148 current->sas_ss_size && !on_sig_stack(regs->gpr[1]))
149 newsp = current->sas_ss_sp + current->sas_ss_size;
150 else
151 newsp = regs->gpr[1];
152
153 if (ka.sa.sa_flags & SA_SIGINFO)
154 ret = handle_rt_signal32(signr, &ka, &info, oldset,
155 regs, newsp);
156 else
157 ret = handle_signal32(signr, &ka, &info, oldset,
158 regs, newsp);
159#ifdef CONFIG_PPC64
160 } else {
161 ret = handle_rt_signal64(signr, &ka, &info, oldset, regs);
162#endif
163 }
164
165 if (ret) {
166 spin_lock_irq(&current->sighand->siglock);
167 sigorsets(&current->blocked, &current->blocked,
168 &ka.sa.sa_mask);
169 if (!(ka.sa.sa_flags & SA_NODEFER))
170 sigaddset(&current->blocked, signr);
171 recalc_sigpending();
172 spin_unlock_irq(&current->sighand->siglock);
173
174 /*
175 * A signal was successfully delivered; the saved sigmask is in
176 * its frame, and we can clear the TIF_RESTORE_SIGMASK flag.
177 */
178 if (test_thread_flag(TIF_RESTORE_SIGMASK))
179 clear_thread_flag(TIF_RESTORE_SIGMASK);
180 }
181
182 return ret;
183}
184
69d15f6b
CH
185long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
186 unsigned long r5, unsigned long r6, unsigned long r7,
187 unsigned long r8, struct pt_regs *regs)
188{
189 return do_sigaltstack(uss, uoss, regs->gpr[1]);
190}
This page took 0.031892 seconds and 5 git commands to generate.