blob: f1e7d2aa25866280c7c0b1001decc4b09ee39bac [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/arch/alpha/kernel/signal.c
3 *
4 * Copyright (C) 1995 Linus Torvalds
5 *
6 * 1997-11-02 Modified for POSIX.1b signals by Richard Henderson
7 */
8
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/signal.h>
12#include <linux/errno.h>
13#include <linux/wait.h>
14#include <linux/ptrace.h>
15#include <linux/unistd.h>
16#include <linux/mm.h>
17#include <linux/smp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <linux/stddef.h>
19#include <linux/tty.h>
20#include <linux/binfmts.h>
21#include <linux/bitops.h>
Ivan Kokshayskye5d9a902009-01-29 14:25:18 -080022#include <linux/syscalls.h>
David Howells733e5e42009-09-09 08:30:21 +010023#include <linux/tracehook.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024
25#include <asm/uaccess.h>
26#include <asm/sigcontext.h>
27#include <asm/ucontext.h>
28
29#include "proto.h"
30
31
32#define DEBUG_SIG 0
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36asmlinkage void ret_from_sys_call(void);
Linus Torvalds1da177e2005-04-16 15:20:36 -070037
38/*
39 * The OSF/1 sigprocmask calling sequence is different from the
40 * C sigprocmask() sequence..
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 */
Al Viroc52c2dd2010-09-26 19:28:12 +010042SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
Al Viroc52c2dd2010-09-26 19:28:12 +010044 sigset_t oldmask;
45 sigset_t mask;
46 unsigned long res;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
Linus Torvalds87400e52010-09-30 08:37:38 -070048 siginitset(&mask, newmask & _BLOCKABLE);
Linus Torvalds0f44fbd2010-09-28 13:26:57 -070049 res = sigprocmask(how, &mask, &oldmask);
Al Viroc52c2dd2010-09-26 19:28:12 +010050 if (!res) {
51 force_successful_syscall_return();
Linus Torvalds0f44fbd2010-09-28 13:26:57 -070052 res = oldmask.sig[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -070053 }
Al Viroc52c2dd2010-09-26 19:28:12 +010054 return res;
Linus Torvalds1da177e2005-04-16 15:20:36 -070055}
56
Ivan Kokshayskye5d9a902009-01-29 14:25:18 -080057SYSCALL_DEFINE3(osf_sigaction, int, sig,
58 const struct osf_sigaction __user *, act,
59 struct osf_sigaction __user *, oact)
Linus Torvalds1da177e2005-04-16 15:20:36 -070060{
61 struct k_sigaction new_ka, old_ka;
62 int ret;
63
64 if (act) {
65 old_sigset_t mask;
66 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
67 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
Al Viro18e6bfa2010-09-26 19:28:22 +010068 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
69 __get_user(mask, &act->sa_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070071 siginitset(&new_ka.sa.sa_mask, mask);
72 new_ka.ka_restorer = NULL;
73 }
74
75 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
76
77 if (!ret && oact) {
78 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
79 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
Al Viro18e6bfa2010-09-26 19:28:22 +010080 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
81 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 }
84
85 return ret;
86}
87
Ivan Kokshayskye5d9a902009-01-29 14:25:18 -080088SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
89 struct sigaction __user *, oact,
90 size_t, sigsetsize, void __user *, restorer)
Linus Torvalds1da177e2005-04-16 15:20:36 -070091{
92 struct k_sigaction new_ka, old_ka;
93 int ret;
94
95 /* XXX: Don't preclude handling different sized sigset_t's. */
96 if (sigsetsize != sizeof(sigset_t))
97 return -EINVAL;
98
99 if (act) {
100 new_ka.ka_restorer = restorer;
101 if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
102 return -EFAULT;
103 }
104
105 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
106
107 if (!ret && oact) {
108 if (copy_to_user(oact, &old_ka.sa, sizeof(*oact)))
109 return -EFAULT;
110 }
111
112 return ret;
113}
114
115/*
116 * Atomically swap in the new signal mask, and wait for a signal.
117 */
Al Viro392fb6e2010-09-18 08:40:07 -0400118SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119{
Matt Fleming2561b062012-04-05 14:25:12 -0700120 sigset_t blocked;
Matt Fleming2561b062012-04-05 14:25:12 -0700121 siginitset(&blocked, mask);
Al Viro68f3f162012-05-21 21:42:32 -0400122 return sigsuspend(&blocked);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123}
124
125asmlinkage int
126sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
127{
128 return do_sigaltstack(uss, uoss, rdusp());
129}
130
131/*
132 * Do a signal return; undo the signal stack.
133 */
134
135#if _NSIG_WORDS > 1
136# error "Non SA_SIGINFO frame needs rearranging"
137#endif
138
139struct sigframe
140{
141 struct sigcontext sc;
142 unsigned int retcode[3];
143};
144
145struct rt_sigframe
146{
147 struct siginfo info;
148 struct ucontext uc;
149 unsigned int retcode[3];
150};
151
152/* If this changes, userland unwinders that Know Things about our signal
153 frame will break. Do not undertake lightly. It also implies an ABI
154 change wrt the size of siginfo_t, which may cause some pain. */
155extern char compile_time_assert
156 [offsetof(struct rt_sigframe, uc.uc_mcontext) == 176 ? 1 : -1];
157
158#define INSN_MOV_R30_R16 0x47fe0410
159#define INSN_LDI_R0 0x201f0000
160#define INSN_CALLSYS 0x00000083
161
162static long
163restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
164 struct switch_stack *sw)
165{
166 unsigned long usp;
167 long i, err = __get_user(regs->pc, &sc->sc_pc);
168
Al Viro2deba1b2010-09-18 08:38:47 -0400169 current_thread_info()->restart_block.fn = do_no_restart_syscall;
170
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171 sw->r26 = (unsigned long) ret_from_sys_call;
172
173 err |= __get_user(regs->r0, sc->sc_regs+0);
174 err |= __get_user(regs->r1, sc->sc_regs+1);
175 err |= __get_user(regs->r2, sc->sc_regs+2);
176 err |= __get_user(regs->r3, sc->sc_regs+3);
177 err |= __get_user(regs->r4, sc->sc_regs+4);
178 err |= __get_user(regs->r5, sc->sc_regs+5);
179 err |= __get_user(regs->r6, sc->sc_regs+6);
180 err |= __get_user(regs->r7, sc->sc_regs+7);
181 err |= __get_user(regs->r8, sc->sc_regs+8);
182 err |= __get_user(sw->r9, sc->sc_regs+9);
183 err |= __get_user(sw->r10, sc->sc_regs+10);
184 err |= __get_user(sw->r11, sc->sc_regs+11);
185 err |= __get_user(sw->r12, sc->sc_regs+12);
186 err |= __get_user(sw->r13, sc->sc_regs+13);
187 err |= __get_user(sw->r14, sc->sc_regs+14);
188 err |= __get_user(sw->r15, sc->sc_regs+15);
189 err |= __get_user(regs->r16, sc->sc_regs+16);
190 err |= __get_user(regs->r17, sc->sc_regs+17);
191 err |= __get_user(regs->r18, sc->sc_regs+18);
192 err |= __get_user(regs->r19, sc->sc_regs+19);
193 err |= __get_user(regs->r20, sc->sc_regs+20);
194 err |= __get_user(regs->r21, sc->sc_regs+21);
195 err |= __get_user(regs->r22, sc->sc_regs+22);
196 err |= __get_user(regs->r23, sc->sc_regs+23);
197 err |= __get_user(regs->r24, sc->sc_regs+24);
198 err |= __get_user(regs->r25, sc->sc_regs+25);
199 err |= __get_user(regs->r26, sc->sc_regs+26);
200 err |= __get_user(regs->r27, sc->sc_regs+27);
201 err |= __get_user(regs->r28, sc->sc_regs+28);
202 err |= __get_user(regs->gp, sc->sc_regs+29);
203 err |= __get_user(usp, sc->sc_regs+30);
204 wrusp(usp);
205
206 for (i = 0; i < 31; i++)
207 err |= __get_user(sw->fp[i], sc->sc_fpregs+i);
208 err |= __get_user(sw->fp[31], &sc->sc_fpcr);
209
210 return err;
211}
212
213/* Note that this syscall is also used by setcontext(3) to install
214 a given sigcontext. This because it's impossible to set *all*
215 registers and transfer control from userland. */
216
217asmlinkage void
218do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs,
219 struct switch_stack *sw)
220{
221 sigset_t set;
222
223 /* Verify that it's a good sigcontext before using it */
224 if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
225 goto give_sigsegv;
226 if (__get_user(set.sig[0], &sc->sc_mask))
227 goto give_sigsegv;
228
229 sigdelsetmask(&set, ~_BLOCKABLE);
Matt Fleming2561b062012-04-05 14:25:12 -0700230 set_current_blocked(&set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
232 if (restore_sigcontext(sc, regs, sw))
233 goto give_sigsegv;
234
235 /* Send SIGTRAP if we're single-stepping: */
236 if (ptrace_cancel_bpt (current)) {
237 siginfo_t info;
238
239 info.si_signo = SIGTRAP;
240 info.si_errno = 0;
241 info.si_code = TRAP_BRKPT;
242 info.si_addr = (void __user *) regs->pc;
243 info.si_trapno = 0;
244 send_sig_info(SIGTRAP, &info, current);
245 }
246 return;
247
248give_sigsegv:
249 force_sig(SIGSEGV, current);
250}
251
252asmlinkage void
253do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs,
254 struct switch_stack *sw)
255{
256 sigset_t set;
257
258 /* Verify that it's a good ucontext_t before using it */
259 if (!access_ok(VERIFY_READ, &frame->uc, sizeof(frame->uc)))
260 goto give_sigsegv;
261 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
262 goto give_sigsegv;
263
264 sigdelsetmask(&set, ~_BLOCKABLE);
Matt Fleming2561b062012-04-05 14:25:12 -0700265 set_current_blocked(&set);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266
267 if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
268 goto give_sigsegv;
269
270 /* Send SIGTRAP if we're single-stepping: */
271 if (ptrace_cancel_bpt (current)) {
272 siginfo_t info;
273
274 info.si_signo = SIGTRAP;
275 info.si_errno = 0;
276 info.si_code = TRAP_BRKPT;
277 info.si_addr = (void __user *) regs->pc;
278 info.si_trapno = 0;
279 send_sig_info(SIGTRAP, &info, current);
280 }
281 return;
282
283give_sigsegv:
284 force_sig(SIGSEGV, current);
285}
286
287
288/*
289 * Set up a signal frame.
290 */
291
292static inline void __user *
293get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
294{
Laurent MEYERd09042d2006-06-23 02:05:36 -0700295 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 sp = current->sas_ss_sp + current->sas_ss_size;
297
298 return (void __user *)((sp - frame_size) & -32ul);
299}
300
301static long
302setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
303 struct switch_stack *sw, unsigned long mask, unsigned long sp)
304{
305 long i, err = 0;
306
307 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
308 err |= __put_user(mask, &sc->sc_mask);
309 err |= __put_user(regs->pc, &sc->sc_pc);
310 err |= __put_user(8, &sc->sc_ps);
311
312 err |= __put_user(regs->r0 , sc->sc_regs+0);
313 err |= __put_user(regs->r1 , sc->sc_regs+1);
314 err |= __put_user(regs->r2 , sc->sc_regs+2);
315 err |= __put_user(regs->r3 , sc->sc_regs+3);
316 err |= __put_user(regs->r4 , sc->sc_regs+4);
317 err |= __put_user(regs->r5 , sc->sc_regs+5);
318 err |= __put_user(regs->r6 , sc->sc_regs+6);
319 err |= __put_user(regs->r7 , sc->sc_regs+7);
320 err |= __put_user(regs->r8 , sc->sc_regs+8);
321 err |= __put_user(sw->r9 , sc->sc_regs+9);
322 err |= __put_user(sw->r10 , sc->sc_regs+10);
323 err |= __put_user(sw->r11 , sc->sc_regs+11);
324 err |= __put_user(sw->r12 , sc->sc_regs+12);
325 err |= __put_user(sw->r13 , sc->sc_regs+13);
326 err |= __put_user(sw->r14 , sc->sc_regs+14);
327 err |= __put_user(sw->r15 , sc->sc_regs+15);
328 err |= __put_user(regs->r16, sc->sc_regs+16);
329 err |= __put_user(regs->r17, sc->sc_regs+17);
330 err |= __put_user(regs->r18, sc->sc_regs+18);
331 err |= __put_user(regs->r19, sc->sc_regs+19);
332 err |= __put_user(regs->r20, sc->sc_regs+20);
333 err |= __put_user(regs->r21, sc->sc_regs+21);
334 err |= __put_user(regs->r22, sc->sc_regs+22);
335 err |= __put_user(regs->r23, sc->sc_regs+23);
336 err |= __put_user(regs->r24, sc->sc_regs+24);
337 err |= __put_user(regs->r25, sc->sc_regs+25);
338 err |= __put_user(regs->r26, sc->sc_regs+26);
339 err |= __put_user(regs->r27, sc->sc_regs+27);
340 err |= __put_user(regs->r28, sc->sc_regs+28);
341 err |= __put_user(regs->gp , sc->sc_regs+29);
342 err |= __put_user(sp, sc->sc_regs+30);
343 err |= __put_user(0, sc->sc_regs+31);
344
345 for (i = 0; i < 31; i++)
346 err |= __put_user(sw->fp[i], sc->sc_fpregs+i);
347 err |= __put_user(0, sc->sc_fpregs+31);
348 err |= __put_user(sw->fp[31], &sc->sc_fpcr);
349
350 err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0);
351 err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1);
352 err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2);
353
354 return err;
355}
356
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700357static int
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
359 struct pt_regs *regs, struct switch_stack * sw)
360{
361 unsigned long oldsp, r26, err = 0;
362 struct sigframe __user *frame;
363
364 oldsp = rdusp();
365 frame = get_sigframe(ka, oldsp, sizeof(*frame));
366 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
Al Virocbdfb9f2012-04-22 02:34:42 -0400367 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
369 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
370 if (err)
Al Virocbdfb9f2012-04-22 02:34:42 -0400371 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
373 /* Set up to return from userspace. If provided, use a stub
374 already in userspace. */
375 if (ka->ka_restorer) {
376 r26 = (unsigned long) ka->ka_restorer;
377 } else {
378 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
379 err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);
380 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
381 imb();
382 r26 = (unsigned long) frame->retcode;
383 }
384
385 /* Check that everything was written properly. */
386 if (err)
Al Virocbdfb9f2012-04-22 02:34:42 -0400387 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 /* "Return" to the handler */
390 regs->r26 = r26;
391 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
392 regs->r16 = sig; /* a0: signal number */
393 regs->r17 = 0; /* a1: exception code */
394 regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */
395 wrusp((unsigned long) frame);
396
397#if DEBUG_SIG
398 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
399 current->comm, current->pid, frame, regs->pc, regs->r26);
400#endif
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700401 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402}
403
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700404static int
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
406 sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
407{
408 unsigned long oldsp, r26, err = 0;
409 struct rt_sigframe __user *frame;
410
411 oldsp = rdusp();
412 frame = get_sigframe(ka, oldsp, sizeof(*frame));
413 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
Al Virocbdfb9f2012-04-22 02:34:42 -0400414 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415
416 err |= copy_siginfo_to_user(&frame->info, info);
417
418 /* Create the ucontext. */
419 err |= __put_user(0, &frame->uc.uc_flags);
420 err |= __put_user(0, &frame->uc.uc_link);
421 err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
422 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
423 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
424 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
425 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw,
426 set->sig[0], oldsp);
427 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
428 if (err)
Al Virocbdfb9f2012-04-22 02:34:42 -0400429 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430
431 /* Set up to return from userspace. If provided, use a stub
432 already in userspace. */
433 if (ka->ka_restorer) {
434 r26 = (unsigned long) ka->ka_restorer;
435 } else {
436 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
437 err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,
438 frame->retcode+1);
439 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
440 imb();
441 r26 = (unsigned long) frame->retcode;
442 }
443
444 if (err)
Al Virocbdfb9f2012-04-22 02:34:42 -0400445 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446
447 /* "Return" to the handler */
448 regs->r26 = r26;
449 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
450 regs->r16 = sig; /* a0: signal number */
451 regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */
452 regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */
453 wrusp((unsigned long) frame);
454
455#if DEBUG_SIG
456 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
457 current->comm, current->pid, frame, regs->pc, regs->r26);
458#endif
459
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700460 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461}
462
463
464/*
465 * OK, we're invoking a handler.
466 */
Al Virocbdfb9f2012-04-22 02:34:42 -0400467static inline void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
Al Virocbdfb9f2012-04-22 02:34:42 -0400469 struct pt_regs * regs, struct switch_stack *sw)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470{
Al Virob7f9a112012-05-02 09:59:21 -0400471 sigset_t *oldset = sigmask_to_save();
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700472 int ret;
473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 if (ka->sa.sa_flags & SA_SIGINFO)
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700475 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 else
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700477 ret = setup_frame(sig, ka, oldset, regs, sw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
Al Virocbdfb9f2012-04-22 02:34:42 -0400479 if (ret) {
480 force_sigsegv(sig, current);
481 return;
482 }
483 block_sigmask(ka, sig);
484 /* A signal was successfully delivered, and the
485 saved sigmask was stored on the signal frame,
486 and will be restored by sigreturn. So we can
487 simply clear the restore sigmask flag. */
488 clear_thread_flag(TIF_RESTORE_SIGMASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489}
490
491static inline void
492syscall_restart(unsigned long r0, unsigned long r19,
493 struct pt_regs *regs, struct k_sigaction *ka)
494{
495 switch (regs->r0) {
496 case ERESTARTSYS:
497 if (!(ka->sa.sa_flags & SA_RESTART)) {
498 case ERESTARTNOHAND:
499 regs->r0 = EINTR;
500 break;
501 }
502 /* fallthrough */
503 case ERESTARTNOINTR:
504 regs->r0 = r0; /* reset v0 and a3 and replay syscall */
505 regs->r19 = r19;
506 regs->pc -= 4;
507 break;
508 case ERESTART_RESTARTBLOCK:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 regs->r0 = EINTR;
510 break;
511 }
512}
513
514
515/*
516 * Note that 'init' is a special process: it doesn't get signals it doesn't
517 * want to handle. Thus you cannot kill init even with a SIGKILL even by
518 * mistake.
519 *
520 * Note that we go through the signals twice: once to check the signals that
521 * the kernel can handle, and then we build all the user-level signal handling
522 * stack-frames in one go after that.
523 *
524 * "r0" and "r19" are the registers we need to restore for system call
525 * restart. "r0" is also used as an indicator whether we can restart at
526 * all (if we get here from anything but a syscall return, it will be 0)
527 */
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700528static void
529do_signal(struct pt_regs * regs, struct switch_stack * sw,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 unsigned long r0, unsigned long r19)
531{
532 siginfo_t info;
533 int signr;
534 unsigned long single_stepping = ptrace_cancel_bpt(current);
535 struct k_sigaction ka;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536
537 /* This lets the debugger run, ... */
538 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700539
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 /* ... so re-check the single stepping. */
541 single_stepping |= ptrace_cancel_bpt(current);
542
543 if (signr > 0) {
544 /* Whee! Actually deliver the signal. */
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700545 if (r0)
546 syscall_restart(r0, r19, regs, &ka);
Al Virocbdfb9f2012-04-22 02:34:42 -0400547 handle_signal(signr, &ka, &info, regs, sw);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 if (single_stepping)
549 ptrace_set_bpt(current); /* re-set bpt */
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700550 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 }
552
553 if (r0) {
554 switch (regs->r0) {
555 case ERESTARTNOHAND:
556 case ERESTARTSYS:
557 case ERESTARTNOINTR:
558 /* Reset v0 and a3 and replay syscall. */
559 regs->r0 = r0;
560 regs->r19 = r19;
561 regs->pc -= 4;
562 break;
563 case ERESTART_RESTARTBLOCK:
564 /* Force v0 to the restart syscall and reply. */
565 regs->r0 = __NR_restart_syscall;
566 regs->pc -= 4;
567 break;
568 }
569 }
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700570
571 /* If there's no signal to deliver, we just restore the saved mask. */
Al Viro51a7b442012-05-21 23:33:55 -0400572 restore_saved_sigmask();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 if (single_stepping)
574 ptrace_set_bpt(current); /* re-set breakpoint */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575}
576
577void
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700578do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
579 unsigned long thread_info_flags,
580 unsigned long r0, unsigned long r19)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581{
Al Virocbdfb9f2012-04-22 02:34:42 -0400582 if (thread_info_flags & _TIF_SIGPENDING)
Richard Hendersonb927b3e2007-05-29 16:03:28 -0700583 do_signal(regs, sw, r0, r19);
David Howellsd0420c82009-09-02 09:14:16 +0100584
585 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
586 clear_thread_flag(TIF_NOTIFY_RESUME);
587 tracehook_notify_resume(regs);
588 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589}