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