* better
[mascara-docs.git] / i386 / linux-2.3.21 / arch / ppc / kernel / signal.c
blob0d55bcefc827534e16c6151e24b1dd905b0bae12
1 /*
2 * linux/arch/ppc/kernel/signal.c
4 * $Id: signal.c,v 1.27 1999/08/03 19:16:38 cort Exp $
6 * PowerPC version
7 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
9 * Derived from "arch/i386/kernel/signal.c"
10 * Copyright (C) 1991, 1992 Linus Torvalds
11 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version
16 * 2 of the License, or (at your option) any later version.
19 #include <linux/sched.h>
20 #include <linux/mm.h>
21 #include <linux/smp.h>
22 #include <linux/smp_lock.h>
23 #include <linux/kernel.h>
24 #include <linux/signal.h>
25 #include <linux/errno.h>
26 #include <linux/wait.h>
27 #include <linux/ptrace.h>
28 #include <linux/unistd.h>
29 #include <linux/stddef.h>
30 #include <linux/elf.h>
31 #include <asm/ucontext.h>
32 #include <asm/uaccess.h>
33 #include <asm/pgtable.h>
35 #define DEBUG_SIG 0
37 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
39 #ifndef MIN
40 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
41 #endif
43 #define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs))
45 /*
46 * These are the flags in the MSR that the user is allowed to change
47 * by modifying the saved value of the MSR on the stack. SE and BE
48 * should not be in this list since gdb may want to change these. I.e,
49 * you should be able to step out of a signal handler to see what
50 * instruction executes next after the signal handler completes.
51 * Alternately, if you stepped into a signal handler, you should be
52 * able to continue 'til the next breakpoint from within the signal
53 * handler, even if the handler returns.
55 #define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
57 int do_signal(sigset_t *oldset, struct pt_regs *regs);
58 extern int sys_wait4(pid_t pid, unsigned long *stat_addr,
59 int options, unsigned long *ru);
62 * Atomically swap in the new signal mask, and wait for a signal.
64 int
65 sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
66 struct pt_regs *regs)
68 sigset_t saveset;
70 mask &= _BLOCKABLE;
71 spin_lock_irq(&current->sigmask_lock);
72 saveset = current->blocked;
73 siginitset(&current->blocked, mask);
74 recalc_sigpending(current);
75 spin_unlock_irq(&current->sigmask_lock);
77 regs->gpr[3] = -EINTR;
78 while (1) {
79 current->state = TASK_INTERRUPTIBLE;
80 schedule();
81 if (do_signal(&saveset, regs))
83 * If a signal handler needs to be called,
84 * do_signal() has set R3 to the signal number (the
85 * first argument of the signal handler), so don't
86 * overwrite that with EINTR !
87 * In the other cases, do_signal() doesn't touch
88 * R3, so it's still set to -EINTR (see above).
90 return regs->gpr[3];
94 int
95 sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
96 int p7, struct pt_regs *regs)
98 sigset_t saveset, newset;
100 /* XXX: Don't preclude handling different sized sigset_t's. */
101 if (sigsetsize != sizeof(sigset_t))
102 return -EINVAL;
104 if (copy_from_user(&newset, unewset, sizeof(newset)))
105 return -EFAULT;
106 sigdelsetmask(&newset, ~_BLOCKABLE);
108 spin_lock_irq(&current->sigmask_lock);
109 saveset = current->blocked;
110 current->blocked = newset;
111 recalc_sigpending(current);
112 spin_unlock_irq(&current->sigmask_lock);
114 regs->gpr[3] = -EINTR;
115 while (1) {
116 current->state = TASK_INTERRUPTIBLE;
117 schedule();
118 if (do_signal(&saveset, regs))
119 return regs->gpr[3];
124 asmlinkage int sys_rt_sigreturn(unsigned long __unused)
126 printk("sys_rt_sigreturn(): %s/%d not yet implemented.\n",
127 current->comm,current->pid);
128 do_exit(SIGSEGV);
131 asmlinkage int
132 sys_sigaltstack(const stack_t *uss, stack_t *uoss)
134 struct pt_regs *regs = (struct pt_regs *) &uss;
135 return do_sigaltstack(uss, uoss, regs->gpr[1]);
138 int
139 sys_sigaction(int sig, const struct old_sigaction *act,
140 struct old_sigaction *oact)
142 struct k_sigaction new_ka, old_ka;
143 int ret;
145 if (act) {
146 old_sigset_t mask;
147 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
148 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
149 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
150 return -EFAULT;
151 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
152 __get_user(mask, &act->sa_mask);
153 siginitset(&new_ka.sa.sa_mask, mask);
156 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
158 if (!ret && oact) {
159 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
160 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
161 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
162 return -EFAULT;
163 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
164 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
167 return ret;
171 * When we have signals to deliver, we set up on the
172 * user stack, going down from the original stack pointer:
173 * a sigregs struct
174 * one or more sigcontext structs
175 * a gap of __SIGNAL_FRAMESIZE bytes
177 * Each of these things must be a multiple of 16 bytes in size.
179 * XXX ultimately we will have to stack up a siginfo and ucontext
180 * for each rt signal.
182 struct sigregs {
183 elf_gregset_t gp_regs;
184 double fp_regs[ELF_NFPREG];
185 unsigned long tramp[2];
186 /* Programs using the rs6000/xcoff abi can save up to 19 gp regs
187 and 18 fp regs below sp before decrementing it. */
188 int abigap[56];
192 * Do a signal return; undo the signal stack.
194 int sys_sigreturn(struct pt_regs *regs)
196 struct sigcontext_struct *sc, sigctx;
197 struct sigregs *sr;
198 int ret;
199 elf_gregset_t saved_regs; /* an array of ELF_NGREG unsigned longs */
200 sigset_t set;
201 unsigned long prevsp;
203 sc = (struct sigcontext_struct *)(regs->gpr[1] + __SIGNAL_FRAMESIZE);
204 if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
205 goto badframe;
207 set.sig[0] = sigctx.oldmask;
208 #if _NSIG_WORDS > 1
209 set.sig[1] = sigctx._unused[3];
210 #endif
211 sigdelsetmask(&set, ~_BLOCKABLE);
212 spin_lock_irq(&current->sigmask_lock);
213 current->blocked = set;
214 recalc_sigpending(current);
215 spin_unlock_irq(&current->sigmask_lock);
217 sc++; /* Look at next sigcontext */
218 if (sc == (struct sigcontext_struct *)(sigctx.regs)) {
219 /* Last stacked signal - restore registers */
220 sr = (struct sigregs *) sigctx.regs;
221 if (regs->msr & MSR_FP )
222 giveup_fpu(current);
223 if (copy_from_user(saved_regs, &sr->gp_regs,
224 sizeof(sr->gp_regs)))
225 goto badframe;
226 saved_regs[PT_MSR] = (regs->msr & ~MSR_USERCHANGE)
227 | (saved_regs[PT_MSR] & MSR_USERCHANGE);
228 memcpy(regs, saved_regs, GP_REGS_SIZE);
230 if (copy_from_user(current->thread.fpr, &sr->fp_regs,
231 sizeof(sr->fp_regs)))
232 goto badframe;
234 ret = regs->result;
236 } else {
237 /* More signals to go */
238 regs->gpr[1] = (unsigned long)sc - __SIGNAL_FRAMESIZE;
239 if (copy_from_user(&sigctx, sc, sizeof(sigctx)))
240 goto badframe;
241 sr = (struct sigregs *) sigctx.regs;
242 regs->gpr[3] = ret = sigctx.signal;
243 regs->gpr[4] = (unsigned long) sc;
244 regs->link = (unsigned long) &sr->tramp;
245 regs->nip = sigctx.handler;
247 if (get_user(prevsp, &sr->gp_regs[PT_R1])
248 || put_user(prevsp, (unsigned long *) regs->gpr[1]))
249 goto badframe;
251 return ret;
253 badframe:
254 lock_kernel();
255 do_exit(SIGSEGV);
259 * Set up a signal frame.
261 static void
262 setup_frame(struct pt_regs *regs, struct sigregs *frame,
263 unsigned long newsp)
265 struct sigcontext_struct *sc = (struct sigcontext_struct *) newsp;
267 if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
268 goto badframe;
269 if (regs->msr & MSR_FP)
270 giveup_fpu(current);
271 if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
272 || __copy_to_user(&frame->fp_regs, current->thread.fpr,
273 ELF_NFPREG * sizeof(double))
274 || __put_user(0x38007777UL, &frame->tramp[0]) /* li r0,0x7777 */
275 || __put_user(0x44000002UL, &frame->tramp[1])) /* sc */
276 goto badframe;
277 flush_icache_range((unsigned long) &frame->tramp[0],
278 (unsigned long) &frame->tramp[2]);
280 newsp -= __SIGNAL_FRAMESIZE;
281 if (put_user(regs->gpr[1], (unsigned long *)newsp)
282 || get_user(regs->nip, &sc->handler)
283 || get_user(regs->gpr[3], &sc->signal))
284 goto badframe;
285 regs->gpr[1] = newsp;
286 regs->gpr[4] = (unsigned long) sc;
287 regs->link = (unsigned long) frame->tramp;
289 return;
291 badframe:
292 #if DEBUG_SIG
293 printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
294 regs, frame, newsp);
295 #endif
296 lock_kernel();
297 do_exit(SIGSEGV);
301 * OK, we're invoking a handler
303 static void
304 handle_signal(unsigned long sig, struct k_sigaction *ka,
305 siginfo_t *info, sigset_t *oldset, struct pt_regs * regs,
306 unsigned long *newspp, unsigned long frame)
308 struct sigcontext_struct *sc;
310 if (regs->trap == 0x0C00 /* System Call! */
311 && ((int)regs->result == -ERESTARTNOHAND ||
312 ((int)regs->result == -ERESTARTSYS &&
313 !(ka->sa.sa_flags & SA_RESTART))))
314 regs->result = -EINTR;
316 /* Put another sigcontext on the stack */
317 *newspp -= sizeof(*sc);
318 sc = (struct sigcontext_struct *) *newspp;
319 if (verify_area(VERIFY_WRITE, sc, sizeof(*sc)))
320 goto badframe;
322 if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler)
323 || __put_user(oldset->sig[0], &sc->oldmask)
324 #if _NSIG_WORDS > 1
325 || __put_user(oldset->sig[1], &sc->_unused[3])
326 #endif
327 || __put_user((struct pt_regs *)frame, &sc->regs)
328 || __put_user(sig, &sc->signal))
329 goto badframe;
331 if (ka->sa.sa_flags & SA_ONESHOT)
332 ka->sa.sa_handler = SIG_DFL;
334 if (!(ka->sa.sa_flags & SA_NODEFER)) {
335 spin_lock_irq(&current->sigmask_lock);
336 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
337 sigaddset(&current->blocked,sig);
338 recalc_sigpending(current);
339 spin_unlock_irq(&current->sigmask_lock);
341 return;
343 badframe:
344 #if DEBUG_SIG
345 printk("badframe in handle_signal, regs=%p frame=%lx newsp=%lx\n",
346 regs, frame, *newspp);
347 printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
348 #endif
349 lock_kernel();
350 do_exit(SIGSEGV);
354 * Note that 'init' is a special process: it doesn't get signals it doesn't
355 * want to handle. Thus you cannot kill init even with a SIGKILL even by
356 * mistake.
358 int do_signal(sigset_t *oldset, struct pt_regs *regs)
360 siginfo_t info;
361 struct k_sigaction *ka;
362 unsigned long frame, newsp;
364 if (!oldset)
365 oldset = &current->blocked;
367 newsp = frame = 0;
369 for (;;) {
370 unsigned long signr;
372 spin_lock_irq(&current->sigmask_lock);
373 signr = dequeue_signal(&current->blocked, &info);
374 spin_unlock_irq(&current->sigmask_lock);
376 if (!signr)
377 break;
379 if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
380 /* Let the debugger run. */
381 current->exit_code = signr;
382 current->state = TASK_STOPPED;
383 notify_parent(current, SIGCHLD);
384 schedule();
386 /* We're back. Did the debugger cancel the sig? */
387 if (!(signr = current->exit_code))
388 continue;
389 current->exit_code = 0;
391 /* The debugger continued. Ignore SIGSTOP. */
392 if (signr == SIGSTOP)
393 continue;
395 /* Update the siginfo structure. Is this good? */
396 if (signr != info.si_signo) {
397 info.si_signo = signr;
398 info.si_errno = 0;
399 info.si_code = SI_USER;
400 info.si_pid = current->p_pptr->pid;
401 info.si_uid = current->p_pptr->uid;
404 /* If the (new) signal is now blocked, requeue it. */
405 if (sigismember(&current->blocked, signr)) {
406 send_sig_info(signr, &info, current);
407 continue;
411 ka = &current->sig->action[signr-1];
412 if (ka->sa.sa_handler == SIG_IGN) {
413 if (signr != SIGCHLD)
414 continue;
415 /* Check for SIGCHLD: it's special. */
416 while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
417 /* nothing */;
418 continue;
421 if (ka->sa.sa_handler == SIG_DFL) {
422 int exit_code = signr;
424 /* Init gets no signals it doesn't want. */
425 if (current->pid == 1)
426 continue;
428 switch (signr) {
429 case SIGCONT: case SIGCHLD: case SIGWINCH:
430 continue;
432 case SIGTSTP: case SIGTTIN: case SIGTTOU:
433 if (is_orphaned_pgrp(current->pgrp))
434 continue;
435 /* FALLTHRU */
437 case SIGSTOP:
438 current->state = TASK_STOPPED;
439 current->exit_code = signr;
440 if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
441 notify_parent(current, SIGCHLD);
442 schedule();
443 continue;
445 case SIGQUIT: case SIGILL: case SIGTRAP:
446 case SIGABRT: case SIGFPE: case SIGSEGV:
447 if (do_coredump(signr, regs))
448 exit_code |= 0x80;
449 /* FALLTHRU */
451 default:
452 lock_kernel();
453 sigaddset(&current->signal, signr);
454 recalc_sigpending(current);
455 current->flags |= PF_SIGNALED;
456 do_exit(exit_code);
457 /* NOTREACHED */
461 if ( (ka->sa.sa_flags & SA_ONSTACK)
462 && (! on_sig_stack(regs->gpr[1])))
463 newsp = (current->sas_ss_sp + current->sas_ss_size);
464 else
465 newsp = regs->gpr[1];
466 newsp = frame = newsp - sizeof(struct sigregs);
468 /* Whee! Actually deliver the signal. */
469 handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
472 if (regs->trap == 0x0C00 /* System Call! */ &&
473 ((int)regs->result == -ERESTARTNOHAND ||
474 (int)regs->result == -ERESTARTSYS ||
475 (int)regs->result == -ERESTARTNOINTR)) {
476 regs->gpr[3] = regs->orig_gpr3;
477 regs->nip -= 4; /* Back up & retry system call */
478 regs->result = 0;
481 if (newsp == frame)
482 return 0; /* no signals delivered */
484 setup_frame(regs, (struct sigregs *) frame, newsp);
485 return 1;