1 /* $Id: signal.c,v 1.19 1999/06/17 13:25:47 ralf Exp $
3 * linux/arch/mips/kernel/signal.c
5 * Copyright (C) 1991, 1992 Linus Torvalds
6 * Copyright (C) 1994, 1995, 1996, 1997, 1998 Ralf Baechle
8 * XXX Handle lazy fp context switches correctly.
10 #include <linux/config.h>
11 #include <linux/sched.h>
13 #include <linux/smp.h>
14 #include <linux/smp_lock.h>
15 #include <linux/kernel.h>
16 #include <linux/signal.h>
17 #include <linux/errno.h>
18 #include <linux/wait.h>
19 #include <linux/ptrace.h>
20 #include <linux/unistd.h>
23 #include <asm/bitops.h>
24 #include <asm/pgtable.h>
25 #include <asm/stackframe.h>
26 #include <asm/uaccess.h>
30 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32 asmlinkage
int sys_wait4(pid_t pid
, unsigned long *stat_addr
,
33 int options
, unsigned long *ru
);
34 asmlinkage
int do_signal(sigset_t
*oldset
, struct pt_regs
*regs
);
35 extern asmlinkage
void (*save_fp_context
)(struct sigcontext
*sc
);
36 extern asmlinkage
void (*restore_fp_context
)(struct sigcontext
*sc
);
39 * Atomically swap in the new signal mask, and wait for a signal.
42 sys_sigsuspend(struct pt_regs regs
)
44 sigset_t
*uset
, saveset
, newset
;
47 uset
= (sigset_t
*) regs
.regs
[4];
48 if (copy_from_user(&newset
, uset
, sizeof(sigset_t
)))
50 sigdelsetmask(&newset
, ~_BLOCKABLE
);
52 spin_lock_irq(¤t
->sigmask_lock
);
53 saveset
= current
->blocked
;
54 current
->blocked
= newset
;
55 spin_unlock_irq(¤t
->sigmask_lock
);
60 current
->state
= TASK_INTERRUPTIBLE
;
62 if (do_signal(&saveset
, ®s
))
68 sys_rt_sigsuspend(struct pt_regs regs
)
70 sigset_t
*uset
, saveset
, newset
;
73 uset
= (sigset_t
*) regs
.regs
[4];
74 if (copy_from_user(&newset
, uset
, sizeof(sigset_t
)))
76 sigdelsetmask(&newset
, ~_BLOCKABLE
);
78 spin_lock_irq(¤t
->sigmask_lock
);
79 saveset
= current
->blocked
;
80 current
->blocked
= newset
;
81 spin_unlock_irq(¤t
->sigmask_lock
);
86 current
->state
= TASK_INTERRUPTIBLE
;
88 if (do_signal(&saveset
, ®s
))
94 sys_sigaction(int sig
, const struct sigaction
*act
,
95 struct sigaction
*oact
)
97 struct k_sigaction new_ka
, old_ka
;
102 if (verify_area(VERIFY_READ
, act
, sizeof(*act
)) ||
103 __get_user(new_ka
.sa
.sa_handler
, &act
->sa_handler
) ||
104 __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
))
107 __copy_from_user(&mask
, &act
->sa_mask
, sizeof(sigset_t
));
108 new_ka
.ka_restorer
= NULL
;
111 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
114 if (verify_area(VERIFY_WRITE
, oact
, sizeof(*oact
)) ||
115 __put_user(old_ka
.sa
.sa_handler
, &oact
->sa_handler
) ||
116 __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
))
118 __copy_to_user(&old_ka
.sa
.sa_mask
, &oact
->sa_mask
,
126 sys_sigaltstack(const stack_t
*uss
, stack_t
*uoss
)
128 struct pt_regs
*regs
= (struct pt_regs
*) &uss
;
130 return do_sigaltstack(uss
, uoss
, regs
->regs
[29]);
134 * To do: this entire function should be accessed over a function pointer
135 * such that we can handle stack frames for different ABIs.
139 restore_sigcontext(struct pt_regs
*regs
, struct sigcontext
*context
)
144 __get_user(regs
->cp0_epc
, &context
->sc_pc
);
146 __get_user(reg
, &context
->sc_mdhi
);
147 regs
->hi
= (int) reg
;
148 __get_user(reg
, &context
->sc_mdlo
);
149 regs
->lo
= (int) reg
;
151 #define restore_gp_reg(i) __get_user(reg, &context->sc_regs[i]); \
152 regs->regs[i] = (int) reg;
153 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
154 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
155 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
156 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
157 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
158 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
159 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
160 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
161 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
162 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
164 #undef restore_gp_reg
166 /* FP depends on what FPU in what mode we have. */
167 __get_user(owned_fp
, &context
->sc_ownedfp
);
170 restore_fp_context(context
);
171 last_task_used_math
= current
;
174 restore_fp_context(context
);
178 * The structure sc describes the stackframe on the userstack. The frames
179 * are identical for normal and realtime signal stackframes with the
180 * exception of the additional struct ucontext for rt frames.
183 unsigned long ass
[4]; /* argument save space for o32 */
184 unsigned int code
[4]; /* signal trampoline */
185 struct sigcontext scc
;
189 unsigned long ass
[4];
190 unsigned int code
[4];
191 struct sigcontext scc
;
192 // struct ucontext uc;
195 asmlinkage
int sys_sigreturn(struct pt_regs regs
)
197 struct sigcontext
*context
;
200 context
= (struct sigcontext
*)(long) regs
.regs
[29];
201 if (!access_ok(VERIFY_READ
, context
, sizeof(struct sigcontext
)) ||
202 (regs
.regs
[29] & (SZREG
- 1)))
206 if (__get_user(blocked
.sig
[0], &context
->sc_sigset
[0]) ||
207 __get_user(blocked
.sig
[1], &context
->sc_sigset
[1]) ||
208 __get_user(blocked
.sig
[2], &context
->sc_sigset
[2]) ||
209 __get_user(blocked
.sig
[3], &context
->sc_sigset
[3]))
212 if (__copy_from_user(&blocked
, &context
->sc_sigset
, sizeof(blocked
)))
216 sigdelsetmask(&blocked
, ~_BLOCKABLE
);
217 spin_lock_irq(¤t
->sigmask_lock
);
218 current
->blocked
= blocked
;
219 recalc_sigpending(current
);
220 spin_unlock_irq(¤t
->sigmask_lock
);
222 restore_sigcontext(®s
, context
);
225 * Don't let your children do this ...
227 __asm__
__volatile__(
229 "j\tret_from_sys_call"
240 /* same as sys_sigreturn for now */
241 asmlinkage
int sys_rt_sigreturn(struct pt_regs regs
)
246 #define scc_offset ((size_t)&((struct sigframe *)0)->scc)
249 * Set up the return code ...
253 * li v0,__NR_sigreturn
258 setup_trampoline(unsigned int *code
)
260 __put_user(0x27bd0000 + scc_offset
, code
+ 0);
261 __put_user(0x24020000 + __NR_sigreturn
, code
+ 1);
262 __put_user(0x0000000c , code
+ 2);
265 * Flush caches so that the instructions will be correctly executed.
267 flush_cache_sigtramp((unsigned long) code
);
271 setup_sigcontext(struct pt_regs
*regs
, struct sigcontext
*sc
, sigset_t
*set
)
275 __put_user(regs
->cp0_epc
, &sc
->sc_pc
);
276 __put_user(regs
->cp0_status
, &sc
->sc_status
); /* Status register */
278 #define save_gp_reg(i) __put_user(regs->regs[(i)], &sc->sc_regs[(i)])
279 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
280 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
281 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
282 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
283 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
284 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
285 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
286 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
290 __put_user(regs
->hi
, &sc
->sc_mdhi
);
291 __put_user(regs
->lo
, &sc
->sc_mdlo
);
292 __put_user(regs
->cp0_cause
, &sc
->sc_cause
);
294 owned_fp
= (current
== last_task_used_math
);
295 __put_user(owned_fp
, &sc
->sc_ownedfp
);
298 if (current
->used_math
) { /* fp is active. */
299 set_cp0_status(ST0_CU1
, ST0_CU1
);
300 save_fp_context(sc
); /* CPU-dependent */
301 last_task_used_math
= NULL
;
302 regs
->cp0_status
&= ~ST0_CU1
;
303 current
->used_math
= 0;
306 set_cp0_status(ST0_CU1
, ST0_CU1
);
307 save_fp_context(sc
); /* CPU-dependent */
309 __put_user(set
->sig
[0], &sc
->sc_sigset
[0]);
310 __put_user(set
->sig
[1], &sc
->sc_sigset
[1]);
311 __put_user(set
->sig
[2], &sc
->sc_sigset
[2]);
312 __put_user(set
->sig
[3], &sc
->sc_sigset
[3]);
316 setup_frame(struct k_sigaction
* ka
, struct pt_regs
*regs
,
317 int signr
, sigset_t
*oldmask
)
319 struct sigframe
*frame
;
320 struct sigcontext
*sc
;
322 /* Align the stackframe to an adequate boundary for the architecture. */
323 frame
= (struct sigframe
*) (long) regs
->regs
[29];
325 frame
= (struct sigframe
*)((unsigned long)frame
& ALMASK
);
327 if (verify_area(VERIFY_WRITE
, frame
, sizeof (*frame
)))
331 setup_trampoline(frame
->code
);
332 setup_sigcontext(regs
, &frame
->scc
, oldmask
);
334 regs
->regs
[4] = signr
; /* arguments */
335 regs
->regs
[5] = 0; /* should be cause */
336 regs
->regs
[6] = (long) frame
; /* ptr to sigcontext */
337 regs
->regs
[29] = (unsigned long) frame
; /* Stack pointer */
338 regs
->regs
[31] = (unsigned long) frame
->code
; /* Return address */
339 regs
->cp0_epc
= (unsigned long) ka
->sa
.sa_handler
; /* handler address */
340 regs
->regs
[25] = regs
->cp0_epc
; /* PIC shit... */
343 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%p ra=0x%p\n",
344 current
->comm
, current
->pid
, frame
, regs
->cp0_epc
, frame
->code
);
355 setup_rt_frame(struct k_sigaction
* ka
, struct pt_regs
*regs
,
356 int signr
, sigset_t
*oldmask
, siginfo_t
*info
)
358 printk("Aiee: setup_tr_frame wants to be written");
361 /* ------------------------------------------------------------------------- */
363 static inline void handle_signal(unsigned long sig
, struct k_sigaction
*ka
,
364 siginfo_t
*info
, sigset_t
*oldset
, struct pt_regs
* regs
)
366 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
367 setup_rt_frame(ka
, regs
, sig
, oldset
, info
);
369 setup_frame(ka
, regs
, sig
, oldset
);
371 if (ka
->sa
.sa_flags
& SA_ONESHOT
)
372 ka
->sa
.sa_handler
= SIG_DFL
;
373 if (!(ka
->sa
.sa_flags
& SA_NODEFER
)) {
374 spin_lock_irq(¤t
->sigmask_lock
);
375 sigorsets(¤t
->blocked
,¤t
->blocked
,&ka
->sa
.sa_mask
);
376 sigaddset(¤t
->blocked
,sig
);
377 recalc_sigpending(current
);
378 spin_unlock_irq(¤t
->sigmask_lock
);
382 static inline void syscall_restart(struct pt_regs
*regs
, struct k_sigaction
*ka
)
384 switch(regs
->regs
[0]) {
386 regs
->regs
[2] = EINTR
;
389 if(!(ka
->sa
.sa_flags
& SA_RESTART
)) {
390 regs
->regs
[2] = EINTR
;
394 case ERESTARTNOINTR
: /* Userland will reload $v0. */
395 regs
->regs
[7] = regs
->regs
[26];
399 regs
->regs
[0] = 0; /* Don't deal with this again. */
402 extern int do_irix_signal(sigset_t
*oldset
, struct pt_regs
*regs
);
404 asmlinkage
int do_signal(sigset_t
*oldset
, struct pt_regs
*regs
)
406 struct k_sigaction
*ka
;
409 #ifdef CONFIG_BINFMT_IRIX
410 if (current
->personality
!= PER_LINUX
) /* XXX */
411 return do_irix_signal(oldset
, regs
);
415 oldset
= ¤t
->blocked
;
420 spin_lock_irq(¤t
->sigmask_lock
);
421 signr
= dequeue_signal(¤t
->blocked
, &info
);
422 spin_unlock_irq(¤t
->sigmask_lock
);
427 if ((current
->flags
& PF_PTRACED
) && signr
!= SIGKILL
) {
428 /* Let the debugger run. */
429 current
->exit_code
= signr
;
430 current
->state
= TASK_STOPPED
;
431 notify_parent(current
, SIGCHLD
);
434 /* We're back. Did the debugger cancel the sig? */
435 if (!(signr
= current
->exit_code
))
437 current
->exit_code
= 0;
439 /* The debugger continued. Ignore SIGSTOP. */
440 if (signr
== SIGSTOP
)
443 /* Update the siginfo structure. Is this good? */
444 if (signr
!= info
.si_signo
) {
445 info
.si_signo
= signr
;
447 info
.si_code
= SI_USER
;
448 info
.si_pid
= current
->p_pptr
->pid
;
449 info
.si_uid
= current
->p_pptr
->uid
;
452 /* If the (new) signal is now blocked, requeue it. */
453 if (sigismember(¤t
->blocked
, signr
)) {
454 send_sig_info(signr
, &info
, current
);
459 ka
= ¤t
->sig
->action
[signr
-1];
460 if (ka
->sa
.sa_handler
== SIG_IGN
) {
461 if (signr
!= SIGCHLD
)
463 /* Check for SIGCHLD: it's special. */
464 while (sys_wait4(-1, NULL
, WNOHANG
, NULL
) > 0)
469 if (ka
->sa
.sa_handler
== SIG_DFL
) {
470 int exit_code
= signr
;
472 /* Init gets no signals it doesn't want. */
473 if (current
->pid
== 1)
477 case SIGCONT
: case SIGCHLD
: case SIGWINCH
:
480 case SIGTSTP
: case SIGTTIN
: case SIGTTOU
:
481 if (is_orphaned_pgrp(current
->pgrp
))
486 current
->state
= TASK_STOPPED
;
487 current
->exit_code
= signr
;
488 if (!(current
->p_pptr
->sig
->action
[SIGCHLD
-1].sa
.sa_flags
& SA_NOCLDSTOP
))
489 notify_parent(current
, SIGCHLD
);
493 case SIGQUIT
: case SIGILL
: case SIGTRAP
:
494 case SIGABRT
: case SIGFPE
: case SIGSEGV
:
496 if (do_coredump(signr
, regs
))
502 sigaddset(¤t
->signal
, signr
);
503 recalc_sigpending(current
);
504 current
->flags
|= PF_SIGNALED
;
511 syscall_restart(regs
, ka
);
512 /* Whee! Actually deliver the signal. */
513 handle_signal(signr
, ka
, &info
, oldset
, regs
);
518 * Who's code doesn't conform to the restartable syscall convention
519 * dies here!!! The li instruction, a single machine instruction,
520 * must directly be followed by the syscall instruction.
523 if (regs
->regs
[2] == ERESTARTNOHAND
||
524 regs
->regs
[2] == ERESTARTSYS
||
525 regs
->regs
[2] == ERESTARTNOINTR
) {
526 regs
->regs
[7] = regs
->regs
[26];
534 * Compatibility syscall. Can be replaced in libc.
536 asmlinkage
int sys_pause(void)
538 current
->state
= TASK_INTERRUPTIBLE
;
540 return -ERESTARTNOHAND
;