Merge branch 'akpm'
[linux-2.6/next.git] / arch / m68k / kernel / signal_no.c
blob33e8bf5d61083653c574295335d6e2e019a3446b
1 /*
2 * linux/arch/m68knommu/kernel/signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
12 * Linux/m68k support by Hamish Macdonald
14 * 68060 fixes by Jesper Skov
16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
18 * mathemu support by Roman Zippel
19 * (Note: fpstate in the signal context is completely ignored for the emulator
20 * and the internal floating point format is put on stack)
24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
25 * Atari :-) Current limitation: Only one sigstack can be active at one time.
26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
28 * signal handlers!
31 #include <linux/sched.h>
32 #include <linux/mm.h>
33 #include <linux/kernel.h>
34 #include <linux/signal.h>
35 #include <linux/syscalls.h>
36 #include <linux/errno.h>
37 #include <linux/wait.h>
38 #include <linux/ptrace.h>
39 #include <linux/unistd.h>
40 #include <linux/stddef.h>
41 #include <linux/highuid.h>
42 #include <linux/tty.h>
43 #include <linux/personality.h>
44 #include <linux/binfmts.h>
46 #include <asm/setup.h>
47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h>
49 #include <asm/traps.h>
50 #include <asm/ucontext.h>
52 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
54 void ret_from_user_signal(void);
55 void ret_from_user_rt_signal(void);
58 * Atomically swap in the new signal mask, and wait for a signal.
60 asmlinkage int
61 sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
63 sigset_t blocked;
65 current->saved_sigmask = current->blocked;
67 mask &= _BLOCKABLE;
68 siginitset(&blocked, mask);
69 set_current_blocked(&blocked);
71 current->state = TASK_INTERRUPTIBLE;
72 schedule();
73 set_restore_sigmask();
75 return -ERESTARTNOHAND;
78 asmlinkage int
79 sys_sigaction(int sig, const struct old_sigaction __user *act,
80 struct old_sigaction __user *oact)
82 struct k_sigaction new_ka, old_ka;
83 int ret;
85 if (act) {
86 old_sigset_t mask;
87 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
88 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
89 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
90 __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
91 __get_user(mask, &act->sa_mask))
92 return -EFAULT;
93 siginitset(&new_ka.sa.sa_mask, mask);
96 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
98 if (!ret && oact) {
99 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
100 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
101 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
102 __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
103 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
104 return -EFAULT;
107 return ret;
110 asmlinkage int
111 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
113 return do_sigaltstack(uss, uoss, rdusp());
118 * Do a signal return; undo the signal stack.
120 * Keep the return code on the stack quadword aligned!
121 * That makes the cache flush below easier.
124 struct sigframe
126 char __user *pretcode;
127 int sig;
128 int code;
129 struct sigcontext __user *psc;
130 char retcode[8];
131 unsigned long extramask[_NSIG_WORDS-1];
132 struct sigcontext sc;
135 struct rt_sigframe
137 char __user *pretcode;
138 int sig;
139 struct siginfo __user *pinfo;
140 void __user *puc;
141 char retcode[8];
142 struct siginfo info;
143 struct ucontext uc;
146 #ifdef CONFIG_FPU
148 static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */
150 static inline int restore_fpu_state(struct sigcontext *sc)
152 int err = 1;
154 if (FPU_IS_EMU) {
155 /* restore registers */
156 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
157 memcpy(current->thread.fp, sc->sc_fpregs, 24);
158 return 0;
161 if (sc->sc_fpstate[0]) {
162 /* Verify the frame format. */
163 if (sc->sc_fpstate[0] != fpu_version)
164 goto out;
166 __asm__ volatile (".chip 68k/68881\n\t"
167 "fmovemx %0,%%fp0-%%fp1\n\t"
168 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
169 ".chip 68k"
170 : /* no outputs */
171 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
173 __asm__ volatile (".chip 68k/68881\n\t"
174 "frestore %0\n\t"
175 ".chip 68k" : : "m" (*sc->sc_fpstate));
176 err = 0;
178 out:
179 return err;
182 #define FPCONTEXT_SIZE 216
183 #define uc_fpstate uc_filler[0]
184 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
185 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
187 static inline int rt_restore_fpu_state(struct ucontext __user *uc)
189 unsigned char fpstate[FPCONTEXT_SIZE];
190 int context_size = 0;
191 fpregset_t fpregs;
192 int err = 1;
194 if (FPU_IS_EMU) {
195 /* restore fpu control register */
196 if (__copy_from_user(current->thread.fpcntl,
197 uc->uc_mcontext.fpregs.f_fpcntl, 12))
198 goto out;
199 /* restore all other fpu register */
200 if (__copy_from_user(current->thread.fp,
201 uc->uc_mcontext.fpregs.f_fpregs, 96))
202 goto out;
203 return 0;
206 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
207 goto out;
208 if (fpstate[0]) {
209 context_size = fpstate[1];
211 /* Verify the frame format. */
212 if (fpstate[0] != fpu_version)
213 goto out;
214 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
215 sizeof(fpregs)))
216 goto out;
217 __asm__ volatile (".chip 68k/68881\n\t"
218 "fmovemx %0,%%fp0-%%fp7\n\t"
219 "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
220 ".chip 68k"
221 : /* no outputs */
222 : "m" (*fpregs.f_fpregs),
223 "m" (*fpregs.f_fpcntl));
225 if (context_size &&
226 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
227 context_size))
228 goto out;
229 __asm__ volatile (".chip 68k/68881\n\t"
230 "frestore %0\n\t"
231 ".chip 68k" : : "m" (*fpstate));
232 err = 0;
234 out:
235 return err;
238 #endif
240 static inline int
241 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp,
242 int *pd0)
244 int formatvec;
245 struct sigcontext context;
246 int err = 0;
248 /* Always make any pending restarted system calls return -EINTR */
249 current_thread_info()->restart_block.fn = do_no_restart_syscall;
251 /* get previous context */
252 if (copy_from_user(&context, usc, sizeof(context)))
253 goto badframe;
255 /* restore passed registers */
256 regs->d1 = context.sc_d1;
257 regs->a0 = context.sc_a0;
258 regs->a1 = context.sc_a1;
259 ((struct switch_stack *)regs - 1)->a5 = context.sc_a5;
260 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
261 regs->pc = context.sc_pc;
262 regs->orig_d0 = -1; /* disable syscall checks */
263 wrusp(context.sc_usp);
264 formatvec = context.sc_formatvec;
265 regs->format = formatvec >> 12;
266 regs->vector = formatvec & 0xfff;
268 #ifdef CONFIG_FPU
269 err = restore_fpu_state(&context);
270 #endif
272 *pd0 = context.sc_d0;
273 return err;
275 badframe:
276 return 1;
279 static inline int
280 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
281 struct ucontext __user *uc, int *pd0)
283 int temp;
284 greg_t __user *gregs = uc->uc_mcontext.gregs;
285 unsigned long usp;
286 int err;
288 /* Always make any pending restarted system calls return -EINTR */
289 current_thread_info()->restart_block.fn = do_no_restart_syscall;
291 err = __get_user(temp, &uc->uc_mcontext.version);
292 if (temp != MCONTEXT_VERSION)
293 goto badframe;
294 /* restore passed registers */
295 err |= __get_user(regs->d0, &gregs[0]);
296 err |= __get_user(regs->d1, &gregs[1]);
297 err |= __get_user(regs->d2, &gregs[2]);
298 err |= __get_user(regs->d3, &gregs[3]);
299 err |= __get_user(regs->d4, &gregs[4]);
300 err |= __get_user(regs->d5, &gregs[5]);
301 err |= __get_user(sw->d6, &gregs[6]);
302 err |= __get_user(sw->d7, &gregs[7]);
303 err |= __get_user(regs->a0, &gregs[8]);
304 err |= __get_user(regs->a1, &gregs[9]);
305 err |= __get_user(regs->a2, &gregs[10]);
306 err |= __get_user(sw->a3, &gregs[11]);
307 err |= __get_user(sw->a4, &gregs[12]);
308 err |= __get_user(sw->a5, &gregs[13]);
309 err |= __get_user(sw->a6, &gregs[14]);
310 err |= __get_user(usp, &gregs[15]);
311 wrusp(usp);
312 err |= __get_user(regs->pc, &gregs[16]);
313 err |= __get_user(temp, &gregs[17]);
314 regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
315 regs->orig_d0 = -1; /* disable syscall checks */
316 regs->format = temp >> 12;
317 regs->vector = temp & 0xfff;
319 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
320 goto badframe;
322 *pd0 = regs->d0;
323 return err;
325 badframe:
326 return 1;
329 asmlinkage int do_sigreturn(unsigned long __unused)
331 struct switch_stack *sw = (struct switch_stack *) &__unused;
332 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
333 unsigned long usp = rdusp();
334 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
335 sigset_t set;
336 int d0;
338 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
339 goto badframe;
340 if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
341 (_NSIG_WORDS > 1 &&
342 __copy_from_user(&set.sig[1], &frame->extramask,
343 sizeof(frame->extramask))))
344 goto badframe;
346 sigdelsetmask(&set, ~_BLOCKABLE);
347 set_current_blocked(&set);
349 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
350 goto badframe;
351 return d0;
353 badframe:
354 force_sig(SIGSEGV, current);
355 return 0;
358 asmlinkage int do_rt_sigreturn(unsigned long __unused)
360 struct switch_stack *sw = (struct switch_stack *) &__unused;
361 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
362 unsigned long usp = rdusp();
363 struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
364 sigset_t set;
365 int d0;
367 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
368 goto badframe;
369 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
370 goto badframe;
372 sigdelsetmask(&set, ~_BLOCKABLE);
373 set_current_blocked(&set);
375 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
376 goto badframe;
377 return d0;
379 badframe:
380 force_sig(SIGSEGV, current);
381 return 0;
384 #ifdef CONFIG_FPU
386 * Set up a signal frame.
389 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
391 if (FPU_IS_EMU) {
392 /* save registers */
393 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
394 memcpy(sc->sc_fpregs, current->thread.fp, 24);
395 return;
398 __asm__ volatile (".chip 68k/68881\n\t"
399 "fsave %0\n\t"
400 ".chip 68k"
401 : : "m" (*sc->sc_fpstate) : "memory");
403 if (sc->sc_fpstate[0]) {
404 fpu_version = sc->sc_fpstate[0];
405 __asm__ volatile (".chip 68k/68881\n\t"
406 "fmovemx %%fp0-%%fp1,%0\n\t"
407 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
408 ".chip 68k"
409 : "=m" (*sc->sc_fpregs),
410 "=m" (*sc->sc_fpcntl)
411 : /* no inputs */
412 : "memory");
416 static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
418 unsigned char fpstate[FPCONTEXT_SIZE];
419 int context_size = 0;
420 int err = 0;
422 if (FPU_IS_EMU) {
423 /* save fpu control register */
424 err |= copy_to_user(uc->uc_mcontext.fpregs.f_pcntl,
425 current->thread.fpcntl, 12);
426 /* save all other fpu register */
427 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
428 current->thread.fp, 96);
429 return err;
432 __asm__ volatile (".chip 68k/68881\n\t"
433 "fsave %0\n\t"
434 ".chip 68k"
435 : : "m" (*fpstate) : "memory");
437 err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
438 if (fpstate[0]) {
439 fpregset_t fpregs;
440 context_size = fpstate[1];
441 fpu_version = fpstate[0];
442 __asm__ volatile (".chip 68k/68881\n\t"
443 "fmovemx %%fp0-%%fp7,%0\n\t"
444 "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
445 ".chip 68k"
446 : "=m" (*fpregs.f_fpregs),
447 "=m" (*fpregs.f_fpcntl)
448 : /* no inputs */
449 : "memory");
450 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
451 sizeof(fpregs));
453 if (context_size)
454 err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
455 context_size);
456 return err;
459 #endif
461 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
462 unsigned long mask)
464 sc->sc_mask = mask;
465 sc->sc_usp = rdusp();
466 sc->sc_d0 = regs->d0;
467 sc->sc_d1 = regs->d1;
468 sc->sc_a0 = regs->a0;
469 sc->sc_a1 = regs->a1;
470 sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5;
471 sc->sc_sr = regs->sr;
472 sc->sc_pc = regs->pc;
473 sc->sc_formatvec = regs->format << 12 | regs->vector;
474 #ifdef CONFIG_FPU
475 save_fpu_state(sc, regs);
476 #endif
479 static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
481 struct switch_stack *sw = (struct switch_stack *)regs - 1;
482 greg_t __user *gregs = uc->uc_mcontext.gregs;
483 int err = 0;
485 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
486 err |= __put_user(regs->d0, &gregs[0]);
487 err |= __put_user(regs->d1, &gregs[1]);
488 err |= __put_user(regs->d2, &gregs[2]);
489 err |= __put_user(regs->d3, &gregs[3]);
490 err |= __put_user(regs->d4, &gregs[4]);
491 err |= __put_user(regs->d5, &gregs[5]);
492 err |= __put_user(sw->d6, &gregs[6]);
493 err |= __put_user(sw->d7, &gregs[7]);
494 err |= __put_user(regs->a0, &gregs[8]);
495 err |= __put_user(regs->a1, &gregs[9]);
496 err |= __put_user(regs->a2, &gregs[10]);
497 err |= __put_user(sw->a3, &gregs[11]);
498 err |= __put_user(sw->a4, &gregs[12]);
499 err |= __put_user(sw->a5, &gregs[13]);
500 err |= __put_user(sw->a6, &gregs[14]);
501 err |= __put_user(rdusp(), &gregs[15]);
502 err |= __put_user(regs->pc, &gregs[16]);
503 err |= __put_user(regs->sr, &gregs[17]);
504 #ifdef CONFIG_FPU
505 err |= rt_save_fpu_state(uc, regs);
506 #endif
507 return err;
510 static inline void __user *
511 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
513 unsigned long usp;
515 /* Default to using normal stack. */
516 usp = rdusp();
518 /* This is the X/Open sanctioned signal stack switching. */
519 if (ka->sa.sa_flags & SA_ONSTACK) {
520 if (!sas_ss_flags(usp))
521 usp = current->sas_ss_sp + current->sas_ss_size;
523 return (void __user *)((usp - frame_size) & -8UL);
526 static int setup_frame (int sig, struct k_sigaction *ka,
527 sigset_t *set, struct pt_regs *regs)
529 struct sigframe __user *frame;
530 struct sigcontext context;
531 int err = 0;
533 frame = get_sigframe(ka, regs, sizeof(*frame));
535 err |= __put_user((current_thread_info()->exec_domain
536 && current_thread_info()->exec_domain->signal_invmap
537 && sig < 32
538 ? current_thread_info()->exec_domain->signal_invmap[sig]
539 : sig),
540 &frame->sig);
542 err |= __put_user(regs->vector, &frame->code);
543 err |= __put_user(&frame->sc, &frame->psc);
545 if (_NSIG_WORDS > 1)
546 err |= copy_to_user(frame->extramask, &set->sig[1],
547 sizeof(frame->extramask));
549 setup_sigcontext(&context, regs, set->sig[0]);
550 err |= copy_to_user (&frame->sc, &context, sizeof(context));
552 /* Set up to return from userspace. */
553 err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
555 if (err)
556 goto give_sigsegv;
558 /* Set up registers for signal handler */
559 wrusp ((unsigned long) frame);
560 regs->pc = (unsigned long) ka->sa.sa_handler;
561 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
562 regs->format = 0x4; /*set format byte to make stack appear modulo 4
563 which it will be when doing the rte */
565 adjust_stack:
566 /* Prepare to skip over the extra stuff in the exception frame. */
567 if (regs->stkadj) {
568 struct pt_regs *tregs =
569 (struct pt_regs *)((ulong)regs + regs->stkadj);
570 #if defined(DEBUG)
571 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
572 #endif
573 /* This must be copied with decreasing addresses to
574 handle overlaps. */
575 tregs->vector = 0;
576 tregs->format = 0;
577 tregs->pc = regs->pc;
578 tregs->sr = regs->sr;
580 return err;
582 give_sigsegv:
583 force_sigsegv(sig, current);
584 goto adjust_stack;
587 static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
588 sigset_t *set, struct pt_regs *regs)
590 struct rt_sigframe __user *frame;
591 int err = 0;
593 frame = get_sigframe(ka, regs, sizeof(*frame));
595 err |= __put_user((current_thread_info()->exec_domain
596 && current_thread_info()->exec_domain->signal_invmap
597 && sig < 32
598 ? current_thread_info()->exec_domain->signal_invmap[sig]
599 : sig),
600 &frame->sig);
601 err |= __put_user(&frame->info, &frame->pinfo);
602 err |= __put_user(&frame->uc, &frame->puc);
603 err |= copy_siginfo_to_user(&frame->info, info);
605 /* Create the ucontext. */
606 err |= __put_user(0, &frame->uc.uc_flags);
607 err |= __put_user(NULL, &frame->uc.uc_link);
608 err |= __put_user((void __user *)current->sas_ss_sp,
609 &frame->uc.uc_stack.ss_sp);
610 err |= __put_user(sas_ss_flags(rdusp()),
611 &frame->uc.uc_stack.ss_flags);
612 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
613 err |= rt_setup_ucontext(&frame->uc, regs);
614 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
616 /* Set up to return from userspace. */
617 err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
619 if (err)
620 goto give_sigsegv;
622 /* Set up registers for signal handler */
623 wrusp ((unsigned long) frame);
624 regs->pc = (unsigned long) ka->sa.sa_handler;
625 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
626 regs->format = 0x4; /*set format byte to make stack appear modulo 4
627 which it will be when doing the rte */
629 adjust_stack:
630 /* Prepare to skip over the extra stuff in the exception frame. */
631 if (regs->stkadj) {
632 struct pt_regs *tregs =
633 (struct pt_regs *)((ulong)regs + regs->stkadj);
634 #if defined(DEBUG)
635 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
636 #endif
637 /* This must be copied with decreasing addresses to
638 handle overlaps. */
639 tregs->vector = 0;
640 tregs->format = 0;
641 tregs->pc = regs->pc;
642 tregs->sr = regs->sr;
644 return err;
646 give_sigsegv:
647 force_sigsegv(sig, current);
648 goto adjust_stack;
651 static inline void
652 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
654 switch (regs->d0) {
655 case -ERESTARTNOHAND:
656 if (!has_handler)
657 goto do_restart;
658 regs->d0 = -EINTR;
659 break;
661 case -ERESTART_RESTARTBLOCK:
662 if (!has_handler) {
663 regs->d0 = __NR_restart_syscall;
664 regs->pc -= 2;
665 break;
667 regs->d0 = -EINTR;
668 break;
670 case -ERESTARTSYS:
671 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
672 regs->d0 = -EINTR;
673 break;
675 /* fallthrough */
676 case -ERESTARTNOINTR:
677 do_restart:
678 regs->d0 = regs->orig_d0;
679 regs->pc -= 2;
680 break;
685 * OK, we're invoking a handler
687 static void
688 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
689 sigset_t *oldset, struct pt_regs *regs)
691 int err;
692 /* are we from a system call? */
693 if (regs->orig_d0 >= 0)
694 /* If so, check system call restarting.. */
695 handle_restart(regs, ka, 1);
697 /* set up the stack frame */
698 if (ka->sa.sa_flags & SA_SIGINFO)
699 err = setup_rt_frame(sig, ka, info, oldset, regs);
700 else
701 err = setup_frame(sig, ka, oldset, regs);
703 if (err)
704 return;
706 block_sigmask(ka, sig);
708 clear_thread_flag(TIF_RESTORE_SIGMASK);
712 * Note that 'init' is a special process: it doesn't get signals it doesn't
713 * want to handle. Thus you cannot kill init even with a SIGKILL even by
714 * mistake.
716 asmlinkage void do_signal(struct pt_regs *regs)
718 struct k_sigaction ka;
719 siginfo_t info;
720 int signr;
721 sigset_t *oldset;
724 * We want the common case to go fast, which
725 * is why we may in certain cases get here from
726 * kernel mode. Just return without doing anything
727 * if so.
729 if (!user_mode(regs))
730 return;
732 if (test_thread_flag(TIF_RESTORE_SIGMASK))
733 oldset = &current->saved_sigmask;
734 else
735 oldset = &current->blocked;
737 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
738 if (signr > 0) {
739 /* Whee! Actually deliver the signal. */
740 handle_signal(signr, &ka, &info, oldset, regs);
741 return;
744 /* Did we come from a system call? */
745 if (regs->orig_d0 >= 0) {
746 /* Restart the system call - no handlers present */
747 handle_restart(regs, NULL, 0);
750 /* If there's no signal to deliver, we just restore the saved mask. */
751 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
752 clear_thread_flag(TIF_RESTORE_SIGMASK);
753 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);