1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1991, 1992  Linus Torvalds
7 * Copyright (C) 1994 - 1999  Ralf Baechle
8 * Copyright (C) 1999 Silicon Graphics, Inc.
9 */
10#include <linux/config.h>
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
14#include <linux/smp_lock.h>
15#include <linux/kernel.h>
16#include <linux/personality.h>
17#include <linux/signal.h>
18#include <linux/errno.h>
19#include <linux/wait.h>
20#include <linux/unistd.h>
21
22#include <asm/asm.h>
23#include <asm/bitops.h>
24#include <asm/cpu.h>
25#include <asm/fpu.h>
26#include <asm/offset.h>
27#include <asm/pgalloc.h>
28#include <asm/ptrace.h>
29#include <asm/uaccess.h>
30#include <asm/ucontext.h>
31
32#define DEBUG_SIG 0
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36extern asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
37
38extern asmlinkage void syscall_trace(void);
39
40int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
41{
42	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
43		return -EFAULT;
44	if (from->si_code < 0)
45		return __copy_to_user(to, from, sizeof(siginfo_t));
46	else {
47		int err;
48
49		/* If you change siginfo_t structure, please be sure
50		   this code is fixed accordingly.
51		   It should never copy any pad contained in the structure
52		   to avoid security leaks, but must copy the generic
53		   3 ints plus the relevant union member.  */
54		err = __put_user(from->si_signo, &to->si_signo);
55		err |= __put_user(from->si_errno, &to->si_errno);
56		err |= __put_user((short)from->si_code, &to->si_code);
57		/* First 32bits of unions are always present.  */
58		err |= __put_user(from->si_pid, &to->si_pid);
59		switch (from->si_code >> 16) {
60		case __SI_FAULT >> 16:
61			break;
62		case __SI_CHLD >> 16:
63			err |= __put_user(from->si_utime, &to->si_utime);
64			err |= __put_user(from->si_stime, &to->si_stime);
65			err |= __put_user(from->si_status, &to->si_status);
66		default:
67			err |= __put_user(from->si_uid, &to->si_uid);
68			break;
69		/* case __SI_RT: This is not generated by the kernel as of now.  */
70		}
71		return err;
72	}
73}
74
75/*
76 * Atomically swap in the new signal mask, and wait for a signal.
77 */
78save_static_function(sys_sigsuspend);
79static_unused int _sys_sigsuspend(struct pt_regs regs)
80{
81	sigset_t *uset, saveset, newset;
82
83	uset = (sigset_t *) regs.regs[4];
84	if (copy_from_user(&newset, uset, sizeof(sigset_t)))
85		return -EFAULT;
86	sigdelsetmask(&newset, ~_BLOCKABLE);
87
88	spin_lock_irq(&current->sigmask_lock);
89	saveset = current->blocked;
90	current->blocked = newset;
91	recalc_sigpending(current);
92	spin_unlock_irq(&current->sigmask_lock);
93
94	regs.regs[2] = EINTR;
95	regs.regs[7] = 1;
96	while (1) {
97		current->state = TASK_INTERRUPTIBLE;
98		schedule();
99		if (do_signal(&saveset, &regs))
100			return -EINTR;
101	}
102}
103
104save_static_function(sys_rt_sigsuspend);
105static_unused int _sys_rt_sigsuspend(struct pt_regs regs)
106{
107	sigset_t *unewset, saveset, newset;
108        size_t sigsetsize;
109
110	sigsetsize = regs.regs[5];
111	if (sigsetsize != sizeof(sigset_t))
112		return -EINVAL;
113
114	unewset = (sigset_t *) regs.regs[4];
115	if (copy_from_user(&newset, unewset, sizeof(newset)))
116		return -EFAULT;
117	sigdelsetmask(&newset, ~_BLOCKABLE);
118
119	spin_lock_irq(&current->sigmask_lock);
120	saveset = current->blocked;
121	current->blocked = newset;
122        recalc_sigpending(current);
123	spin_unlock_irq(&current->sigmask_lock);
124
125	regs.regs[2] = EINTR;
126	regs.regs[7] = 1;
127	while (1) {
128		current->state = TASK_INTERRUPTIBLE;
129		schedule();
130		if (do_signal(&saveset, &regs))
131			return -EINTR;
132	}
133}
134
135asmlinkage int sys_sigaction(int sig, const struct sigaction *act,
136	struct sigaction *oact)
137{
138	struct k_sigaction new_ka, old_ka;
139	int ret;
140	int err = 0;
141
142	if (act) {
143		old_sigset_t mask;
144
145		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
146			return -EFAULT;
147		err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
148		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
149		err |= __get_user(mask, &act->sa_mask.sig[0]);
150		err |= __get_user(new_ka.sa.sa_restorer, &act->sa_restorer);
151		if (err)
152			return -EFAULT;
153
154		siginitset(&new_ka.sa.sa_mask, mask);
155	}
156
157	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
158
159	if (!ret && oact) {
160		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
161                        return -EFAULT;
162		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
163		err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
164		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
165                err |= __put_user(0, &oact->sa_mask.sig[1]);
166                err |= __put_user(0, &oact->sa_mask.sig[2]);
167                err |= __put_user(0, &oact->sa_mask.sig[3]);
168		err |= __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer);
169                if (err)
170			return -EFAULT;
171	}
172
173	return ret;
174}
175
176asmlinkage int sys_sigaltstack(struct pt_regs regs)
177{
178	const stack_t *uss = (const stack_t *) regs.regs[4];
179	stack_t *uoss = (stack_t *) regs.regs[5];
180	unsigned long usp = regs.regs[29];
181
182	return do_sigaltstack(uss, uoss, usp);
183}
184
185static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
186{
187	int err = 0;
188	u64 reg;
189
190	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
191
192	err |= __get_user(reg, &sc->sc_mdhi);
193	regs->hi = (int) reg;
194	err |= __get_user(reg, &sc->sc_mdlo);
195	regs->lo = (int) reg;
196
197#define restore_gp_reg(i) do {						\
198	err |= __get_user(reg, &sc->sc_regs[i]);			\
199	regs->regs[i] = reg;						\
200} while(0)
201	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
202	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
203	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
204	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
205	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
206	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
207	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
208	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
209	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
210	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
211	restore_gp_reg(31);
212#undef restore_gp_reg
213
214	err |= __get_user(current->used_math, &sc->sc_used_math);
215
216	if (current->used_math) {
217		/* restore fpu context if we have used it before */
218		own_fpu();
219		err |= restore_fp_context(sc);
220	} else {
221		/* signal handler may have used FPU.  Give it up. */
222		loose_fpu();
223	}
224
225	return err;
226}
227
228struct sigframe {
229	u32 sf_ass[4];			/* argument save space for o32 */
230	u32 sf_code[2];			/* signal trampoline */
231	struct sigcontext sf_sc;
232	sigset_t sf_mask;
233};
234
235struct rt_sigframe {
236	u32 rs_ass[4];			/* argument save space for o32 */
237	u32 rs_code[2];			/* signal trampoline */
238	struct siginfo rs_info;
239	struct ucontext rs_uc;
240};
241
242asmlinkage void sys_sigreturn(struct pt_regs regs)
243{
244	struct sigframe *frame;
245	sigset_t blocked;
246
247	frame = (struct sigframe *) regs.regs[29];
248	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
249		goto badframe;
250	if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
251		goto badframe;
252
253	sigdelsetmask(&blocked, ~_BLOCKABLE);
254	spin_lock_irq(&current->sigmask_lock);
255	current->blocked = blocked;
256	recalc_sigpending(current);
257	spin_unlock_irq(&current->sigmask_lock);
258
259	if (restore_sigcontext(&regs, &frame->sf_sc))
260		goto badframe;
261
262	/*
263	 * Don't let your children do this ...
264	 */
265	if (current->ptrace & PT_TRACESYS)
266		syscall_trace();
267	__asm__ __volatile__(
268		"move\t$29, %0\n\t"
269		"j\tret_from_sys_call"
270		:/* no outputs */
271		:"r" (&regs));
272	/* Unreached */
273
274badframe:
275	force_sig(SIGSEGV, current);
276}
277
278asmlinkage void sys_rt_sigreturn(struct pt_regs regs)
279{
280	struct rt_sigframe *frame;
281	sigset_t set;
282	stack_t st;
283
284	frame = (struct rt_sigframe *) regs.regs[29];
285	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
286		goto badframe;
287	if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
288		goto badframe;
289
290	sigdelsetmask(&set, ~_BLOCKABLE);
291	spin_lock_irq(&current->sigmask_lock);
292	current->blocked = set;
293	recalc_sigpending(current);
294	spin_unlock_irq(&current->sigmask_lock);
295
296	if (restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext))
297		goto badframe;
298
299	if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
300		goto badframe;
301	/* It is more difficult to avoid calling this function than to
302	   call it and ignore errors.  */
303	do_sigaltstack(&st, NULL, regs.regs[29]);
304
305	/*
306	 * Don't let your children do this ...
307	 */
308	__asm__ __volatile__(
309		"move\t$29, %0\n\t"
310		"j\tret_from_sys_call"
311		:/* no outputs */
312		:"r" (&regs));
313	/* Unreached */
314
315badframe:
316	force_sig(SIGSEGV, current);
317}
318
319static int inline setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
320{
321	int err = 0;
322	u64 reg;
323
324	reg = regs->cp0_epc; err |= __put_user(reg, &sc->sc_pc);
325	err |= __put_user(regs->cp0_status, &sc->sc_status);
326
327#define save_gp_reg(i) {						\
328	reg = regs->regs[i];						\
329	err |= __put_user(reg, &sc->sc_regs[i]);			\
330} while(0)
331	reg = 0; err |= __put_user(reg, &sc->sc_regs[0]);
332	save_gp_reg(1); save_gp_reg(2);
333	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
334	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
335	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
336	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
337	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
338	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
339	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
340	save_gp_reg(31);
341#undef save_gp_reg
342
343	reg = regs->hi; err |= __put_user(reg, &sc->sc_mdhi);
344	reg = regs->lo; err |= __put_user(reg, &sc->sc_mdlo);
345	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
346	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
347
348	err |= __put_user(current->used_math, &sc->sc_used_math);
349
350	if (!current->used_math)
351		goto out;
352
353	/*
354	 * Save FPU state to signal context.  Signal handler will "inherit"
355	 * current FPU state.
356	 */
357	if (!is_fpu_owner()) {
358		own_fpu();
359		restore_fp(current);
360	}
361	err |= save_fp_context(sc);
362
363out:
364	return err;
365}
366
367/*
368 * Determine which stack to use..
369 */
370static inline void * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
371	size_t frame_size)
372{
373	unsigned long sp;
374
375	/* Default to using normal stack */
376	sp = regs->regs[29];
377
378	/*
379 	 * FPU emulator may have it's own trampoline active just
380 	 * above the user stack, 16-bytes before the next lowest
381 	 * 16 byte boundary.  Try to avoid trashing it.
382 	 */
383 	sp -= 32;
384
385	/* This is the X/Open sanctioned signal stack switching.  */
386	if ((ka->sa.sa_flags & SA_ONSTACK) && ! on_sig_stack(sp))
387                sp = current->sas_ss_sp + current->sas_ss_size;
388
389	return (void *)((sp - frame_size) & ALMASK);
390}
391
392static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
393	int signr, sigset_t *set)
394{
395	struct sigframe *frame;
396	int err = 0;
397
398	frame = get_sigframe(ka, regs, sizeof(*frame));
399	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
400		goto give_sigsegv;
401
402	/* Set up to return from userspace.  If provided, use a stub already
403	   in userspace.  */
404	if (ka->sa.sa_flags & SA_RESTORER)
405		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
406	else {
407		/*
408		 * Set up the return code ...
409		 *
410		 *         li      v0, __NR_sigreturn
411		 *         syscall
412		 */
413		err |= __put_user(0x24020000 + __NR_sigreturn,
414		                  frame->sf_code + 0);
415		err |= __put_user(0x0000000c                 ,
416		                  frame->sf_code + 1);
417		flush_cache_sigtramp((unsigned long) frame->sf_code);
418	}
419
420	err |= setup_sigcontext(regs, &frame->sf_sc);
421	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
422	if (err)
423		goto give_sigsegv;
424
425	/*
426	 * Arguments to signal handler:
427	 *
428	 *   a0 = signal number
429	 *   a1 = 0 (should be cause)
430	 *   a2 = pointer to struct sigcontext
431	 *
432	 * $25 and c0_epc point to the signal handler, $29 points to the
433	 * struct sigframe.
434	 */
435	regs->regs[ 4] = signr;
436	regs->regs[ 5] = 0;
437	regs->regs[ 6] = (unsigned long) &frame->sf_sc;
438	regs->regs[29] = (unsigned long) frame;
439	regs->regs[31] = (unsigned long) frame->sf_code;
440	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
441
442#if DEBUG_SIG
443	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
444	       current->comm, current->pid,
445	       frame, regs->cp0_epc, frame->sf_code);
446#endif
447        return;
448
449give_sigsegv:
450	if (signr == SIGSEGV)
451		ka->sa.sa_handler = SIG_DFL;
452	force_sig(SIGSEGV, current);
453}
454
455static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
456	int signr, sigset_t *set, siginfo_t *info)
457{
458	struct rt_sigframe *frame;
459	int err = 0;
460
461	frame = get_sigframe(ka, regs, sizeof(*frame));
462	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
463		goto give_sigsegv;
464
465	/* Set up to return from userspace.  If provided, use a stub already
466	   in userspace.  */
467	if (ka->sa.sa_flags & SA_RESTORER)
468		regs->regs[31] = (unsigned long) ka->sa.sa_restorer;
469	else {
470		/*
471		 * Set up the return code ...
472		 *
473		 *         li      v0, __NR_rt_sigreturn
474		 *         syscall
475		 */
476		err |= __put_user(0x24020000 + __NR_rt_sigreturn,
477		                  frame->rs_code + 0);
478		err |= __put_user(0x0000000c                 ,
479		                  frame->rs_code + 1);
480		flush_cache_sigtramp((unsigned long) frame->rs_code);
481	}
482
483	/* Create siginfo.  */
484	err |= copy_siginfo_to_user(&frame->rs_info, info);
485
486	/* Create the ucontext.  */
487	err |= __put_user(0, &frame->rs_uc.uc_flags);
488	err |= __put_user(0, &frame->rs_uc.uc_link);
489	err |= __put_user((void *)current->sas_ss_sp,
490	                  &frame->rs_uc.uc_stack.ss_sp);
491	err |= __put_user(sas_ss_flags(regs->regs[29]),
492	                  &frame->rs_uc.uc_stack.ss_flags);
493	err |= __put_user(current->sas_ss_size,
494	                  &frame->rs_uc.uc_stack.ss_size);
495	err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
496	err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
497
498	if (err)
499		goto give_sigsegv;
500
501	/*
502	 * Arguments to signal handler:
503	 *
504	 *   a0 = signal number
505	 *   a1 = 0 (should be cause)
506	 *   a2 = pointer to ucontext
507	 *
508	 * $25 and c0_epc point to the signal handler, $29 points to
509	 * the struct rt_sigframe.
510	 */
511	regs->regs[ 4] = signr;
512	regs->regs[ 5] = (unsigned long) &frame->rs_info;
513	regs->regs[ 6] = (unsigned long) &frame->rs_uc;
514	regs->regs[29] = (unsigned long) frame;
515	regs->regs[31] = (unsigned long) frame->rs_code;
516	regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
517
518#if DEBUG_SIG
519	printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
520	       current->comm, current->pid,
521	       frame, regs->cp0_epc, frame->rs_code);
522#endif
523	return;
524
525give_sigsegv:
526	if (signr == SIGSEGV)
527		ka->sa.sa_handler = SIG_DFL;
528	force_sig(SIGSEGV, current);
529}
530
531static inline void handle_signal(unsigned long sig, struct k_sigaction *ka,
532	siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
533{
534	if (ka->sa.sa_flags & SA_SIGINFO)
535		setup_rt_frame(ka, regs, sig, oldset, info);
536	else
537		setup_frame(ka, regs, sig, oldset);
538
539	if (ka->sa.sa_flags & SA_ONESHOT)
540		ka->sa.sa_handler = SIG_DFL;
541	if (!(ka->sa.sa_flags & SA_NODEFER)) {
542		spin_lock_irq(&current->sigmask_lock);
543		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
544		sigaddset(&current->blocked,sig);
545		recalc_sigpending(current);
546		spin_unlock_irq(&current->sigmask_lock);
547	}
548}
549
550static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
551{
552	switch(regs->regs[0]) {
553	case ERESTARTNOHAND:
554		regs->regs[2] = EINTR;
555		break;
556	case ERESTARTSYS:
557		if(!(ka->sa.sa_flags & SA_RESTART)) {
558			regs->regs[2] = EINTR;
559			break;
560		}
561	/* fallthrough */
562	case ERESTARTNOINTR:		/* Userland will reload $v0.  */
563		regs->regs[7] = regs->regs[26];
564		regs->cp0_epc -= 8;
565	}
566
567	regs->regs[0] = 0;		/* Don't deal with this again.  */
568}
569
570extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs);
571
572asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
573{
574	struct k_sigaction *ka;
575	siginfo_t info;
576
577#ifdef CONFIG_BINFMT_IRIX
578	if (current->personality != PER_LINUX)
579		return do_irix_signal(oldset, regs);
580#endif
581
582	if (!oldset)
583		oldset = &current->blocked;
584
585	for (;;) {
586		unsigned long signr;
587
588		spin_lock_irq(&current->sigmask_lock);
589		signr = dequeue_signal(&current->blocked, &info);
590		spin_unlock_irq(&current->sigmask_lock);
591
592		if (!signr)
593			break;
594
595		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
596			/* Let the debugger run.  */
597			current->exit_code = signr;
598			current->state = TASK_STOPPED;
599			notify_parent(current, SIGCHLD);
600			schedule();
601
602			/* We're back.  Did the debugger cancel the sig?  */
603			if (!(signr = current->exit_code))
604				continue;
605			current->exit_code = 0;
606
607			/* The debugger continued.  Ignore SIGSTOP.  */
608			if (signr == SIGSTOP)
609				continue;
610
611			/* Update the siginfo structure.  Is this good?  */
612			if (signr != info.si_signo) {
613				info.si_signo = signr;
614				info.si_errno = 0;
615				info.si_code = SI_USER;
616				info.si_pid = current->p_pptr->pid;
617				info.si_uid = current->p_pptr->uid;
618			}
619
620			/* If the (new) signal is now blocked, requeue it.  */
621			if (sigismember(&current->blocked, signr)) {
622				send_sig_info(signr, &info, current);
623				continue;
624			}
625		}
626
627		ka = &current->sig->action[signr-1];
628		if (ka->sa.sa_handler == SIG_IGN) {
629			if (signr != SIGCHLD)
630				continue;
631			/* Check for SIGCHLD: it's special.  */
632			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
633				/* nothing */;
634			continue;
635		}
636
637		if (ka->sa.sa_handler == SIG_DFL) {
638			int exit_code = signr;
639
640			/* Init gets no signals it doesn't want.  */
641			if (current->pid == 1)
642				continue;
643
644			switch (signr) {
645			case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
646				continue;
647
648			case SIGTSTP: case SIGTTIN: case SIGTTOU:
649				if (is_orphaned_pgrp(current->pgrp))
650					continue;
651				/* FALLTHRU */
652
653			case SIGSTOP:
654				current->state = TASK_STOPPED;
655				current->exit_code = signr;
656				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
657					notify_parent(current, SIGCHLD);
658				schedule();
659				continue;
660
661			case SIGQUIT: case SIGILL: case SIGTRAP:
662			case SIGABRT: case SIGFPE: case SIGSEGV:
663			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
664				if (do_coredump(signr, regs))
665					exit_code |= 0x80;
666				/* FALLTHRU */
667
668			default:
669				sig_exit(signr, exit_code, &info);
670				/* NOTREACHED */
671			}
672		}
673
674		if (regs->regs[0])
675			syscall_restart(regs, ka);
676		/* Whee!  Actually deliver the signal.  */
677		handle_signal(signr, ka, &info, oldset, regs);
678		return 1;
679	}
680
681	/*
682	 * Who's code doesn't conform to the restartable syscall convention
683	 * dies here!!!  The li instruction, a single machine instruction,
684	 * must directly be followed by the syscall instruction.
685	 */
686	if (regs->regs[0]) {
687		if (regs->regs[2] == ERESTARTNOHAND ||
688		    regs->regs[2] == ERESTARTSYS ||
689		    regs->regs[2] == ERESTARTNOINTR) {
690			regs->regs[7] = regs->regs[26];
691			regs->cp0_epc -= 8;
692		}
693	}
694	return 0;
695}
696