1 /* $Id: signal.c,v 1.56 2001/03/21 11:46:20 davem Exp $
2 * arch/sparc64/kernel/signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
8 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
11 #include <linux/config.h>
12 #include <linux/sched.h>
13 #include <linux/kernel.h>
14 #include <linux/signal.h>
15 #include <linux/errno.h>
16 #include <linux/wait.h>
17 #include <linux/ptrace.h>
18 #include <linux/unistd.h>
20 #include <linux/smp_lock.h>
22 #include <asm/uaccess.h>
23 #include <asm/bitops.h>
24 #include <asm/ptrace.h>
26 #include <asm/pgtable.h>
27 #include <asm/fpumacro.h>
29 #include <asm/siginfo.h>
30 #include <asm/visasm.h>
32 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
34 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
35 unsigned long orig_o0, int ret_from_syscall);
37 /* This turned off for production... */
38 /* #define DEBUG_SIGNALS 1 */
39 /* #define DEBUG_SIGNALS_TRACE 1 */
40 /* #define DEBUG_SIGNALS_MAPS 1 */
42 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
44 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
46 if (from->si_code < 0)
47 return __copy_to_user(to, from, sizeof(siginfo_t));
51 /* If you change siginfo_t structure, please be sure
52 this code is fixed accordingly.
53 It should never copy any pad contained in the structure
54 to avoid security leaks, but must copy the generic
55 3 ints plus the relevant union member. */
56 err = __put_user(*(long *)&from->si_signo, (long *)&to->si_signo);
57 err |= __put_user((short)from->si_code, &to->si_code);
58 switch (from->si_code >> 16) {
60 err |= __put_user(from->si_utime, &to->si_utime);
61 err |= __put_user(from->si_stime, &to->si_stime);
62 case __SI_FAULT >> 16:
64 err |= __put_user(from->si_trapno, &to->si_trapno);
66 err |= __put_user(from->si_addr, &to->si_addr);
68 /* case __SI_RT: This is not generated by the kernel as of now. */
74 /* {set, get}context() needed for 64-bit SparcLinux userland. */
75 asmlinkage void sparc64_set_context(struct pt_regs *regs)
77 struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
78 struct thread_struct *tp = ¤t->thread;
80 unsigned long pc, npc, tstate;
87 (((unsigned long)ucp) & (sizeof(unsigned long)-1)) ||
88 (!__access_ok((unsigned long)ucp, sizeof(*ucp))))
90 grp = &ucp->uc_mcontext.mc_gregs;
91 err = __get_user(pc, &((*grp)[MC_PC]));
92 err |= __get_user(npc, &((*grp)[MC_NPC]));
93 if(err || ((pc | npc) & 3))
95 if(regs->u_regs[UREG_I1]) {
98 if (_NSIG_WORDS == 1) {
99 if (__get_user(set.sig[0], &ucp->uc_sigmask.sig[0]))
102 if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t)))
105 sigdelsetmask(&set, ~_BLOCKABLE);
106 spin_lock_irq(¤t->sigmask_lock);
107 current->blocked = set;
108 recalc_sigpending(current);
109 spin_unlock_irq(¤t->sigmask_lock);
111 if ((tp->flags & SPARC_FLAG_32BIT) != 0) {
117 err |= __get_user(regs->y, &((*grp)[MC_Y]));
118 err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
119 regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
120 regs->tstate |= (tstate & (TSTATE_ICC | TSTATE_XCC));
121 err |= __get_user(regs->u_regs[UREG_G1], (&(*grp)[MC_G1]));
122 err |= __get_user(regs->u_regs[UREG_G2], (&(*grp)[MC_G2]));
123 err |= __get_user(regs->u_regs[UREG_G3], (&(*grp)[MC_G3]));
124 err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
125 err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
126 err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
127 err |= __get_user(regs->u_regs[UREG_G7], (&(*grp)[MC_G7]));
128 err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
129 err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
130 err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
131 err |= __get_user(regs->u_regs[UREG_I3], (&(*grp)[MC_O3]));
132 err |= __get_user(regs->u_regs[UREG_I4], (&(*grp)[MC_O4]));
133 err |= __get_user(regs->u_regs[UREG_I5], (&(*grp)[MC_O5]));
134 err |= __get_user(regs->u_regs[UREG_I6], (&(*grp)[MC_O6]));
135 err |= __get_user(regs->u_regs[UREG_I7], (&(*grp)[MC_O7]));
137 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
138 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
139 err |= __put_user(fp,
140 (&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
141 err |= __put_user(i7,
142 (&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
144 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
146 unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
150 err |= __get_user(fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
152 err |= copy_from_user(fpregs,
153 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs),
154 (sizeof(unsigned int) * 32));
156 err |= copy_from_user(fpregs+16,
157 ((unsigned long *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
158 (sizeof(unsigned int) * 32));
159 err |= __get_user(current->thread.xfsr[0],
160 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
161 err |= __get_user(current->thread.gsr[0],
162 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
163 regs->tstate &= ~TSTATE_PEF;
173 asmlinkage void sparc64_get_context(struct pt_regs *regs)
175 struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
176 struct thread_struct *tp = ¤t->thread;
179 unsigned long fp, i7;
183 synchronize_user_stack();
184 if(tp->w_saved || clear_user(ucp, sizeof(*ucp)))
188 fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
190 fenab = (current->thread.fpsaved[0] & FPRS_FEF);
193 mcp = &ucp->uc_mcontext;
194 grp = &mcp->mc_gregs;
196 /* Skip over the trap instruction, first. */
197 if ((tp->flags & SPARC_FLAG_32BIT) != 0) {
198 regs->tpc = (regs->tnpc & 0xffffffff);
199 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
201 regs->tpc = regs->tnpc;
205 if (_NSIG_WORDS == 1)
206 err |= __put_user(current->blocked.sig[0],
207 (unsigned long *)&ucp->uc_sigmask);
209 err |= __copy_to_user(&ucp->uc_sigmask, ¤t->blocked,
212 err |= __put_user(regs->tstate, &((*grp)[MC_TSTATE]));
213 err |= __put_user(regs->tpc, &((*grp)[MC_PC]));
214 err |= __put_user(regs->tnpc, &((*grp)[MC_NPC]));
215 err |= __put_user(regs->y, &((*grp)[MC_Y]));
216 err |= __put_user(regs->u_regs[UREG_G1], &((*grp)[MC_G1]));
217 err |= __put_user(regs->u_regs[UREG_G2], &((*grp)[MC_G2]));
218 err |= __put_user(regs->u_regs[UREG_G3], &((*grp)[MC_G3]));
219 err |= __put_user(regs->u_regs[UREG_G4], &((*grp)[MC_G4]));
220 err |= __put_user(regs->u_regs[UREG_G5], &((*grp)[MC_G5]));
221 err |= __put_user(regs->u_regs[UREG_G6], &((*grp)[MC_G6]));
222 err |= __put_user(regs->u_regs[UREG_G6], &((*grp)[MC_G7]));
223 err |= __put_user(regs->u_regs[UREG_I0], &((*grp)[MC_O0]));
224 err |= __put_user(regs->u_regs[UREG_I1], &((*grp)[MC_O1]));
225 err |= __put_user(regs->u_regs[UREG_I2], &((*grp)[MC_O2]));
226 err |= __put_user(regs->u_regs[UREG_I3], &((*grp)[MC_O3]));
227 err |= __put_user(regs->u_regs[UREG_I4], &((*grp)[MC_O4]));
228 err |= __put_user(regs->u_regs[UREG_I5], &((*grp)[MC_O5]));
229 err |= __put_user(regs->u_regs[UREG_I6], &((*grp)[MC_O6]));
230 err |= __put_user(regs->u_regs[UREG_I7], &((*grp)[MC_O7]));
232 err |= __get_user(fp,
233 (&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
234 err |= __get_user(i7,
235 (&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
236 err |= __put_user(fp, &(mcp->mc_fp));
237 err |= __put_user(i7, &(mcp->mc_i7));
239 err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab));
241 unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
244 fprs = current->thread.fpsaved[0];
246 err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
247 (sizeof(unsigned int) * 32));
250 ((unsigned long *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
251 (sizeof(unsigned int) * 32));
252 err |= __put_user(current->thread.xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
253 err |= __put_user(current->thread.gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
254 err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
264 struct rt_signal_frame {
265 struct sparc_stackf ss;
268 __siginfo_fpu_t * fpu_save;
271 __siginfo_fpu_t fpu_state;
275 #define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
278 * atomically swap in the new signal mask, and wait for a signal.
279 * This is really tricky on the Sparc, watch out...
281 asmlinkage void _sigpause_common(old_sigset_t set, struct pt_regs *regs)
285 #ifdef CONFIG_SPARC32_COMPAT
286 if (current->thread.flags & SPARC_FLAG_32BIT) {
287 extern asmlinkage void _sigpause32_common(old_sigset_t32,
289 _sigpause32_common(set, regs);
294 spin_lock_irq(¤t->sigmask_lock);
295 saveset = current->blocked;
296 siginitset(¤t->blocked, set);
297 recalc_sigpending(current);
298 spin_unlock_irq(¤t->sigmask_lock);
300 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
301 regs->tpc = (regs->tnpc & 0xffffffff);
302 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
304 regs->tpc = regs->tnpc;
308 /* Condition codes and return value where set here for sigpause,
309 * and so got used by setup_frame, which again causes sigreturn()
313 current->state = TASK_INTERRUPTIBLE;
316 * Return -EINTR and set condition code here,
317 * so the interrupted system call actually returns
320 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
321 regs->u_regs[UREG_I0] = EINTR;
322 if (do_signal(&saveset, regs, 0, 0))
327 asmlinkage void do_sigpause(unsigned int set, struct pt_regs *regs)
329 _sigpause_common(set, regs);
332 asmlinkage void do_sigsuspend(struct pt_regs *regs)
334 _sigpause_common(regs->u_regs[UREG_I0], regs);
337 asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_regs *regs)
339 sigset_t oldset, set;
341 /* XXX: Don't preclude handling different sized sigset_t's. */
342 if (sigsetsize != sizeof(sigset_t)) {
343 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
344 regs->u_regs[UREG_I0] = EINVAL;
347 if (copy_from_user(&set, uset, sizeof(set))) {
348 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
349 regs->u_regs[UREG_I0] = EFAULT;
353 sigdelsetmask(&set, ~_BLOCKABLE);
354 spin_lock_irq(¤t->sigmask_lock);
355 oldset = current->blocked;
356 current->blocked = set;
357 recalc_sigpending(current);
358 spin_unlock_irq(¤t->sigmask_lock);
360 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
361 regs->tpc = (regs->tnpc & 0xffffffff);
362 regs->tnpc = (regs->tnpc + 4) & 0xffffffff;
364 regs->tpc = regs->tnpc;
368 /* Condition codes and return value where set here for sigpause,
369 * and so got used by setup_frame, which again causes sigreturn()
373 current->state = TASK_INTERRUPTIBLE;
376 * Return -EINTR and set condition code here,
377 * so the interrupted system call actually returns
380 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
381 regs->u_regs[UREG_I0] = EINTR;
382 if (do_signal(&oldset, regs, 0, 0))
388 restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
390 unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
394 err = __get_user(fprs, &fpu->si_fprs);
396 regs->tstate &= ~TSTATE_PEF;
398 err |= copy_from_user(fpregs, &fpu->si_float_regs[0],
399 (sizeof(unsigned int) * 32));
401 err |= copy_from_user(fpregs+16, &fpu->si_float_regs[32],
402 (sizeof(unsigned int) * 32));
403 err |= __get_user(current->thread.xfsr[0], &fpu->si_fsr);
404 err |= __get_user(current->thread.gsr[0], &fpu->si_gsr);
405 current->thread.fpsaved[0] |= fprs;
409 void do_rt_sigreturn(struct pt_regs *regs)
411 struct rt_signal_frame *sf;
412 unsigned long tpc, tnpc, tstate;
413 __siginfo_fpu_t *fpu_save;
418 synchronize_user_stack ();
419 sf = (struct rt_signal_frame *)
420 (regs->u_regs [UREG_FP] + STACK_BIAS);
422 /* 1. Make sure we are not getting garbage from the user */
423 if (((unsigned long) sf) & 3)
426 err = get_user(tpc, &sf->regs.tpc);
427 err |= __get_user(tnpc, &sf->regs.tnpc);
428 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
432 err |= ((tpc | tnpc) & 3);
434 /* 2. Restore the state */
435 err |= __get_user(regs->y, &sf->regs.y);
436 err |= __get_user(tstate, &sf->regs.tstate);
437 err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs));
439 /* User can only change condition codes in %tstate. */
440 regs->tstate &= ~(TSTATE_ICC);
441 regs->tstate |= (tstate & TSTATE_ICC);
443 err |= __get_user(fpu_save, &sf->fpu_save);
445 err |= restore_fpu_state(regs, &sf->fpu_state);
447 err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
448 err |= __copy_from_user(&st, &sf->stack, sizeof(stack_t));
456 /* It is more difficult to avoid calling this function than to
457 call it and ignore errors. */
458 do_sigaltstack(&st, NULL, (unsigned long)sf);
460 sigdelsetmask(&set, ~_BLOCKABLE);
461 spin_lock_irq(¤t->sigmask_lock);
462 current->blocked = set;
463 recalc_sigpending(current);
464 spin_unlock_irq(¤t->sigmask_lock);
467 send_sig(SIGSEGV, current, 1);
470 /* Checks if the fp is valid */
471 static int invalid_frame_pointer(void *fp, int fplen)
473 if (((unsigned long) fp) & 7)
479 save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
481 unsigned long *fpregs = (unsigned long *)(regs+1);
485 fprs = current->thread.fpsaved[0];
487 err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
488 (sizeof(unsigned int) * 32));
490 err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
491 (sizeof(unsigned int) * 32));
492 err |= __put_user(current->thread.xfsr[0], &fpu->si_fsr);
493 err |= __put_user(current->thread.gsr[0], &fpu->si_gsr);
494 err |= __put_user(fprs, &fpu->si_fprs);
499 static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
503 sp = regs->u_regs[UREG_FP] + STACK_BIAS;
505 /* This is the X/Open sanctioned signal stack switching. */
506 if (ka->sa.sa_flags & SA_ONSTACK) {
507 if (!on_sig_stack(sp) &&
508 !((current->sas_ss_sp + current->sas_ss_size) & 7))
509 sp = current->sas_ss_sp + current->sas_ss_size;
511 return (void *)(sp - framesize);
515 setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
516 int signo, sigset_t *oldset, siginfo_t *info)
518 struct rt_signal_frame *sf;
519 int sigframe_size, err;
521 /* 1. Make sure everything is clean */
522 synchronize_user_stack();
523 save_and_clear_fpu();
525 sigframe_size = RT_ALIGNEDSZ;
526 if (!(current->thread.fpsaved[0] & FPRS_FEF))
527 sigframe_size -= sizeof(__siginfo_fpu_t);
529 sf = (struct rt_signal_frame *)get_sigframe(ka, regs, sigframe_size);
531 if (invalid_frame_pointer (sf, sigframe_size))
534 if (current->thread.w_saved != 0) {
536 printk ("%s[%d]: Invalid user stack frame for "
537 "signal delivery.\n", current->comm, current->pid);
542 /* 2. Save the current process state */
543 err = copy_to_user(&sf->regs, regs, sizeof (*regs));
545 if (current->thread.fpsaved[0] & FPRS_FEF) {
546 err |= save_fpu_state(regs, &sf->fpu_state);
547 err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
549 err |= __put_user(0, &sf->fpu_save);
552 /* Setup sigaltstack */
553 err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
554 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
555 err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
557 err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
559 err |= copy_in_user((u64 *)sf,
560 (u64 *)(regs->u_regs[UREG_FP]+STACK_BIAS),
561 sizeof(struct reg_window));
564 err |= copy_siginfo_to_user(&sf->info, info);
566 err |= __put_user(signo, &sf->info.si_signo);
567 err |= __put_user(SI_NOINFO, &sf->info.si_code);
572 /* 3. signal handler back-trampoline and parameters */
573 regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
574 regs->u_regs[UREG_I0] = signo;
575 regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
577 /* 5. signal handler */
578 regs->tpc = (unsigned long) ka->sa.sa_handler;
579 regs->tnpc = (regs->tpc + 4);
580 if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) {
581 regs->tpc &= 0xffffffff;
582 regs->tnpc &= 0xffffffff;
584 /* 4. return to kernel instructions */
585 regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
594 static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
596 sigset_t *oldset, struct pt_regs *regs)
598 setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
599 if(ka->sa.sa_flags & SA_ONESHOT)
600 ka->sa.sa_handler = SIG_DFL;
601 if(!(ka->sa.sa_flags & SA_NOMASK)) {
602 spin_lock_irq(¤t->sigmask_lock);
603 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
604 sigaddset(¤t->blocked,signr);
605 recalc_sigpending(current);
606 spin_unlock_irq(¤t->sigmask_lock);
610 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
611 struct sigaction *sa)
613 switch(regs->u_regs[UREG_I0]) {
615 no_system_call_restart:
616 regs->u_regs[UREG_I0] = EINTR;
617 regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
620 if(!(sa->sa_flags & SA_RESTART))
621 goto no_system_call_restart;
624 regs->u_regs[UREG_I0] = orig_i0;
630 #ifdef DEBUG_SIGNALS_MAPS
632 #define MAPS_LINE_FORMAT "%016lx-%016lx %s %016lx %s %lu "
634 static inline void read_maps (void)
636 struct vm_area_struct * map, * next;
640 buffer = (char*)__get_free_page(GFP_KERNEL);
644 for (map = current->mm->mmap ; map ; map = next ) {
645 /* produce the next line */
647 char str[5], *cp = str;
653 * Get the next vma now (but it won't be used if we sleep).
656 flags = map->vm_flags;
658 *cp++ = flags & VM_READ ? 'r' : '-';
659 *cp++ = flags & VM_WRITE ? 'w' : '-';
660 *cp++ = flags & VM_EXEC ? 'x' : '-';
661 *cp++ = flags & VM_MAYSHARE ? 's' : 'p';
666 if (map->vm_file != NULL) {
667 dev = map->vm_file->f_dentry->d_inode->i_dev;
668 ino = map->vm_file->f_dentry->d_inode->i_ino;
669 line = d_path(map->vm_file->f_dentry,
670 map->vm_file->f_vfsmnt,
673 printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
675 if (map->vm_file != NULL)
676 printk("%s\n", line);
680 free_page((unsigned long)buffer);
686 /* Note that 'init' is a special process: it doesn't get signals it doesn't
687 * want to handle. Thus you cannot kill init even with a SIGKILL even by
690 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
691 unsigned long orig_i0, int restart_syscall)
695 struct k_sigaction *ka;
698 oldset = ¤t->blocked;
700 #ifdef CONFIG_SPARC32_COMPAT
701 if (current->thread.flags & SPARC_FLAG_32BIT) {
702 extern asmlinkage int do_signal32(sigset_t *, struct pt_regs *,
704 return do_signal32(oldset, regs, orig_i0, restart_syscall);
708 spin_lock_irq(¤t->sigmask_lock);
709 signr = dequeue_signal(¤t->blocked, &info);
710 spin_unlock_irq(¤t->sigmask_lock);
714 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
715 current->exit_code = signr;
716 current->state = TASK_STOPPED;
717 notify_parent(current, SIGCHLD);
719 if (!(signr = current->exit_code))
721 current->exit_code = 0;
722 if (signr == SIGSTOP)
725 /* Update the siginfo structure. Is this good? */
726 if (signr != info.si_signo) {
727 info.si_signo = signr;
729 info.si_code = SI_USER;
730 info.si_pid = current->p_pptr->pid;
731 info.si_uid = current->p_pptr->uid;
734 /* If the (new) signal is now blocked, requeue it. */
735 if (sigismember(¤t->blocked, signr)) {
736 send_sig_info(signr, &info, current);
741 ka = ¤t->sig->action[signr-1];
743 if(ka->sa.sa_handler == SIG_IGN) {
747 /* sys_wait4() grabs the master kernel lock, so
748 * we need not do so, that sucker should be
749 * threaded and would not be that difficult to
752 while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
756 if(ka->sa.sa_handler == SIG_DFL) {
757 unsigned long exit_code = signr;
759 if(current->pid == 1)
762 case SIGCONT: case SIGCHLD: case SIGWINCH:
765 case SIGTSTP: case SIGTTIN: case SIGTTOU:
766 if (is_orphaned_pgrp(current->pgrp))
770 if (current->ptrace & PT_PTRACED)
772 current->state = TASK_STOPPED;
773 current->exit_code = signr;
774 if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
776 notify_parent(current, SIGCHLD);
780 case SIGQUIT: case SIGILL: case SIGTRAP:
781 case SIGABRT: case SIGFPE: case SIGSEGV:
782 case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
783 if (do_coredump(signr, regs))
786 /* Very useful to debug the dynamic linker */
787 printk ("Sig %d going...\n", (int)signr);
789 #ifdef DEBUG_SIGNALS_TRACE
791 struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
792 unsigned long ins[8];
795 !(((unsigned long) rw) & 0x3)) {
796 copy_from_user(ins, &rw->ins[0], sizeof(ins));
797 printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
798 rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
802 #ifdef DEBUG_SIGNALS_MAPS
809 sigaddset(¤t->pending.signal, signr);
810 recalc_sigpending(current);
811 current->flags |= PF_SIGNALED;
817 syscall_restart(orig_i0, regs, &ka->sa);
818 handle_signal(signr, ka, &info, oldset, regs);
821 if(restart_syscall &&
822 (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
823 regs->u_regs[UREG_I0] == ERESTARTSYS ||
824 regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
825 /* replay the system call when we are done */
826 regs->u_regs[UREG_I0] = orig_i0;