- pre3:
[davej-history.git] / arch / ppc / kernel / signal.c
blob31e381b1731fb45ec21bd5056d7844a24c97b6a2
1 /*
2 * linux/arch/ppc/kernel/signal.c
4 * PowerPC version
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
7 * Derived from "arch/i386/kernel/signal.c"
8 * Copyright (C) 1991, 1992 Linus Torvalds
9 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
17 #include <linux/sched.h>
18 #include <linux/mm.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
21 #include <linux/kernel.h>
22 #include <linux/signal.h>
23 #include <linux/errno.h>
24 #include <linux/wait.h>
25 #include <linux/ptrace.h>
26 #include <linux/unistd.h>
27 #include <linux/stddef.h>
28 #include <linux/elf.h>
29 #include <asm/ucontext.h>
30 #include <asm/uaccess.h>
31 #include <asm/pgtable.h>
33 #define DEBUG_SIG 0
35 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37 #ifndef MIN
38 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
39 #endif
41 #define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
43 /*
44 * These are the flags in the MSR that the user is allowed to change
45 * by modifying the saved value of the MSR on the stack. SE and BE
46 * should not be in this list since gdb may want to change these. I.e,
47 * you should be able to step out of a signal handler to see what
48 * instruction executes next after the signal handler completes.
49 * Alternately, if you stepped into a signal handler, you should be
50 * able to continue 'til the next breakpoint from within the signal
51 * handler, even if the handler returns.
53 #define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
55 int do_signal(sigset_t *oldset, struct pt_regs *regs);
56 extern int sys_wait4(pid_t pid, unsigned long *stat_addr,
57 int options, unsigned long *ru);
59 int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
61 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
62 return -EFAULT;
63 if (from->si_code < 0)
64 return __copy_to_user(to, from, sizeof(siginfo_t));
65 else {
66 int err;
68 /* If you change siginfo_t structure, please be sure
69 this code is fixed accordingly.
70 It should never copy any pad contained in the structure
71 to avoid security leaks, but must copy the generic
72 3 ints plus the relevant union member. */
73 err = __put_user(from->si_signo, &to->si_signo);
74 err |= __put_user(from->si_errno, &to->si_errno);
75 err |= __put_user((short)from->si_code, &to->si_code);
76 /* First 32bits of unions are always present. */
77 err |= __put_user(from->si_pid, &to->si_pid);
78 switch (from->si_code >> 16) {
79 case __SI_FAULT >> 16:
80 break;
81 case __SI_CHLD >> 16:
82 err |= __put_user(from->si_utime, &to->si_utime);
83 err |= __put_user(from->si_stime, &to->si_stime);
84 err |= __put_user(from->si_status, &to->si_status);
85 default:
86 err |= __put_user(from->si_uid, &to->si_uid);
87 break;
88 /* case __SI_RT: This is not generated by the kernel as of now. */
90 return err;
95 * Atomically swap in the new signal mask, and wait for a signal.
97 int
98 sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
99 struct pt_regs *regs)
101 sigset_t saveset;
103 mask &= _BLOCKABLE;
104 spin_lock_irq(&current->sigmask_lock);
105 saveset = current->blocked;
106 siginitset(&current->blocked, mask);
107 recalc_sigpending(current);
108 spin_unlock_irq(&current->sigmask_lock);
110 regs->gpr[3] = -EINTR;
111 while (1) {
112 current->state = TASK_INTERRUPTIBLE;
113 schedule();
114 if (do_signal(&saveset, regs))
116 * If a signal handler needs to be called,
117 * do_signal() has set R3 to the signal number (the
118 * first argument of the signal handler), so don't
119 * overwrite that with EINTR !
120 * In the other cases, do_signal() doesn't touch
121 * R3, so it's still set to -EINTR (see above).
123 return regs->gpr[3];
128 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
129 int p7, struct pt_regs *regs)
131 sigset_t saveset, newset;
133 /* XXX: Don't preclude handling different sized sigset_t's. */
134 if (sigsetsize != sizeof(sigset_t))
135 return -EINVAL;
137 if (copy_from_user(&newset, unewset, sizeof(newset)))
138 return -EFAULT;
139 sigdelsetmask(&newset, ~_BLOCKABLE);
141 spin_lock_irq(&current->sigmask_lock);
142 saveset = current->blocked;
143 current->blocked = newset;
144 recalc_sigpending(current);
145 spin_unlock_irq(&current->sigmask_lock);
147 regs->gpr[3] = -EINTR;
148 while (1) {
149 current->state = TASK_INTERRUPTIBLE;
150 schedule();
151 if (do_signal(&saveset, regs))
152 return regs->gpr[3];
157 asmlinkage int
158 sys_sigaltstack(const stack_t *uss, stack_t *uoss)
160 struct pt_regs *regs = (struct pt_regs *) &uss;
161 return do_sigaltstack(uss, uoss, regs->gpr[1]);
164 int
165 sys_sigaction(int sig, const struct old_sigaction *act,
166 struct old_sigaction *oact)
168 struct k_sigaction new_ka, old_ka;
169 int ret;
171 if (act) {
172 old_sigset_t mask;
173 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
174 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
175 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
176 return -EFAULT;
177 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
178 __get_user(mask, &act->sa_mask);
179 siginitset(&new_ka.sa.sa_mask, mask);
182 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
184 if (!ret && oact) {
185 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
186 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
187 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
188 return -EFAULT;
189 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
190 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
193 return ret;
197 * When we have signals to deliver, we set up on the
198 * user stack, going down from the original stack pointer:
199 * a sigregs struct
200 * one or more sigcontext structs with
201 * a gap of __SIGNAL_FRAMESIZE bytes
203 * Each of these things must be a multiple of 16 bytes in size.
206 struct sigregs {
207 elf_gregset_t gp_regs;
208 double fp_regs[ELF_NFPREG];
209 unsigned long tramp[2];
210 /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
211 and 18 fp regs below sp before decrementing it. */
212 int abigap[56];
215 struct rt_sigframe
217 unsigned long _unused[2];
218 struct siginfo *pinfo;
219 void *puc;
220 struct siginfo info;
221 struct ucontext uc;
226 * When we have rt signals to deliver, we set up on the
227 * user stack, going down from the original stack pointer:
228 * a sigregs struct
229 * one rt_sigframe struct (siginfo + ucontext)
230 * a gap of __SIGNAL_FRAMESIZE bytes
232 * Each of these things must be a multiple of 16 bytes in size.
235 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
237 struct rt_sigframe *rt_sf;
238 struct sigcontext_struct sigctx;
239 struct sigregs *sr;
240 int ret;
241 elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
242 sigset_t set;
243 stack_t st;
244 unsigned long prevsp;
246 rt_sf = (struct rt_sigframe *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
247 if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx))
248 || copy_from_user(&set, &rt_sf->uc.uc_sigmask, sizeof(set))
249 || copy_from_user(&st, &rt_sf->uc.uc_stack, sizeof(st)))
250 goto badframe;
251 sigdelsetmask(&set, ~_BLOCKABLE);
252 spin_lock_irq(&current->sigmask_lock);
253 current->blocked = set;
254 recalc_sigpending(current);
255 spin_unlock_irq(&current->sigmask_lock);
257 rt_sf++; /* Look at next rt_sigframe */
258 if (rt_sf == (struct rt_sigframe *)(sigctx.regs)) {
259 /* Last stacked signal - restore registers -
260 * sigctx is initialized to point to the
261 * preamble frame (where registers are stored)
262 * see handle_signal()
264 sr = (struct sigregs *) sigctx.regs;
265 if (regs->msr & MSR_FP )
266 giveup_fpu(current);
267 if (copy_from_user(saved_regs, &sr->gp_regs,
268 sizeof(sr->gp_regs)))
269 goto badframe;
270 saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
271 | (saved_regs[PT_MSR] & MSR_USERCHANGE);
272 memcpy(regs, saved_regs, GP_REGS_SIZE);
273 if (copy_from_user(current->thread.fpr, &sr->fp_regs,
274 sizeof(sr->fp_regs)))
275 goto badframe;
276 /* This function sets back the stack flags into
277 the current task structure. */
278 sys_sigaltstack(&st, NULL);
280 ret = regs->result;
281 } else {
282 /* More signals to go */
283 /* Set up registers for next signal handler */
284 regs->gpr[1] = (unsigned long)rt_sf - __SIGNAL_FRAMESIZE;
285 if (copy_from_user(&sigctx, &rt_sf->uc.uc_mcontext, sizeof(sigctx)))
286 goto badframe;
287 sr = (struct sigregs *) sigctx.regs;
288 regs->gpr[3] = ret = sigctx.signal;
289 /* Get the siginfo */
290 get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo);
291 /* Get the ucontext */
292 get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc);
293 regs->gpr[6] = (unsigned long) rt_sf;
295 regs->link = (unsigned long) &sr->tramp;
296 regs->nip = sigctx.handler;
297 if (get_user(prevsp, &sr->gp_regs[PT_R1])
298 || put_user(prevsp, (unsigned long *) regs->gpr[1]))
299 goto badframe;
301 return ret;
303 badframe:
304 lock_kernel();
305 do_exit(SIGSEGV);
308 static void
309 setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
310 signed long newsp)
312 struct rt_sigframe *rt_sf = (struct rt_sigframe *) newsp;
314 /* Set up preamble frame */
315 if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
316 goto badframe;
317 if (regs->msr & MSR_FP)
318 giveup_fpu(current);
319 if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
320 || __copy_to_user(&frame->fp_regs, current->thread.fpr,
321 ELF_NFPREG * sizeof(double))
322 /* Set up to return from user space.
323 It calls the sc exception at offset 0x9999
324 for sys_rt_sigreturn().
326 || __put_user(0x38006666UL, &frame->tramp[0]) /* li r0,0x6666 */
327 || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */
328 goto badframe;
329 flush_icache_range((unsigned long) &frame->tramp[0],
330 (unsigned long) &frame->tramp[2]);
332 /* Retrieve rt_sigframe from stack and
333 set up registers for signal handler
335 newsp -= __SIGNAL_FRAMESIZE;
336 if (put_user(regs->gpr[1], (unsigned long *)newsp)
337 || get_user(regs->nip, &rt_sf->uc.uc_mcontext.handler)
338 || get_user(regs->gpr[3], &rt_sf->uc.uc_mcontext.signal)
339 || get_user(regs->gpr[4], (unsigned long *)&rt_sf->pinfo)
340 || get_user(regs->gpr[5], (unsigned long *)&rt_sf->puc))
341 goto badframe;
343 regs->gpr[1] = newsp;
344 regs->gpr[6] = (unsigned long) rt_sf;
345 regs->link = (unsigned long) frame->tramp;
347 return;
349 badframe:
350 #if DEBUG_SIG
351 printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
352 regs, frame, newsp);
353 #endif
354 lock_kernel();
355 do_exit(SIGSEGV);
359 * Do a signal return; undo the signal stack.
361 int sys_sigreturn(struct pt_regs *regs)
363 struct sigcontext_struct *sc, sigctx;
364 struct sigregs *sr;
365 int ret;
366 elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
367 sigset_t set;
368 unsigned long prevsp;
370 sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
371 if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
372 goto badframe;
374 set.sig[0] = sigctx.oldmask;
375 #if _NSIG_WORDS > 1
376 set.sig[1] = sigctx._unused[3];
377 #endif
378 sigdelsetmask(&set, ~_BLOCKABLE);
379 spin_lock_irq(&current->sigmask_lock);
380 current->blocked = set;
381 recalc_sigpending(current);
382 spin_unlock_irq(&current->sigmask_lock);
384 sc++; /* Look at next sigcontext */
385 if (sc == (struct sigcontext_struct *)(sigctx.regs)) {
386 /* Last stacked signal - restore registers */
387 sr = (struct sigregs *) sigctx.regs;
388 if (regs->msr & MSR_FP )
389 giveup_fpu(current);
390 if (copy_from_user(saved_regs, &sr->gp_regs,
391 sizeof(sr->gp_regs)))
392 goto badframe;
393 saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
394 | (saved_regs[PT_MSR] & MSR_USERCHANGE);
395 memcpy(regs, saved_regs, GP_REGS_SIZE);
397 if (copy_from_user(current->thread.fpr, &sr->fp_regs,
398 sizeof(sr->fp_regs)))
399 goto badframe;
401 ret = regs->result;
403 } else {
404 /* More signals to go */
405 regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE;
406 if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
407 goto badframe;
408 sr = (struct sigregs *) sigctx.regs;
409 regs->gpr[3] = ret = sigctx.signal;
410 regs->gpr[4] = (unsigned long) sc;
411 regs->link = (unsigned long) &sr->tramp;
412 regs->nip = sigctx.handler;
414 if (get_user(prevsp, &sr->gp_regs[PT_R1])
415 || put_user(prevsp, (unsigned long *) regs->gpr[1]))
416 goto badframe;
418 return ret;
420 badframe:
421 lock_kernel();
422 do_exit(SIGSEGV);
426 * Set up a signal frame.
428 static void
429 setup_frame(struct pt_regs *regs, struct sigregs *frame,
430 unsigned long newsp)
432 struct sigcontext_struct *sc = (struct sigcontext_struct *) newsp;
434 if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
435 goto badframe;
436 if (regs->msr & MSR_FP)
437 giveup_fpu(current);
438 if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
439 || __copy_to_user(&frame->fp_regs, current->thread.fpr,
440 ELF_NFPREG * sizeof(double))
441 || __put_user(0x38007777UL, &frame->tramp[0]) /* li r0,0x7777 */
442 || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */
443 goto badframe;
444 flush_icache_range((unsigned long) &frame->tramp[0],
445 (unsigned long) &frame->tramp[2]);
447 newsp -= __SIGNAL_FRAMESIZE;
448 if (put_user(regs->gpr[1], (unsigned long *)newsp)
449 || get_user(regs->nip, &sc->handler)
450 || get_user(regs->gpr[3], &sc->signal))
451 goto badframe;
452 regs->gpr[1] = newsp;
453 regs->gpr[4] = (unsigned long) sc;
454 regs->link = (unsigned long) frame->tramp;
456 return;
458 badframe:
459 #if DEBUG_SIG
460 printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
461 regs, frame, newsp);
462 #endif
463 lock_kernel();
464 do_exit(SIGSEGV);
468 * OK, we're invoking a handler
470 static void
471 handle_signal(unsigned long sig, struct k_sigaction *ka,
472 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
473 unsigned long *newspp, unsigned long frame)
475 struct sigcontext_struct *sc;
476 struct rt_sigframe *rt_sf;
478 if (regs->trap == 0x0C00 /* System Call! */
479 && ((int)regs->result == -ERESTARTNOHAND ||
480 ((int)regs->result == -ERESTARTSYS &&
481 !(ka->sa.sa_flags & SA_RESTART))))
482 regs->result = -EINTR;
484 /* Set up Signal Frame */
485 if (ka->sa.sa_flags & SA_SIGINFO) {
486 /* Put a Real Time Context onto stack */
487 *newspp -= sizeof(*rt_sf);
488 rt_sf = (struct rt_sigframe *) *newspp;
489 if (verify_area(VERIFY_WRITE, rt_sf, sizeof(*rt_sf)))
490 goto badframe;
492 if (__put_user((unsigned long) ka->sa.sa_handler, &rt_sf->uc.uc_mcontext.handler)
493 || __put_user(&rt_sf->info, &rt_sf->pinfo)
494 || __put_user(&rt_sf->uc, &rt_sf->puc)
495 /* Put the siginfo */
496 || __copy_to_user(&rt_sf->info, info, sizeof(*info))
497 /* Create the ucontext */
498 || __put_user(0, &rt_sf->uc.uc_flags)
499 || __put_user(0, &rt_sf->uc.uc_link)
500 || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp)
501 || __put_user(sas_ss_flags(regs->gpr[1]),
502 &rt_sf->uc.uc_stack.ss_flags)
503 || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size)
504 || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))
505 /* mcontext.regs points to preamble register frame */
506 || __put_user((struct pt_regs *)frame, &rt_sf->uc.uc_mcontext.regs)
507 || __put_user(sig, &rt_sf->uc.uc_mcontext.signal))
508 goto badframe;
509 } else {
510 /* Put another sigcontext on the stack */
511 *newspp -= sizeof(*sc);
512 sc = (struct sigcontext_struct *) *newspp;
513 if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
514 goto badframe;
516 if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
517 || __put_user(oldset->sig[0], &sc->oldmask)
518 #if _NSIG_WORDS > 1
519 || __put_user(oldset->sig[1], &sc->_unused[3])
520 #endif
521 || __put_user((struct pt_regs *)frame, &sc->regs)
522 || __put_user(sig, &sc->signal))
523 goto badframe;
526 if (ka->sa.sa_flags & SA_ONESHOT)
527 ka->sa.sa_handler = SIG_DFL;
529 if (!(ka->sa.sa_flags & SA_NODEFER)) {
530 spin_lock_irq(&current->sigmask_lock);
531 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
532 sigaddset(&current->blocked,sig);
533 recalc_sigpending(current);
534 spin_unlock_irq(&current->sigmask_lock);
536 return;
538 badframe:
539 #if DEBUG_SIG
540 printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
541 regs, frame, *newspp);
542 printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
543 #endif
544 lock_kernel();
545 do_exit(SIGSEGV);
549 * Note that 'init' is a special process: it doesn't get signals it doesn't
550 * want to handle. Thus you cannot kill init even with a SIGKILL even by
551 * mistake.
553 int do_signal(sigset_t *oldset, struct pt_regs *regs)
555 siginfo_t info;
556 struct k_sigaction *ka;
557 unsigned long frame, newsp;
559 if (!oldset)
560 oldset = &current->blocked;
562 newsp = frame = 0;
564 for (;;) {
565 unsigned long signr;
567 spin_lock_irq(&current->sigmask_lock);
568 signr = dequeue_signal(&current->blocked, &info);
569 spin_unlock_irq(&current->sigmask_lock);
571 if (!signr)
572 break;
574 if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
575 /* Let the debugger run. */
576 current->exit_code = signr;
577 current->state = TASK_STOPPED;
578 notify_parent(current, SIGCHLD);
579 schedule();
581 /* We're back. Did the debugger cancel the sig? */
582 if (!(signr = current->exit_code))
583 continue;
584 current->exit_code = 0;
586 /* The debugger continued. Ignore SIGSTOP. */
587 if (signr == SIGSTOP)
588 continue;
590 /* Update the siginfo structure. Is this good? */
591 if (signr != info.si_signo) {
592 info.si_signo = signr;
593 info.si_errno = 0;
594 info.si_code = SI_USER;
595 info.si_pid = current->p_pptr->pid;
596 info.si_uid = current->p_pptr->uid;
599 /* If the (new) signal is now blocked, requeue it. */
600 if (sigismember(&current->blocked, signr)) {
601 send_sig_info(signr, &info, current);
602 continue;
606 ka = &current->sig->action[signr-1];
607 if (ka->sa.sa_handler == SIG_IGN) {
608 if (signr != SIGCHLD)
609 continue;
610 /* Check for SIGCHLD: it's special. */
611 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
612 /* nothing */;
613 continue;
616 if (ka->sa.sa_handler == SIG_DFL) {
617 int exit_code = signr;
619 /* Init gets no signals it doesn't want. */
620 if (current->pid == 1)
621 continue;
623 switch (signr) {
624 case SIGCONT: case SIGCHLD: case SIGWINCH:
625 continue;
627 case SIGTSTP: case SIGTTIN: case SIGTTOU:
628 if (is_orphaned_pgrp(current->pgrp))
629 continue;
630 /* FALLTHRU */
632 case SIGSTOP:
633 current->state = TASK_STOPPED;
634 current->exit_code = signr;
635 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
636 notify_parent(current, SIGCHLD);
637 schedule();
638 continue;
640 case SIGQUIT: case SIGILL: case SIGTRAP:
641 case SIGABRT: case SIGFPE: case SIGSEGV:
642 case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
643 if (do_coredump(signr, regs))
644 exit_code |= 0x80;
645 /* FALLTHRU */
647 default:
648 lock_kernel();
649 sigaddset(&current->pending.signal, signr);
650 recalc_sigpending(current);
651 current->flags |= PF_SIGNALED;
652 do_exit(exit_code);
653 /* NOTREACHED */
657 if ( (ka->sa.sa_flags & SA_ONSTACK)
658 && (! on_sig_stack(regs->gpr[1])))
659 newsp = (current->sas_ss_sp + current->sas_ss_size);
660 else
661 newsp = regs->gpr[1];
662 newsp = frame = newsp - sizeof(struct sigregs);
664 /* Whee! Actually deliver the signal. */
665 handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
668 if (regs->trap == 0x0C00 /* System Call! */ &&
669 ((int)regs->result == -ERESTARTNOHAND ||
670 (int)regs->result == -ERESTARTSYS ||
671 (int)regs->result == -ERESTARTNOINTR)) {
672 regs->gpr[3] = regs->orig_gpr3;
673 regs->nip -= 4; /* Back up & retry system call */
674 regs->result = 0;
677 if (newsp == frame)
678 return 0; /* no signals delivered */
680 if (ka->sa.sa_flags & SA_SIGINFO)
681 setup_rt_frame(regs, (struct sigregs *) frame, newsp);
682 else
683 setup_frame(regs, (struct sigregs *) frame, newsp);
684 return 1;