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