]> bbs.cooldavid.org Git - net-next-2.6.git/blob - arch/parisc/kernel/signal.c
parisc: tracehook_signal_handler
[net-next-2.6.git] / arch / parisc / kernel / signal.c
1 /*
2  *  linux/arch/parisc/kernel/signal.c: Architecture-specific signal
3  *  handling support.
4  *
5  *  Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
6  *  Copyright (C) 2000 Linuxcare, Inc.
7  *
8  *  Based on the ia64, i386, and alpha versions.
9  *
10  *  Like the IA-64, we are a recent enough port (we are *starting*
11  *  with glibc2.2) that we do not need to support the old non-realtime
12  *  Linux signals.  Therefore we don't.  HP/UX signals will go in
13  *  arch/parisc/hpux/signal.c when we figure out how to do them.
14  */
15
16 #include <linux/sched.h>
17 #include <linux/mm.h>
18 #include <linux/smp.h>
19 #include <linux/kernel.h>
20 #include <linux/signal.h>
21 #include <linux/errno.h>
22 #include <linux/wait.h>
23 #include <linux/ptrace.h>
24 #include <linux/tracehook.h>
25 #include <linux/unistd.h>
26 #include <linux/stddef.h>
27 #include <linux/compat.h>
28 #include <linux/elf.h>
29 #include <linux/tracehook.h>
30 #include <asm/ucontext.h>
31 #include <asm/rt_sigframe.h>
32 #include <asm/uaccess.h>
33 #include <asm/pgalloc.h>
34 #include <asm/cacheflush.h>
35 #include <asm/asm-offsets.h>
36
37 #ifdef CONFIG_COMPAT
38 #include <linux/compat.h>
39 #include "signal32.h"
40 #endif
41
42 #define DEBUG_SIG 0 
43 #define DEBUG_SIG_LEVEL 2
44
45 #if DEBUG_SIG
46 #define DBG(LEVEL, ...) \
47         ((DEBUG_SIG_LEVEL >= LEVEL) \
48         ? printk(__VA_ARGS__) : (void) 0)
49 #else
50 #define DBG(LEVEL, ...)
51 #endif
52         
53
54 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
55
56 /* gcc will complain if a pointer is cast to an integer of different
57  * size.  If you really need to do this (and we do for an ELF32 user
58  * application in an ELF64 kernel) then you have to do a cast to an
59  * integer of the same size first.  The A() macro accomplishes
60  * this. */
61 #define A(__x)  ((unsigned long)(__x))
62
63 /*
64  * Atomically swap in the new signal mask, and wait for a signal.
65  */
66 #ifdef CONFIG_64BIT
67 #include "sys32.h"
68 #endif
69
70 /*
71  * Do a signal return - restore sigcontext.
72  */
73
74 /* Trampoline for calling rt_sigreturn() */
75 #define INSN_LDI_R25_0   0x34190000 /* ldi  0,%r25 (in_syscall=0) */
76 #define INSN_LDI_R25_1   0x34190002 /* ldi  1,%r25 (in_syscall=1) */
77 #define INSN_LDI_R20     0x3414015a /* ldi  __NR_rt_sigreturn,%r20 */
78 #define INSN_BLE_SR2_R0  0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
79 #define INSN_NOP         0x08000240 /* nop */
80 /* For debugging */
81 #define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
82
83 static long
84 restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
85 {
86         long err = 0;
87
88         err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
89         err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
90         err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
91         err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
92         err |= __get_user(regs->sar, &sc->sc_sar);
93         DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n", 
94                         regs->iaoq[0],regs->iaoq[1]);
95         DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
96         return err;
97 }
98
99 void
100 sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
101 {
102         struct rt_sigframe __user *frame;
103         struct siginfo si;
104         sigset_t set;
105         unsigned long usp = (regs->gr[30] & ~(0x01UL));
106         unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
107 #ifdef CONFIG_64BIT
108         compat_sigset_t compat_set;
109         struct compat_rt_sigframe __user * compat_frame;
110         
111         if (is_compat_task())
112                 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
113 #endif
114
115
116         /* Unwind the user stack to get the rt_sigframe structure. */
117         frame = (struct rt_sigframe __user *)
118                 (usp - sigframe_size);
119         DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
120
121 #ifdef CONFIG_64BIT
122         compat_frame = (struct compat_rt_sigframe __user *)frame;
123         
124         if (is_compat_task()) {
125                 DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
126                 if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
127                         goto give_sigsegv;
128                 sigset_32to64(&set,&compat_set);
129         } else
130 #endif
131         {
132                 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
133                         goto give_sigsegv;
134         }
135                 
136         sigdelsetmask(&set, ~_BLOCKABLE);
137         spin_lock_irq(&current->sighand->siglock);
138         current->blocked = set;
139         recalc_sigpending();
140         spin_unlock_irq(&current->sighand->siglock);
141
142         /* Good thing we saved the old gr[30], eh? */
143 #ifdef CONFIG_64BIT
144         if (is_compat_task()) {
145                 DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
146                                 &compat_frame->uc.uc_mcontext);
147 // FIXME: Load upper half from register file
148                 if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 
149                                         &compat_frame->regs, regs))
150                         goto give_sigsegv;
151                 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
152                                 usp, &compat_frame->uc.uc_stack);
153                 if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT)
154                         goto give_sigsegv;
155         } else
156 #endif
157         {
158                 DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
159                                 &frame->uc.uc_mcontext);
160                 if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
161                         goto give_sigsegv;
162                 DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
163                                 usp, &frame->uc.uc_stack);
164                 if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
165                         goto give_sigsegv;
166         }
167                 
168
169
170         /* If we are on the syscall path IAOQ will not be restored, and
171          * if we are on the interrupt path we must not corrupt gr31.
172          */
173         if (in_syscall)
174                 regs->gr[31] = regs->iaoq[0];
175 #if DEBUG_SIG
176         DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
177         show_regs(regs);
178 #endif
179         return;
180
181 give_sigsegv:
182         DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
183         si.si_signo = SIGSEGV;
184         si.si_errno = 0;
185         si.si_code = SI_KERNEL;
186         si.si_pid = task_pid_vnr(current);
187         si.si_uid = current_uid();
188         si.si_addr = &frame->uc;
189         force_sig_info(SIGSEGV, &si, current);
190         return;
191 }
192
193 /*
194  * Set up a signal frame.
195  */
196
197 static inline void __user *
198 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
199 {
200         /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
201           don't use the parameter it doesn't matter */
202
203         DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
204                         (unsigned long)ka, sp, frame_size);
205         
206         if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
207                 sp = current->sas_ss_sp; /* Stacks grow up! */
208
209         DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
210         return (void __user *) sp; /* Stacks grow up.  Fun. */
211 }
212
213 static long
214 setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
215                  
216 {
217         unsigned long flags = 0;
218         long err = 0;
219
220         if (on_sig_stack((unsigned long) sc))
221                 flags |= PARISC_SC_FLAG_ONSTACK;
222         if (in_syscall) {
223                 flags |= PARISC_SC_FLAG_IN_SYSCALL;
224                 /* regs->iaoq is undefined in the syscall return path */
225                 err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
226                 err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
227                 err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
228                 err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
229                 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
230                         regs->gr[31], regs->gr[31]+4);
231         } else {
232                 err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
233                 err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
234                 DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n", 
235                         regs->iaoq[0], regs->iaoq[1]);
236         }
237
238         err |= __put_user(flags, &sc->sc_flags);
239         err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
240         err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
241         err |= __put_user(regs->sar, &sc->sc_sar);
242         DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
243
244         return err;
245 }
246
247 static long
248 setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
249                sigset_t *set, struct pt_regs *regs, int in_syscall)
250 {
251         struct rt_sigframe __user *frame;
252         unsigned long rp, usp;
253         unsigned long haddr, sigframe_size;
254         int err = 0;
255 #ifdef CONFIG_64BIT
256         compat_int_t compat_val;
257         struct compat_rt_sigframe __user * compat_frame;
258         compat_sigset_t compat_set;
259 #endif
260         
261         usp = (regs->gr[30] & ~(0x01UL));
262         /*FIXME: frame_size parameter is unused, remove it. */
263         frame = get_sigframe(ka, usp, sizeof(*frame));
264
265         DBG(1,"SETUP_RT_FRAME: START\n");
266         DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
267
268         
269 #ifdef CONFIG_64BIT
270
271         compat_frame = (struct compat_rt_sigframe __user *)frame;
272         
273         if (is_compat_task()) {
274                 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
275                 err |= copy_siginfo_to_user32(&compat_frame->info, info);
276                 DBG(1,"SETUP_RT_FRAME: 1\n");
277                 compat_val = (compat_int_t)current->sas_ss_sp;
278                 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
279                 DBG(1,"SETUP_RT_FRAME: 2\n");
280                 compat_val = (compat_int_t)current->sas_ss_size;
281                 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size);
282                 DBG(1,"SETUP_RT_FRAME: 3\n");
283                 compat_val = sas_ss_flags(regs->gr[30]);                
284                 err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags);             
285                 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
286                 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
287                 err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
288                                         &compat_frame->regs, regs, in_syscall);
289                 sigset_64to32(&compat_set,set);
290                 err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
291         } else
292 #endif
293         {       
294                 DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
295                 err |= copy_siginfo_to_user(&frame->info, info);
296                 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
297                 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
298                 err |= __put_user(sas_ss_flags(regs->gr[30]),
299                                   &frame->uc.uc_stack.ss_flags);
300                 DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
301                 DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
302                 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
303                 /* FIXME: Should probably be converted aswell for the compat case */
304                 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
305         }
306         
307         if (err)
308                 goto give_sigsegv;
309
310         /* Set up to return from userspace.  If provided, use a stub
311            already in userspace. The first words of tramp are used to
312            save the previous sigrestartblock trampoline that might be
313            on the stack. We start the sigreturn trampoline at 
314            SIGRESTARTBLOCK_TRAMP+X. */
315         err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
316                         &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
317         err |= __put_user(INSN_LDI_R20, 
318                         &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
319         err |= __put_user(INSN_BLE_SR2_R0, 
320                         &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
321         err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
322
323 #if DEBUG_SIG
324         /* Assert that we're flushing in the correct space... */
325         {
326                 int sid;
327                 asm ("mfsp %%sr3,%0" : "=r" (sid));
328                 DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
329                        sid, frame->tramp);
330         }
331 #endif
332
333         flush_user_dcache_range((unsigned long) &frame->tramp[0],
334                            (unsigned long) &frame->tramp[TRAMP_SIZE]);
335         flush_user_icache_range((unsigned long) &frame->tramp[0],
336                            (unsigned long) &frame->tramp[TRAMP_SIZE]);
337
338         /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
339          * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
340          * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
341          */
342         rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
343
344         if (err)
345                 goto give_sigsegv;
346
347         haddr = A(ka->sa.sa_handler);
348         /* The sa_handler may be a pointer to a function descriptor */
349 #ifdef CONFIG_64BIT
350         if (is_compat_task()) {
351 #endif
352                 if (haddr & PA_PLABEL_FDESC) {
353                         Elf32_Fdesc fdesc;
354                         Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
355
356                         err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
357
358                         if (err)
359                                 goto give_sigsegv;
360
361                         haddr = fdesc.addr;
362                         regs->gr[19] = fdesc.gp;
363                 }
364 #ifdef CONFIG_64BIT
365         } else {
366                 Elf64_Fdesc fdesc;
367                 Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
368                 
369                 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
370                 
371                 if (err)
372                         goto give_sigsegv;
373                 
374                 haddr = fdesc.addr;
375                 regs->gr[19] = fdesc.gp;
376                 DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
377                      haddr, regs->gr[19], in_syscall);
378         }
379 #endif
380
381         /* The syscall return path will create IAOQ values from r31.
382          */
383         sigframe_size = PARISC_RT_SIGFRAME_SIZE;
384 #ifdef CONFIG_64BIT
385         if (is_compat_task())
386                 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
387 #endif
388         if (in_syscall) {
389                 regs->gr[31] = haddr;
390 #ifdef CONFIG_64BIT
391                 if (!test_thread_flag(TIF_32BIT))
392                         sigframe_size |= 1;
393 #endif
394         } else {
395                 unsigned long psw = USER_PSW;
396 #ifdef CONFIG_64BIT
397                 if (!test_thread_flag(TIF_32BIT))
398                         psw |= PSW_W;
399 #endif
400
401                 /* If we are singlestepping, arrange a trap to be delivered
402                    when we return to userspace. Note the semantics -- we
403                    should trap before the first insn in the handler is
404                    executed. Ref:
405                         http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
406                  */
407                 if (pa_psw(current)->r) {
408                         pa_psw(current)->r = 0;
409                         psw |= PSW_R;
410                         mtctl(-1, 0);
411                 }
412
413                 regs->gr[0] = psw;
414                 regs->iaoq[0] = haddr | 3;
415                 regs->iaoq[1] = regs->iaoq[0] + 4;
416         }
417
418         regs->gr[2]  = rp;                /* userland return pointer */
419         regs->gr[26] = sig;               /* signal number */
420         
421 #ifdef CONFIG_64BIT
422         if (is_compat_task()) {
423                 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
424                 regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
425         } else
426 #endif
427         {               
428                 regs->gr[25] = A(&frame->info); /* siginfo pointer */
429                 regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
430         }
431         
432         DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
433                regs->gr[30], sigframe_size,
434                regs->gr[30] + sigframe_size);
435         /* Raise the user stack pointer to make a proper call frame. */
436         regs->gr[30] = (A(frame) + sigframe_size);
437
438
439         DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
440                current->comm, current->pid, frame, regs->gr[30],
441                regs->iaoq[0], regs->iaoq[1], rp);
442
443         return 1;
444
445 give_sigsegv:
446         DBG(1,"setup_rt_frame: sending SIGSEGV\n");
447         force_sigsegv(sig, current);
448         return 0;
449 }
450
451 /*
452  * OK, we're invoking a handler.
453  */     
454
455 static long
456 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
457                 sigset_t *oldset, struct pt_regs *regs, int in_syscall)
458 {
459         DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
460                sig, ka, info, oldset, regs);
461         
462         /* Set up the stack frame */
463         if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
464                 return 0;
465
466         spin_lock_irq(&current->sighand->siglock);
467         sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
468         if (!(ka->sa.sa_flags & SA_NODEFER))
469                 sigaddset(&current->blocked,sig);
470         recalc_sigpending();
471         spin_unlock_irq(&current->sighand->siglock);
472
473         tracehook_signal_handler(sig, info, ka, regs, 0);
474
475         return 1;
476 }
477
478 static inline void
479 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
480 {
481         /* Check the return code */
482         switch (regs->gr[28]) {
483         case -ERESTART_RESTARTBLOCK:
484                 current_thread_info()->restart_block.fn =
485                         do_no_restart_syscall;
486         case -ERESTARTNOHAND:
487                 DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
488                 regs->gr[28] = -EINTR;
489                 break;
490
491         case -ERESTARTSYS:
492                 if (!(ka->sa.sa_flags & SA_RESTART)) {
493                         DBG(1,"ERESTARTSYS: putting -EINTR\n");
494                         regs->gr[28] = -EINTR;
495                         break;
496                 }
497                 /* fallthrough */
498         case -ERESTARTNOINTR:
499                 /* A syscall is just a branch, so all
500                  * we have to do is fiddle the return pointer.
501                  */
502                 regs->gr[31] -= 8; /* delayed branching */
503                 /* Preserve original r28. */
504                 regs->gr[28] = regs->orig_r28;
505                 break;
506         }
507 }
508
509 static inline void
510 insert_restart_trampoline(struct pt_regs *regs)
511 {
512         switch(regs->gr[28]) {
513         case -ERESTART_RESTARTBLOCK: {
514                 /* Restart the system call - no handlers present */
515                 unsigned int *usp = (unsigned int *)regs->gr[30];
516
517                 /* Setup a trampoline to restart the syscall
518                  * with __NR_restart_syscall
519                  *
520                  *  0: <return address (orig r31)>
521                  *  4: <2nd half for 64-bit>
522                  *  8: ldw 0(%sp), %r31
523                  * 12: be 0x100(%sr2, %r0)
524                  * 16: ldi __NR_restart_syscall, %r20
525                  */
526 #ifdef CONFIG_64BIT
527                 put_user(regs->gr[31] >> 32, &usp[0]);
528                 put_user(regs->gr[31] & 0xffffffff, &usp[1]);
529                 put_user(0x0fc010df, &usp[2]);
530 #else
531                 put_user(regs->gr[31], &usp[0]);
532                 put_user(0x0fc0109f, &usp[2]);
533 #endif
534                 put_user(0xe0008200, &usp[3]);
535                 put_user(0x34140000, &usp[4]);
536
537                 /* Stack is 64-byte aligned, and we only need
538                  * to flush 1 cache line.
539                  * Flushing one cacheline is cheap.
540                  * "sync" on bigger (> 4 way) boxes is not.
541                  */
542                 flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4);
543                 flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
544
545                 regs->gr[31] = regs->gr[30] + 8;
546                 /* Preserve original r28. */
547                 regs->gr[28] = regs->orig_r28;
548
549                 return;
550         }
551         case -ERESTARTNOHAND:
552         case -ERESTARTSYS:
553         case -ERESTARTNOINTR: {
554                 /* Hooray for delayed branching.  We don't
555                  * have to restore %r20 (the system call
556                  * number) because it gets loaded in the delay
557                  * slot of the branch external instruction.
558                  */
559                 regs->gr[31] -= 8;
560                 /* Preserve original r28. */
561                 regs->gr[28] = regs->orig_r28;
562
563                 return;
564         }
565         default:
566                 break;
567         }
568 }
569
570 /*
571  * Note that 'init' is a special process: it doesn't get signals it doesn't
572  * want to handle. Thus you cannot kill init even with a SIGKILL even by
573  * mistake.
574  *
575  * We need to be able to restore the syscall arguments (r21-r26) to
576  * restart syscalls.  Thus, the syscall path should save them in the
577  * pt_regs structure (it's okay to do so since they are caller-save
578  * registers).  As noted below, the syscall number gets restored for
579  * us due to the magic of delayed branching.
580  */
581 asmlinkage void
582 do_signal(struct pt_regs *regs, long in_syscall)
583 {
584         siginfo_t info;
585         struct k_sigaction ka;
586         int signr;
587         sigset_t *oldset;
588
589         DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
590                oldset, regs, regs->sr[7], in_syscall);
591
592         /* Everyone else checks to see if they are in kernel mode at
593            this point and exits if that's the case.  I'm not sure why
594            we would be called in that case, but for some reason we
595            are. */
596
597         if (test_thread_flag(TIF_RESTORE_SIGMASK))
598                 oldset = &current->saved_sigmask;
599         else
600                 oldset = &current->blocked;
601
602         DBG(1,"do_signal: oldset %08lx / %08lx\n", 
603                 oldset->sig[0], oldset->sig[1]);
604
605
606         /* May need to force signal if handle_signal failed to deliver */
607         while (1) {
608           
609                 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
610                 DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
611         
612                 if (signr <= 0)
613                   break;
614                 
615                 /* Restart a system call if necessary. */
616                 if (in_syscall)
617                         syscall_restart(regs, &ka);
618
619                 /* Whee!  Actually deliver the signal.  If the
620                    delivery failed, we need to continue to iterate in
621                    this loop so we can deliver the SIGSEGV... */
622                 if (handle_signal(signr, &info, &ka, oldset,
623                                   regs, in_syscall)) {
624                         DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
625                                 regs->gr[28]);
626                         if (test_thread_flag(TIF_RESTORE_SIGMASK))
627                                 clear_thread_flag(TIF_RESTORE_SIGMASK);
628                         return;
629                 }
630         }
631         /* end of while(1) looping forever if we can't force a signal */
632
633         /* Did we come from a system call? */
634         if (in_syscall)
635                 insert_restart_trampoline(regs);
636         
637         DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
638                 regs->gr[28]);
639
640         if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
641                 clear_thread_flag(TIF_RESTORE_SIGMASK);
642                 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
643         }
644
645         return;
646 }
647
648 void do_notify_resume(struct pt_regs *regs, long in_syscall)
649 {
650         if (test_thread_flag(TIF_SIGPENDING) ||
651             test_thread_flag(TIF_RESTORE_SIGMASK))
652                 do_signal(regs, in_syscall);
653
654         if (test_thread_flag(TIF_NOTIFY_RESUME)) {
655                 clear_thread_flag(TIF_NOTIFY_RESUME);
656                 tracehook_notify_resume(regs);
657                 if (current->replacement_session_keyring)
658                         key_replace_session_keyring();
659         }
660 }