File: /usr/src/linux/arch/alpha/kernel/signal.c

1     /*
2      *  linux/arch/alpha/kernel/signal.c
3      *
4      *  Copyright (C) 1995  Linus Torvalds
5      *
6      *  1997-11-02  Modified for POSIX.1b signals by Richard Henderson
7      */
8     
9     #include <linux/sched.h>
10     #include <linux/kernel.h>
11     #include <linux/signal.h>
12     #include <linux/errno.h>
13     #include <linux/wait.h>
14     #include <linux/ptrace.h>
15     #include <linux/unistd.h>
16     #include <linux/mm.h>
17     #include <linux/smp.h>
18     #include <linux/smp_lock.h>
19     #include <linux/stddef.h>
20     
21     #include <asm/bitops.h>
22     #include <asm/uaccess.h>
23     #include <asm/sigcontext.h>
24     #include <asm/ucontext.h>
25     
26     #include "proto.h"
27     
28     
29     #define DEBUG_SIG 0
30     
31     #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
32     
33     asmlinkage void ret_from_sys_call(void);
34     asmlinkage int do_signal(sigset_t *, struct pt_regs *,
35     			 struct switch_stack *, unsigned long, unsigned long);
36     
37     
38     int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
39     {
40     	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
41     		return -EFAULT;
42     	if (from->si_code < 0)
43     		return __copy_to_user(to, from, sizeof(siginfo_t));
44     	else {
45     		int err;
46     
47     		/* If you change siginfo_t structure, please be sure
48     		   this code is fixed accordingly.
49     		   It should never copy any pad contained in the structure
50     		   to avoid security leaks, but must copy the generic
51     		   3 ints plus the relevant union member.  */
52     		err = __put_user(*(long *)&from->si_signo, (long *)&to->si_signo);
53     		err |= __put_user((short)from->si_code, &to->si_code);
54     		switch (from->si_code >> 16) {
55     		case __SI_CHLD >> 16:
56     			err |= __put_user(from->si_utime, &to->si_utime);
57     			err |= __put_user(from->si_stime, &to->si_stime);
58     			err |= __put_user(from->si_status, &to->si_status);
59     		default:
60     			err |= __put_user(from->si_addr, &to->si_addr);
61     			break;
62     		/* case __SI_RT: This is not generated by the kernel as of now.  */
63     		}
64     		return err;
65     	}
66     }
67     
68     /*
69      * The OSF/1 sigprocmask calling sequence is different from the
70      * C sigprocmask() sequence..
71      *
72      * how:
73      * 1 - SIG_BLOCK
74      * 2 - SIG_UNBLOCK
75      * 3 - SIG_SETMASK
76      *
77      * We change the range to -1 .. 1 in order to let gcc easily
78      * use the conditional move instructions.
79      *
80      * Note that we don't need to acquire the kernel lock for SMP
81      * operation, as all of this is local to this thread.
82      */
83     asmlinkage unsigned long
84     osf_sigprocmask(int how, unsigned long newmask, long a2, long a3,
85     		long a4, long a5, struct pt_regs regs)
86     {
87     	unsigned long oldmask = -EINVAL;
88     
89     	if ((unsigned long)how-1 <= 2) {
90     		long sign = how-2;		/* -1 .. 1 */
91     		unsigned long block, unblock;
92     
93     		newmask &= _BLOCKABLE;
94     		spin_lock_irq(&current->sigmask_lock);
95     		oldmask = current->blocked.sig[0];
96     
97     		unblock = oldmask & ~newmask;
98     		block = oldmask | newmask;
99     		if (!sign)
100     			block = unblock;
101     		if (sign <= 0)
102     			newmask = block;
103     		if (_NSIG_WORDS > 1 && sign > 0)
104     			sigemptyset(&current->blocked);
105     		current->blocked.sig[0] = newmask;
106     		recalc_sigpending(current);
107     		spin_unlock_irq(&current->sigmask_lock);
108     
109     		(&regs)->r0 = 0;		/* special no error return */
110     	}
111     	return oldmask;
112     }
113     
114     asmlinkage int 
115     osf_sigaction(int sig, const struct osf_sigaction *act,
116     	      struct osf_sigaction *oact)
117     {
118     	struct k_sigaction new_ka, old_ka;
119     	int ret;
120     
121     	if (act) {
122     		old_sigset_t mask;
123     		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
124     		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
125     		    __get_user(new_ka.sa.sa_flags, &act->sa_flags))
126     			return -EFAULT;
127     		__get_user(mask, &act->sa_mask);
128     		siginitset(&new_ka.sa.sa_mask, mask);
129     		new_ka.ka_restorer = NULL;
130     	}
131     
132     	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
133     
134     	if (!ret && oact) {
135     		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
136     		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
137     		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
138     			return -EFAULT;
139     		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
140     	}
141     
142     	return ret;
143     }
144     
145     asmlinkage int 
146     sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
147     		 size_t sigsetsize, void *restorer)
148     {
149     	struct k_sigaction new_ka, old_ka;
150     	int ret;
151     
152     	/* XXX: Don't preclude handling different sized sigset_t's.  */
153     	if (sigsetsize != sizeof(sigset_t))
154     		return -EINVAL;
155     
156     	if (act) {
157     		new_ka.ka_restorer = restorer;
158     		if (copy_from_user(&new_ka.sa, act, sizeof(*act)))
159     			return -EFAULT;
160     	}
161     
162     	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
163     
164     	if (!ret && oact) {
165     		if (copy_to_user(oact, &old_ka.sa, sizeof(*oact)))
166     			return -EFAULT;
167     	}
168     
169     	return ret;
170     }
171     
172     /*
173      * Atomically swap in the new signal mask, and wait for a signal.
174      */
175     asmlinkage int
176     do_sigsuspend(old_sigset_t mask, struct pt_regs *reg, struct switch_stack *sw)
177     {
178     	sigset_t oldset;
179     
180     	mask &= _BLOCKABLE;
181     	spin_lock_irq(&current->sigmask_lock);
182     	oldset = current->blocked;
183     	siginitset(&current->blocked, mask);
184     	recalc_sigpending(current);
185     	spin_unlock_irq(&current->sigmask_lock);
186     
187     	while (1) {
188     		current->state = TASK_INTERRUPTIBLE;
189     		schedule();
190     		if (do_signal(&oldset, reg, sw, 0, 0))
191     			return -EINTR;
192     	}
193     }
194     
195     asmlinkage int
196     do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize,
197     		 struct pt_regs *reg, struct switch_stack *sw)
198     {
199     	sigset_t oldset, set;
200     
201     	/* XXX: Don't preclude handling different sized sigset_t's.  */
202     	if (sigsetsize != sizeof(sigset_t))
203     		return -EINVAL;
204     	if (copy_from_user(&set, uset, sizeof(set)))
205     		return -EFAULT;
206     
207     	sigdelsetmask(&set, ~_BLOCKABLE);
208     	spin_lock_irq(&current->sigmask_lock);
209     	oldset = current->blocked;
210     	current->blocked = set;
211     	recalc_sigpending(current);
212     	spin_unlock_irq(&current->sigmask_lock);
213     
214     	while (1) {
215     		current->state = TASK_INTERRUPTIBLE;
216     		schedule();
217     		if (do_signal(&oldset, reg, sw, 0, 0))
218     			return -EINTR;
219     	}
220     }
221     
222     asmlinkage int
223     sys_sigaltstack(const stack_t *uss, stack_t *uoss)
224     {
225     	return do_sigaltstack(uss, uoss, rdusp());
226     }
227     
228     /*
229      * Do a signal return; undo the signal stack.
230      */
231     
232     struct sigframe
233     {
234     	struct sigcontext sc;
235     	unsigned long extramask[_NSIG_WORDS-1];
236     	unsigned int retcode[3];
237     };
238     
239     struct rt_sigframe
240     {
241     	struct siginfo info;
242     	struct ucontext uc;
243     	unsigned int retcode[3];
244     };
245     
246     #define INSN_MOV_R30_R16	0x47fe0410
247     #define INSN_LDI_R0		0x201f0000
248     #define INSN_CALLSYS		0x00000083
249     
250     static long
251     restore_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
252     		   struct switch_stack *sw)
253     {
254     	unsigned long usp;
255     	long i, err = 0;
256     
257     	err |= __get_user(regs->pc, &sc->sc_pc);
258     	sw->r26 = (unsigned long) ret_from_sys_call;
259     
260     	err |= __get_user(regs->r0, sc->sc_regs+0);
261     	err |= __get_user(regs->r1, sc->sc_regs+1);
262     	err |= __get_user(regs->r2, sc->sc_regs+2);
263     	err |= __get_user(regs->r3, sc->sc_regs+3);
264     	err |= __get_user(regs->r4, sc->sc_regs+4);
265     	err |= __get_user(regs->r5, sc->sc_regs+5);
266     	err |= __get_user(regs->r6, sc->sc_regs+6);
267     	err |= __get_user(regs->r7, sc->sc_regs+7);
268     	err |= __get_user(regs->r8, sc->sc_regs+8);
269     	err |= __get_user(sw->r9, sc->sc_regs+9);
270     	err |= __get_user(sw->r10, sc->sc_regs+10);
271     	err |= __get_user(sw->r11, sc->sc_regs+11);
272     	err |= __get_user(sw->r12, sc->sc_regs+12);
273     	err |= __get_user(sw->r13, sc->sc_regs+13);
274     	err |= __get_user(sw->r14, sc->sc_regs+14);
275     	err |= __get_user(sw->r15, sc->sc_regs+15);
276     	err |= __get_user(regs->r16, sc->sc_regs+16);
277     	err |= __get_user(regs->r17, sc->sc_regs+17);
278     	err |= __get_user(regs->r18, sc->sc_regs+18);
279     	err |= __get_user(regs->r19, sc->sc_regs+19);
280     	err |= __get_user(regs->r20, sc->sc_regs+20);
281     	err |= __get_user(regs->r21, sc->sc_regs+21);
282     	err |= __get_user(regs->r22, sc->sc_regs+22);
283     	err |= __get_user(regs->r23, sc->sc_regs+23);
284     	err |= __get_user(regs->r24, sc->sc_regs+24);
285     	err |= __get_user(regs->r25, sc->sc_regs+25);
286     	err |= __get_user(regs->r26, sc->sc_regs+26);
287     	err |= __get_user(regs->r27, sc->sc_regs+27);
288     	err |= __get_user(regs->r28, sc->sc_regs+28);
289     	err |= __get_user(regs->gp, sc->sc_regs+29);
290     	err |= __get_user(usp, sc->sc_regs+30);
291     	wrusp(usp);
292     
293     	for (i = 0; i < 31; i++)
294     		err |= __get_user(sw->fp[i], sc->sc_fpregs+i);
295     	err |= __get_user(sw->fp[31], &sc->sc_fpcr);
296     
297     	return err;
298     }
299     
300     asmlinkage void
301     do_sigreturn(struct sigframe *frame, struct pt_regs *regs,
302     	     struct switch_stack *sw)
303     {
304     	sigset_t set;
305     
306     	/* Verify that it's a good sigcontext before using it */
307     	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
308     		goto give_sigsegv;
309     	if (__get_user(set.sig[0], &frame->sc.sc_mask)
310     	    || (_NSIG_WORDS > 1
311     		&& __copy_from_user(&set.sig[1], &frame->extramask,
312     				    sizeof(frame->extramask))))
313     		goto give_sigsegv;
314     
315     	sigdelsetmask(&set, ~_BLOCKABLE);
316     	spin_lock_irq(&current->sigmask_lock);
317     	current->blocked = set;
318     	recalc_sigpending(current);
319     	spin_unlock_irq(&current->sigmask_lock);
320     
321     	if (restore_sigcontext(&frame->sc, regs, sw))
322     		goto give_sigsegv;
323     
324     	/* Send SIGTRAP if we're single-stepping: */
325     	if (ptrace_cancel_bpt (current))
326     		send_sig(SIGTRAP, current, 1);
327     	return;
328     
329     give_sigsegv:
330     	force_sig(SIGSEGV, current);
331     }
332     
333     asmlinkage void
334     do_rt_sigreturn(struct rt_sigframe *frame, struct pt_regs *regs,
335     		struct switch_stack *sw)
336     {
337     	sigset_t set;
338     	stack_t st;
339     
340     	/* Verify that it's a good sigcontext before using it */
341     	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
342     		goto give_sigsegv;
343     	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
344     		goto give_sigsegv;
345     
346     	sigdelsetmask(&set, ~_BLOCKABLE);
347     	spin_lock_irq(&current->sigmask_lock);
348     	current->blocked = set;
349     	recalc_sigpending(current);
350     	spin_unlock_irq(&current->sigmask_lock);
351     
352     	if (restore_sigcontext(&frame->uc.uc_mcontext, regs, sw))
353     		goto give_sigsegv;
354     
355     	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
356     		goto give_sigsegv;
357     	/* It is more difficult to avoid calling this function than to
358     	   call it and ignore errors.  */
359     	do_sigaltstack(&st, NULL, rdusp());
360     
361     	/* Send SIGTRAP if we're single-stepping: */
362     	if (ptrace_cancel_bpt (current))
363     		send_sig(SIGTRAP, current, 1);
364     	return;
365     
366     give_sigsegv:
367     	force_sig(SIGSEGV, current);
368     }
369     
370     
371     /*
372      * Set up a signal frame.
373      */
374     
375     static inline void *
376     get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
377     {
378     	if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
379     		sp = current->sas_ss_sp + current->sas_ss_size;
380     
381     	return (void *)((sp - frame_size) & -32ul);
382     }
383     
384     static long
385     setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 
386     		 struct switch_stack *sw, unsigned long mask, unsigned long sp)
387     {
388     	long i, err = 0;
389     
390     	err |= __put_user(on_sig_stack((unsigned long)sc), &sc->sc_onstack);
391     	err |= __put_user(mask, &sc->sc_mask);
392     	err |= __put_user(regs->pc, &sc->sc_pc);
393     	err |= __put_user(8, &sc->sc_ps);
394     
395     	err |= __put_user(regs->r0 , sc->sc_regs+0);
396     	err |= __put_user(regs->r1 , sc->sc_regs+1);
397     	err |= __put_user(regs->r2 , sc->sc_regs+2);
398     	err |= __put_user(regs->r3 , sc->sc_regs+3);
399     	err |= __put_user(regs->r4 , sc->sc_regs+4);
400     	err |= __put_user(regs->r5 , sc->sc_regs+5);
401     	err |= __put_user(regs->r6 , sc->sc_regs+6);
402     	err |= __put_user(regs->r7 , sc->sc_regs+7);
403     	err |= __put_user(regs->r8 , sc->sc_regs+8);
404     	err |= __put_user(sw->r9   , sc->sc_regs+9);
405     	err |= __put_user(sw->r10  , sc->sc_regs+10);
406     	err |= __put_user(sw->r11  , sc->sc_regs+11);
407     	err |= __put_user(sw->r12  , sc->sc_regs+12);
408     	err |= __put_user(sw->r13  , sc->sc_regs+13);
409     	err |= __put_user(sw->r14  , sc->sc_regs+14);
410     	err |= __put_user(sw->r15  , sc->sc_regs+15);
411     	err |= __put_user(regs->r16, sc->sc_regs+16);
412     	err |= __put_user(regs->r17, sc->sc_regs+17);
413     	err |= __put_user(regs->r18, sc->sc_regs+18);
414     	err |= __put_user(regs->r19, sc->sc_regs+19);
415     	err |= __put_user(regs->r20, sc->sc_regs+20);
416     	err |= __put_user(regs->r21, sc->sc_regs+21);
417     	err |= __put_user(regs->r22, sc->sc_regs+22);
418     	err |= __put_user(regs->r23, sc->sc_regs+23);
419     	err |= __put_user(regs->r24, sc->sc_regs+24);
420     	err |= __put_user(regs->r25, sc->sc_regs+25);
421     	err |= __put_user(regs->r26, sc->sc_regs+26);
422     	err |= __put_user(regs->r27, sc->sc_regs+27);
423     	err |= __put_user(regs->r28, sc->sc_regs+28);
424     	err |= __put_user(regs->gp , sc->sc_regs+29);
425     	err |= __put_user(sp, sc->sc_regs+30);
426     	err |= __put_user(0, sc->sc_regs+31);
427     
428     	for (i = 0; i < 31; i++)
429     		err |= __put_user(sw->fp[i], sc->sc_fpregs+i);
430     	err |= __put_user(0, sc->sc_fpregs+31);
431     	err |= __put_user(sw->fp[31], &sc->sc_fpcr);
432     
433     	err |= __put_user(regs->trap_a0, &sc->sc_traparg_a0);
434     	err |= __put_user(regs->trap_a1, &sc->sc_traparg_a1);
435     	err |= __put_user(regs->trap_a2, &sc->sc_traparg_a2);
436     
437     	return err;
438     }
439     
440     static void
441     setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
442     	    struct pt_regs *regs, struct switch_stack * sw)
443     {
444     	unsigned long oldsp, r26, err = 0;
445     	struct sigframe *frame;
446     
447     	oldsp = rdusp();
448     	frame = get_sigframe(ka, oldsp, sizeof(*frame));
449     	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
450     		goto give_sigsegv;
451     
452     	err |= setup_sigcontext(&frame->sc, regs, sw, set->sig[0], oldsp);
453     	if (_NSIG_WORDS > 1) {
454     		err |= __copy_to_user(frame->extramask, &set->sig[1], 
455     				      sizeof(frame->extramask));
456     	}
457     	if (err)
458     		goto give_sigsegv;
459     
460     	/* Set up to return from userspace.  If provided, use a stub
461     	   already in userspace.  */
462     	if (ka->ka_restorer) {
463     		r26 = (unsigned long) ka->ka_restorer;
464     	} else {
465     		err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
466     		err |= __put_user(INSN_LDI_R0+__NR_sigreturn, frame->retcode+1);
467     		err |= __put_user(INSN_CALLSYS, frame->retcode+2);
468     		imb();
469     		r26 = (unsigned long) frame->retcode;
470     	}
471     
472     	/* Check that everything was written properly.  */
473     	if (err)
474     		goto give_sigsegv;
475     
476     	/* "Return" to the handler */
477     	regs->r26 = r26;
478     	regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
479     	regs->r16 = sig;			/* a0: signal number */
480     	regs->r17 = 0;				/* a1: exception code */
481     	regs->r18 = (unsigned long) &frame->sc;	/* a2: sigcontext pointer */
482     	wrusp((unsigned long) frame);
483     	
484     #if DEBUG_SIG
485     	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
486     		current->comm, current->pid, frame, regs->pc, regs->r26);
487     #endif
488     
489     	return;
490     
491     give_sigsegv:
492     	if (sig == SIGSEGV)
493     		ka->sa.sa_handler = SIG_DFL;
494     	force_sig(SIGSEGV, current);
495     }
496     
497     static void
498     setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
499     	       sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
500     {
501     	unsigned long oldsp, r26, err = 0;
502     	struct rt_sigframe *frame;
503     
504     	oldsp = rdusp();
505     	frame = get_sigframe(ka, oldsp, sizeof(*frame));
506     	if (verify_area(VERIFY_WRITE, frame, sizeof(*frame)))
507     		goto give_sigsegv;
508     
509     	err |= copy_siginfo_to_user(&frame->info, info);
510     
511     	/* Create the ucontext.  */
512     	err |= __put_user(0, &frame->uc.uc_flags);
513     	err |= __put_user(0, &frame->uc.uc_link);
514     	err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
515     	err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
516     	err |= __put_user(sas_ss_flags(oldsp), &frame->uc.uc_stack.ss_flags);
517     	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
518     	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, sw,
519     				set->sig[0], oldsp);
520     	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
521     	if (err)
522     		goto give_sigsegv;
523     
524     	/* Set up to return from userspace.  If provided, use a stub
525     	   already in userspace.  */
526     	if (ka->ka_restorer) {
527     		r26 = (unsigned long) ka->ka_restorer;
528     	} else {
529     		err |= __put_user(INSN_MOV_R30_R16, frame->retcode+0);
530     		err |= __put_user(INSN_LDI_R0+__NR_rt_sigreturn,
531     				  frame->retcode+1);
532     		err |= __put_user(INSN_CALLSYS, frame->retcode+2);
533     		imb();
534     		r26 = (unsigned long) frame->retcode;
535     	}
536     
537     	if (err)
538     		goto give_sigsegv;
539     
540     	/* "Return" to the handler */
541     	regs->r26 = r26;
542     	regs->r27 = regs->pc = (unsigned long) ka->sa.sa_handler;
543     	regs->r16 = sig;			  /* a0: signal number */
544     	regs->r17 = (unsigned long) &frame->info; /* a1: siginfo pointer */
545     	regs->r18 = (unsigned long) &frame->uc;	  /* a2: ucontext pointer */
546     	wrusp((unsigned long) frame);
547     
548     #if DEBUG_SIG
549     	printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
550     		current->comm, current->pid, frame, regs->pc, regs->r26);
551     #endif
552     
553     	return;
554     
555     give_sigsegv:
556     	if (sig == SIGSEGV)
557     		ka->sa.sa_handler = SIG_DFL;
558     	force_sig(SIGSEGV, current);
559     }
560     
561     
562     /*
563      * OK, we're invoking a handler.
564      */
565     static inline void
566     handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
567     	      sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
568     {
569     	if (ka->sa.sa_flags & SA_SIGINFO)
570     		setup_rt_frame(sig, ka, info, oldset, regs, sw);
571     	else
572     		setup_frame(sig, ka, oldset, regs, sw);
573     
574     	if (ka->sa.sa_flags & SA_RESETHAND)
575     		ka->sa.sa_handler = SIG_DFL;
576     
577     	if (!(ka->sa.sa_flags & SA_NODEFER)) {
578     		spin_lock_irq(&current->sigmask_lock);
579     		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
580     		sigaddset(&current->blocked,sig);
581     		recalc_sigpending(current);
582     		spin_unlock_irq(&current->sigmask_lock);
583     	}
584     }
585     
586     static inline void
587     syscall_restart(unsigned long r0, unsigned long r19,
588     		struct pt_regs *regs, struct k_sigaction *ka)
589     {
590     	switch (regs->r0) {
591     	case ERESTARTSYS:
592     		if (!(ka->sa.sa_flags & SA_RESTART)) {
593     		case ERESTARTNOHAND:
594     			regs->r0 = EINTR;
595     			break;
596     		}
597     		/* fallthrough */
598     	case ERESTARTNOINTR:
599     		regs->r0 = r0;	/* reset v0 and a3 and replay syscall */
600     		regs->r19 = r19;
601     		regs->pc -= 4;
602     		break;
603     	}
604     }
605     
606     
607     /*
608      * Note that 'init' is a special process: it doesn't get signals it doesn't
609      * want to handle. Thus you cannot kill init even with a SIGKILL even by
610      * mistake.
611      *
612      * Note that we go through the signals twice: once to check the signals that
613      * the kernel can handle, and then we build all the user-level signal handling
614      * stack-frames in one go after that.
615      *
616      * "r0" and "r19" are the registers we need to restore for system call
617      * restart. "r0" is also used as an indicator whether we can restart at
618      * all (if we get here from anything but a syscall return, it will be 0)
619      */
620     asmlinkage int
621     do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
622     	  unsigned long r0, unsigned long r19)
623     {
624     	unsigned long single_stepping = ptrace_cancel_bpt(current);
625     
626     	if (!oldset)
627     		oldset = &current->blocked;
628     
629     	while (1) {
630     		unsigned long signr;
631     		struct k_sigaction *ka;
632     		siginfo_t info;
633     
634     		spin_lock_irq(&current->sigmask_lock);
635     		signr = dequeue_signal(&current->blocked, &info);
636     		spin_unlock_irq(&current->sigmask_lock);
637     
638     		if (!signr)
639     			break;
640     
641     		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
642     			/* Let the debugger run.  */
643     			current->exit_code = signr;
644     			current->state = TASK_STOPPED;
645     			notify_parent(current, SIGCHLD);
646     			schedule();
647     			single_stepping |= ptrace_cancel_bpt(current);
648     
649     			/* We're back.  Did the debugger cancel the sig?  */
650     			if (!(signr = current->exit_code))
651     				continue;
652     			current->exit_code = 0;
653     
654     			/* The debugger continued.  Ignore SIGSTOP.  */
655     			if (signr == SIGSTOP)
656     				continue;
657     
658     			/* Update the siginfo structure.  Is this good?  */
659     			if (signr != info.si_signo) {
660     				info.si_signo = signr;
661     				info.si_errno = 0;
662     				info.si_code = SI_USER;
663     				info.si_pid = current->p_pptr->pid;
664     				info.si_uid = current->p_pptr->uid;
665     			}
666     
667     			/* If the (new) signal is now blocked, requeue it.  */
668     			if (sigismember(&current->blocked, signr)) {
669     				send_sig_info(signr, &info, current);
670     				continue;
671     			}
672     		}
673     
674     		ka = &current->sig->action[signr-1];
675     		if (ka->sa.sa_handler == SIG_IGN) {
676     			if (signr != SIGCHLD)
677     				continue;
678     			/* Check for SIGCHLD: it's special.  */
679     			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
680     				/* nothing */;
681     			continue;
682     		}
683     
684     		if (ka->sa.sa_handler == SIG_DFL) {
685     			int exit_code = signr & 0x7f;
686     
687     			/* Init gets no signals it doesn't want.  */
688     			if (current->pid == 1)
689     				continue;
690     
691     			switch (signr) {
692     			case SIGCONT: case SIGCHLD: case SIGWINCH:
693     				continue;
694     
695     			case SIGTSTP: case SIGTTIN: case SIGTTOU:
696     				if (is_orphaned_pgrp(current->pgrp))
697     					continue;
698     				/* FALLTHRU */
699     
700     			case SIGSTOP:
701     				current->state = TASK_STOPPED;
702     				current->exit_code = signr;
703     				if (!(current->p_pptr->sig->action[SIGCHLD-1]
704     				      .sa.sa_flags & SA_NOCLDSTOP))
705     					notify_parent(current, SIGCHLD);
706     				schedule();
707     				single_stepping |= ptrace_cancel_bpt(current);
708     				continue;
709     
710     			case SIGQUIT: case SIGILL: case SIGTRAP:
711     			case SIGABRT: case SIGFPE: case SIGSEGV:
712     			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
713     				if (do_coredump(signr, regs))
714     					exit_code |= 0x80;
715     				/* FALLTHRU */
716     
717     			default:
718     				lock_kernel();
719     				sigaddset(&current->pending.signal, signr);
720     				current->flags |= PF_SIGNALED;
721     				do_exit(exit_code);
722     				/* NOTREACHED */
723     			}
724     			continue;
725     		}
726     
727     		/* Whee!  Actually deliver the signal.  */
728     		if (r0) syscall_restart(r0, r19, regs, ka);
729     		handle_signal(signr, ka, &info, oldset, regs, sw);
730     		if (single_stepping) 
731     			ptrace_set_bpt(current); /* re-set bpt */
732     		return 1;
733     	}
734     
735     	if (r0 &&
736     	    (regs->r0 == ERESTARTNOHAND ||
737     	     regs->r0 == ERESTARTSYS ||
738     	     regs->r0 == ERESTARTNOINTR)) {
739     		regs->r0 = r0;	/* reset v0 and a3 and replay syscall */
740     		regs->r19 = r19;
741     		regs->pc -= 4;
742     	}
743     	if (single_stepping)
744     		ptrace_set_bpt(current);	/* re-set breakpoint */
745     
746     	return 0;
747     }
748