KEYS: Add a keyctl to install a process's session keyring on its parent [try #6]
[deliverable/linux.git] / arch / alpha / kernel / signal.c
CommitLineData
1da177e4
LT
1/*
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>
1da177e4
LT
18#include <linux/stddef.h>
19#include <linux/tty.h>
20#include <linux/binfmts.h>
21#include <linux/bitops.h>
e5d9a90c 22#include <linux/syscalls.h>
1da177e4
LT
23
24#include <asm/uaccess.h>
25#include <asm/sigcontext.h>
26#include <asm/ucontext.h>
27
28#include "proto.h"
29
30
31#define DEBUG_SIG 0
32
33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34
35asmlinkage void ret_from_sys_call(void);
b927b3e2
RH
36static void do_signal(struct pt_regs *, struct switch_stack *,
37 unsigned long, unsigned long);
1da177e4
LT
38
39
40/*
41 * The OSF/1 sigprocmask calling sequence is different from the
42 * C sigprocmask() sequence..
43 *
44 * how:
45 * 1 - SIG_BLOCK
46 * 2 - SIG_UNBLOCK
47 * 3 - SIG_SETMASK
48 *
49 * We change the range to -1 .. 1 in order to let gcc easily
50 * use the conditional move instructions.
51 *
52 * Note that we don't need to acquire the kernel lock for SMP
53 * operation, as all of this is local to this thread.
54 */
e5d9a90c
IK
55SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask,
56 struct pt_regs *, regs)
1da177e4
LT
57{
58 unsigned long oldmask = -EINVAL;
59
60 if ((unsigned long)how-1 <= 2) {
61 long sign = how-2; /* -1 .. 1 */
62 unsigned long block, unblock;
63
64 newmask &= _BLOCKABLE;
65 spin_lock_irq(&current->sighand->siglock);
66 oldmask = current->blocked.sig[0];
67
68 unblock = oldmask & ~newmask;
69 block = oldmask | newmask;
70 if (!sign)
71 block = unblock;
72 if (sign <= 0)
73 newmask = block;
74 if (_NSIG_WORDS > 1 && sign > 0)
75 sigemptyset(&current->blocked);
76 current->blocked.sig[0] = newmask;
77 recalc_sigpending();
78 spin_unlock_irq(&current->sighand->siglock);
79
80 regs->r0 = 0; /* special no error return */
81 }
82 return oldmask;
83}
84
e5d9a90c
IK
85SYSCALL_DEFINE3(osf_sigaction, int, sig,
86 const struct osf_sigaction __user *, act,
87 struct osf_sigaction __user *, oact)
1da177e4
LT
88{
89 struct k_sigaction new_ka, old_ka;
90 int ret;
91
92 if (act) {
93 old_sigset_t mask;
94 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
95 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
96 __get_user(new_ka.sa.sa_flags, &act->sa_flags))
97 return -EFAULT;
98 __get_user(mask, &act->sa_mask);
99 siginitset(&new_ka.sa.sa_mask, mask);
100 new_ka.ka_restorer = NULL;
101 }
102
103 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
104
105 if (!ret && oact) {
106 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
107 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
108 __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
109 return -EFAULT;
110 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
111 }
112
113 return ret;
114}
115
e5d9a90c
IK
116SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act,
117 struct sigaction __user *, oact,
118 size_t, sigsetsize, void __user *, restorer)
1da177e4
LT
119{
120 struct k_sigaction new_ka, old_ka;
121 int ret;
122
123 /* XXX: Don't preclude handling different sized sigset_t's. */
124 if (sigsetsize != sizeof(sigset_t))
125 return -EINVAL;
126
127 if (act) {
128 new_ka.ka_restorer = restorer;
129 if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
130 return -EFAULT;
131 }
132
133 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
134
135 if (!ret && oact) {
136 if (copy_to_user(oact, &old_ka.sa, sizeof(*oact)))
137 return -EFAULT;
138 }
139
140 return ret;
141}
142
143/*
144 * Atomically swap in the new signal mask, and wait for a signal.
145 */
146asmlinkage int
147do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
148{
1da177e4
LT
149 mask &= _BLOCKABLE;
150 spin_lock_irq(&current->sighand->siglock);
b927b3e2 151 current->saved_sigmask = current->blocked;
1da177e4
LT
152 siginitset(&current->blocked, mask);
153 recalc_sigpending();
154 spin_unlock_irq(&current->sighand->siglock);
155
156 /* Indicate EINTR on return from any possible signal handler,
157 which will not come back through here, but via sigreturn. */
158 regs->r0 = EINTR;
159 regs->r19 = 1;
160
b927b3e2
RH
161 current->state = TASK_INTERRUPTIBLE;
162 schedule();
163 set_thread_flag(TIF_RESTORE_SIGMASK);
164 return -ERESTARTNOHAND;
1da177e4
LT
165}
166
167asmlinkage int
168do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
169 struct pt_regs *regs, struct switch_stack *sw)
170{
b927b3e2 171 sigset_t set;
1da177e4
LT
172
173 /* XXX: Don't preclude handling different sized sigset_t's. */
174 if (sigsetsize != sizeof(sigset_t))
175 return -EINVAL;
176 if (copy_from_user(&set, uset, sizeof(set)))
177 return -EFAULT;
178
179 sigdelsetmask(&set, ~_BLOCKABLE);
180 spin_lock_irq(&current->sighand->siglock);
b927b3e2 181 current->saved_sigmask = current->blocked;
1da177e4
LT
182 current->blocked = set;
183 recalc_sigpending();
184 spin_unlock_irq(&current->sighand->siglock);
185
186 /* Indicate EINTR on return from any possible signal handler,
187 which will not come back through here, but via sigreturn. */
188 regs->r0 = EINTR;
189 regs->r19 = 1;
190
b927b3e2
RH
191 current->state = TASK_INTERRUPTIBLE;
192 schedule();
193 set_thread_flag(TIF_RESTORE_SIGMASK);
194 return -ERESTARTNOHAND;
1da177e4
LT
195}
196
197asmlinkage int
198sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
199{
200 return do_sigaltstack(uss, uoss, rdusp());
201}
202
203/*
204 * Do a signal return; undo the signal stack.
205 */
206
207#if _NSIG_WORDS > 1
208# error "Non SA_SIGINFO frame needs rearranging"
209#endif
210
211struct sigframe
212{
213 struct sigcontext sc;
214 unsigned int retcode[3];
215};
216
217struct rt_sigframe
218{
219 struct siginfo info;
220 struct ucontext uc;
221 unsigned int retcode[3];
222};
223
224/* If this changes, userland unwinders that Know Things about our signal
225 frame will break. Do not undertake lightly. It also implies an ABI
226 change wrt the size of siginfo_t, which may cause some pain. */
227extern char compile_time_assert
228 [offsetof(struct rt_sigframe, uc.uc_mcontext) == 176 ? 1 : -1];
229
230#define INSN_MOV_R30_R16 0x47fe0410
231#define INSN_LDI_R0 0x201f0000
232#define INSN_CALLSYS 0x00000083
233
234static long
235restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
236 struct switch_stack *sw)
237{
238 unsigned long usp;
239 long i, err = __get_user(regs->pc, &sc->sc_pc);
240
241 sw->r26 = (unsigned long) ret_from_sys_call;
242
243 err |= __get_user(regs->r0, sc->sc_regs+0);
244 err |= __get_user(regs->r1, sc->sc_regs+1);
245 err |= __get_user(regs->r2, sc->sc_regs+2);
246 err |= __get_user(regs->r3, sc->sc_regs+3);
247 err |= __get_user(regs->r4, sc->sc_regs+4);
248 err |= __get_user(regs->r5, sc->sc_regs+5);
249 err |= __get_user(regs->r6, sc->sc_regs+6);
250 err |= __get_user(regs->r7, sc->sc_regs+7);
251 err |= __get_user(regs->r8, sc->sc_regs+8);
252 err |= __get_user(sw->r9, sc->sc_regs+9);
253 err |= __get_user(sw->r10, sc->sc_regs+10);
254 err |= __get_user(sw->r11, sc->sc_regs+11);
255 err |= __get_user(sw->r12, sc->sc_regs+12);
256 err |= __get_user(sw->r13, sc->sc_regs+13);
257 err |= __get_user(sw->r14, sc->sc_regs+14);
258 err |= __get_user(sw->r15, sc->sc_regs+15);
259 err |= __get_user(regs->r16, sc->sc_regs+16);
260 err |= __get_user(regs->r17, sc->sc_regs+17);
261 err |= __get_user(regs->r18, sc->sc_regs+18);
262 err |= __get_user(regs->r19, sc->sc_regs+19);
263 err |= __get_user(regs->r20, sc->sc_regs+20);
264 err |= __get_user(regs->r21, sc->sc_regs+21);
265 err |= __get_user(regs->r22, sc->sc_regs+22);
266 err |= __get_user(regs->r23, sc->sc_regs+23);
267 err |= __get_user(regs->r24, sc->sc_regs+24);
268 err |= __get_user(regs->r25, sc->sc_regs+25);
269 err |= __get_user(regs->r26, sc->sc_regs+26);
270 err |= __get_user(regs->r27, sc->sc_regs+27);
271 err |= __get_user(regs->r28, sc->sc_regs+28);
272 err |= __get_user(regs->gp, sc->sc_regs+29);
273 err |= __get_user(usp, sc->sc_regs+30);
274 wrusp(usp);
275
276 for (i = 0; i < 31; i++)
277 err |= __get_user(sw->fp[i], sc->sc_fpregs+i);
278 err |= __get_user(sw->fp[31], &sc->sc_fpcr);
279
280 return err;
281}
282
283/* Note that this syscall is also used by setcontext(3) to install
284 a given sigcontext. This because it's impossible to set *all*
285 registers and transfer control from userland. */
286
287asmlinkage void
288do_sigreturn(struct sigcontext __user *sc, struct pt_regs *regs,
289 struct switch_stack *sw)
290{
291 sigset_t set;
292
293 /* Verify that it's a good sigcontext before using it */
294 if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
295 goto give_sigsegv;
296 if (__get_user(set.sig[0], &sc->sc_mask))
297 goto give_sigsegv;
298
299 sigdelsetmask(&set, ~_BLOCKABLE);
300 spin_lock_irq(&current->sighand->siglock);
301 current->blocked = set;
302 recalc_sigpending();
303 spin_unlock_irq(&current->sighand->siglock);
304
305 if (restore_sigcontext(sc, regs, sw))
306 goto give_sigsegv;
307
308 /* Send SIGTRAP if we're single-stepping: */
309 if (ptrace_cancel_bpt (current)) {
310 siginfo_t info;
311
312 info.si_signo = SIGTRAP;
313 info.si_errno = 0;
314 info.si_code = TRAP_BRKPT;
315 info.si_addr = (void __user *) regs->pc;
316 info.si_trapno = 0;
317 send_sig_info(SIGTRAP, &info, current);
318 }
319 return;
320
321give_sigsegv:
322 force_sig(SIGSEGV, current);
323}
324
325asmlinkage void
326do_rt_sigreturn(struct rt_sigframe __user *frame, struct pt_regs *regs,
327 struct switch_stack *sw)
328{
329 sigset_t set;
330
331 /* Verify that it's a good ucontext_t before using it */
332 if (!access_ok(VERIFY_READ, &frame->uc, sizeof(frame->uc)))
333 goto give_sigsegv;
334 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
335 goto give_sigsegv;
336
337 sigdelsetmask(&set, ~_BLOCKABLE);
338 spin_lock_irq(&current->sighand->siglock);
339 current->blocked = set;
340 recalc_sigpending();
341 spin_unlock_irq(&current->sighand->siglock);
342
343 if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
344 goto give_sigsegv;
345
346 /* Send SIGTRAP if we're single-stepping: */
347 if (ptrace_cancel_bpt (current)) {
348 siginfo_t info;
349
350 info.si_signo = SIGTRAP;
351 info.si_errno = 0;
352 info.si_code = TRAP_BRKPT;
353 info.si_addr = (void __user *) regs->pc;
354 info.si_trapno = 0;
355 send_sig_info(SIGTRAP, &info, current);
356 }
357 return;
358
359give_sigsegv:
360 force_sig(SIGSEGV, current);
361}
362
363
364/*
365 * Set up a signal frame.
366 */
367
368static inline void __user *
369get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
370{
d09042da 371 if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
1da177e4
LT
372 sp = current->sas_ss_sp + current->sas_ss_size;
373
374 return (void __user *)((sp - frame_size) & -32ul);
375}
376
377static long
378setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
379 struct switch_stack *sw, unsigned long mask, unsigned long sp)
380{
381 long i, err = 0;
382
383 err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
384 err |= __put_user(mask, &sc->sc_mask);
385 err |= __put_user(regs->pc, &sc->sc_pc);
386 err |= __put_user(8, &sc->sc_ps);
387
388 err |= __put_user(regs->r0 , sc->sc_regs+0);
389 err |= __put_user(regs->r1 , sc->sc_regs+1);
390 err |= __put_user(regs->r2 , sc->sc_regs+2);
391 err |= __put_user(regs->r3 , sc->sc_regs+3);
392 err |= __put_user(regs->r4 , sc->sc_regs+4);
393 err |= __put_user(regs->r5 , sc->sc_regs+5);
394 err |= __put_user(regs->r6 , sc->sc_regs+6);
395 err |= __put_user(regs->r7 , sc->sc_regs+7);
396 err |= __put_user(regs->r8 , sc->sc_regs+8);
397 err |= __put_user(sw->r9 , sc->sc_regs+9);
398 err |= __put_user(sw->r10 , sc->sc_regs+10);
399 err |= __put_user(sw->r11 , sc->sc_regs+11);
400 err |= __put_user(sw->r12 , sc->sc_regs+12);
401 err |= __put_user(sw->r13 , sc->sc_regs+13);
402 err |= __put_user(sw->r14 , sc->sc_regs+14);
403 err |= __put_user(sw->r15 , sc->sc_regs+15);
404 err |= __put_user(regs->r16, sc->sc_regs+16);
405 err |= __put_user(regs->r17, sc->sc_regs+17);
406 err |= __put_user(regs->r18, sc->sc_regs+18);
407 err |= __put_user(regs->r19, sc->sc_regs+19);
408 err |= __put_user(regs->r20, sc->sc_regs+20);
409 err |= __put_user(regs->r21, sc->sc_regs+21);
410 err |= __put_user(regs->r22, sc->sc_regs+22);
411 err |= __put_user(regs->r23, sc->sc_regs+23);
412 err |= __put_user(regs->r24, sc->sc_regs+24);
413 err |= __put_user(regs->r25, sc->sc_regs+25);
414 err |= __put_user(regs->r26, sc->sc_regs+26);
415 err |= __put_user(regs->r27, sc->sc_regs+27);
416 err |= __put_user(regs->r28, sc->sc_regs+28);
417 err |= __put_user(regs->gp , sc->sc_regs+29);
418 err |= __put_user(sp, sc->sc_regs+30);
419 err |= __put_user(0, sc->sc_regs+31);
420
421 for (i = 0; i < 31; i++)
422 err |= __put_user(sw->fp[i], sc->sc_fpregs+i);
423 err |= __put_user(0, sc->sc_fpregs+31);
424 err |= __put_user(sw->fp[31], &sc->sc_fpcr);
425
426 err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0);
427 err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1);
428 err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2);
429
430 return err;
431}
432
b927b3e2 433static int
1da177e4
LT
434setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
435 struct pt_regs *regs, struct switch_stack * sw)
436{
437 unsigned long oldsp, r26, err = 0;
438 struct sigframe __user *frame;
439
440 oldsp = rdusp();
441 frame = get_sigframe(ka, oldsp, sizeof(*frame));
442 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
443 goto give_sigsegv;
444
445 err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
446 if (err)
447 goto give_sigsegv;
448
449 /* Set up to return from userspace. If provided, use a stub
450 already in userspace. */
451 if (ka->ka_restorer) {
452 r26 = (unsigned long) ka->ka_restorer;
453 } else {
454 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
455 err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);
456 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
457 imb();
458 r26 = (unsigned long) frame->retcode;
459 }
460
461 /* Check that everything was written properly. */
462 if (err)
463 goto give_sigsegv;
464
465 /* "Return" to the handler */
466 regs->r26 = r26;
467 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
468 regs->r16 = sig; /* a0: signal number */
469 regs->r17 = 0; /* a1: exception code */
470 regs->r18 = (unsigned long) &frame->sc; /* a2: sigcontext pointer */
471 wrusp((unsigned long) frame);
472
473#if DEBUG_SIG
474 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
475 current->comm, current->pid, frame, regs->pc, regs->r26);
476#endif
477
b927b3e2 478 return 0;
1da177e4
LT
479
480give_sigsegv:
481 force_sigsegv(sig, current);
b927b3e2 482 return -EFAULT;
1da177e4
LT
483}
484
b927b3e2 485static int
1da177e4
LT
486setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
487 sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
488{
489 unsigned long oldsp, r26, err = 0;
490 struct rt_sigframe __user *frame;
491
492 oldsp = rdusp();
493 frame = get_sigframe(ka, oldsp, sizeof(*frame));
494 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
495 goto give_sigsegv;
496
497 err |= copy_siginfo_to_user(&frame->info, info);
498
499 /* Create the ucontext. */
500 err |= __put_user(0, &frame->uc.uc_flags);
501 err |= __put_user(0, &frame->uc.uc_link);
502 err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
503 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
504 err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
505 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
506 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw,
507 set->sig[0], oldsp);
508 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
509 if (err)
510 goto give_sigsegv;
511
512 /* Set up to return from userspace. If provided, use a stub
513 already in userspace. */
514 if (ka->ka_restorer) {
515 r26 = (unsigned long) ka->ka_restorer;
516 } else {
517 err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
518 err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,
519 frame->retcode+1);
520 err |= __put_user(INSN_CALLSYS, frame->retcode+2);
521 imb();
522 r26 = (unsigned long) frame->retcode;
523 }
524
525 if (err)
526 goto give_sigsegv;
527
528 /* "Return" to the handler */
529 regs->r26 = r26;
530 regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
531 regs->r16 = sig; /* a0: signal number */
532 regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */
533 regs->r18 = (unsigned long) &frame->uc; /* a2: ucontext pointer */
534 wrusp((unsigned long) frame);
535
536#if DEBUG_SIG
537 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
538 current->comm, current->pid, frame, regs->pc, regs->r26);
539#endif
540
b927b3e2 541 return 0;
1da177e4
LT
542
543give_sigsegv:
544 force_sigsegv(sig, current);
b927b3e2 545 return -EFAULT;
1da177e4
LT
546}
547
548
549/*
550 * OK, we're invoking a handler.
551 */
b927b3e2 552static inline int
1da177e4
LT
553handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
554 sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
555{
b927b3e2
RH
556 int ret;
557
1da177e4 558 if (ka->sa.sa_flags & SA_SIGINFO)
b927b3e2 559 ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
1da177e4 560 else
b927b3e2 561 ret = setup_frame(sig, ka, oldset, regs, sw);
1da177e4 562
b927b3e2
RH
563 if (ret == 0) {
564 spin_lock_irq(&current->sighand->siglock);
565 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
566 if (!(ka->sa.sa_flags & SA_NODEFER))
567 sigaddset(&current->blocked,sig);
568 recalc_sigpending();
569 spin_unlock_irq(&current->sighand->siglock);
570 }
1da177e4 571
b927b3e2 572 return ret;
1da177e4
LT
573}
574
575static inline void
576syscall_restart(unsigned long r0, unsigned long r19,
577 struct pt_regs *regs, struct k_sigaction *ka)
578{
579 switch (regs->r0) {
580 case ERESTARTSYS:
581 if (!(ka->sa.sa_flags & SA_RESTART)) {
582 case ERESTARTNOHAND:
583 regs->r0 = EINTR;
584 break;
585 }
586 /* fallthrough */
587 case ERESTARTNOINTR:
588 regs->r0 = r0; /* reset v0 and a3 and replay syscall */
589 regs->r19 = r19;
590 regs->pc -= 4;
591 break;
592 case ERESTART_RESTARTBLOCK:
593 current_thread_info()->restart_block.fn = do_no_restart_syscall;
594 regs->r0 = EINTR;
595 break;
596 }
597}
598
599
600/*
601 * Note that 'init' is a special process: it doesn't get signals it doesn't
602 * want to handle. Thus you cannot kill init even with a SIGKILL even by
603 * mistake.
604 *
605 * Note that we go through the signals twice: once to check the signals that
606 * the kernel can handle, and then we build all the user-level signal handling
607 * stack-frames in one go after that.
608 *
609 * "r0" and "r19" are the registers we need to restore for system call
610 * restart. "r0" is also used as an indicator whether we can restart at
611 * all (if we get here from anything but a syscall return, it will be 0)
612 */
b927b3e2
RH
613static void
614do_signal(struct pt_regs * regs, struct switch_stack * sw,
1da177e4
LT
615 unsigned long r0, unsigned long r19)
616{
617 siginfo_t info;
618 int signr;
619 unsigned long single_stepping = ptrace_cancel_bpt(current);
620 struct k_sigaction ka;
b927b3e2 621 sigset_t *oldset;
1da177e4 622
b927b3e2
RH
623 if (test_thread_flag(TIF_RESTORE_SIGMASK))
624 oldset = &current->saved_sigmask;
625 else
1da177e4
LT
626 oldset = &current->blocked;
627
628 /* This lets the debugger run, ... */
629 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
b927b3e2 630
1da177e4
LT
631 /* ... so re-check the single stepping. */
632 single_stepping |= ptrace_cancel_bpt(current);
633
634 if (signr > 0) {
635 /* Whee! Actually deliver the signal. */
b927b3e2
RH
636 if (r0)
637 syscall_restart(r0, r19, regs, &ka);
638 if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) {
639 /* A signal was successfully delivered, and the
640 saved sigmask was stored on the signal frame,
641 and will be restored by sigreturn. So we can
642 simply clear the restore sigmask flag. */
643 if (test_thread_flag(TIF_RESTORE_SIGMASK))
644 clear_thread_flag(TIF_RESTORE_SIGMASK);
645 }
1da177e4
LT
646 if (single_stepping)
647 ptrace_set_bpt(current); /* re-set bpt */
b927b3e2 648 return;
1da177e4
LT
649 }
650
651 if (r0) {
652 switch (regs->r0) {
653 case ERESTARTNOHAND:
654 case ERESTARTSYS:
655 case ERESTARTNOINTR:
656 /* Reset v0 and a3 and replay syscall. */
657 regs->r0 = r0;
658 regs->r19 = r19;
659 regs->pc -= 4;
660 break;
661 case ERESTART_RESTARTBLOCK:
662 /* Force v0 to the restart syscall and reply. */
663 regs->r0 = __NR_restart_syscall;
664 regs->pc -= 4;
665 break;
666 }
667 }
b927b3e2
RH
668
669 /* If there's no signal to deliver, we just restore the saved mask. */
670 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
671 clear_thread_flag(TIF_RESTORE_SIGMASK);
672 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
673 }
674
1da177e4
LT
675 if (single_stepping)
676 ptrace_set_bpt(current); /* re-set breakpoint */
1da177e4
LT
677}
678
679void
b927b3e2
RH
680do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
681 unsigned long thread_info_flags,
682 unsigned long r0, unsigned long r19)
1da177e4 683{
b927b3e2
RH
684 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
685 do_signal(regs, sw, r0, r19);
d0420c83
DH
686
687 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
688 clear_thread_flag(TIF_NOTIFY_RESUME);
689 tracehook_notify_resume(regs);
ee18d64c
DH
690 if (current->replacement_session_keyring)
691 key_replace_session_keyring();
d0420c83 692 }
1da177e4 693}
This page took 0.420267 seconds and 5 git commands to generate.