ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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.  */
357         err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
358                         &frame->tramp[SIGRETURN_TRAMP+0]);
359         err |= __put_user(INSN_LDI_R20, &frame->tramp[SIGRETURN_TRAMP+1]);
360         err |= __put_user(INSN_BLE_SR2_R0, &frame->tramp[SIGRETURN_TRAMP+2]);
361         err |= __put_user(INSN_NOP, &frame->tramp[SIGRETURN_TRAMP+3]);
362
363 #if DEBUG_SIG
364         /* Assert that we're flushing in the correct space... */
365         {
366                 int sid;
367                 asm ("mfsp %%sr3,%0" : "=r" (sid));
368                 DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
369                        sid, frame->tramp);
370         }
371 #endif
372
373         flush_user_dcache_range((unsigned long) &frame->tramp[SIGRETURN_TRAMP],
374                            (unsigned long) &frame->tramp[TRAMP_SIZE]);
375         flush_user_icache_range((unsigned long) &frame->tramp[SIGRETURN_TRAMP],
376                            (unsigned long) &frame->tramp[TRAMP_SIZE]);
377
378         rp = (unsigned long) &frame->tramp[SIGRETURN_TRAMP];
379
380         if (err)
381                 goto give_sigsegv;
382
383         haddr = A(ka->sa.sa_handler);
384         /* The sa_handler may be a pointer to a function descriptor */
385 #ifdef __LP64__
386         if(personality(current->personality) == PER_LINUX32) {
387 #endif
388                 if (haddr & PA_PLABEL_FDESC) {
389                         Elf32_Fdesc fdesc;
390                         Elf32_Fdesc *ufdesc = (Elf32_Fdesc *)A(haddr & ~3);
391
392                         err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
393
394                         if (err)
395                                 goto give_sigsegv;
396
397                         haddr = fdesc.addr;
398                         regs->gr[19] = fdesc.gp;
399                 }
400 #ifdef __LP64__
401         } else {
402                 Elf64_Fdesc fdesc;
403                 Elf64_Fdesc *ufdesc = (Elf64_Fdesc *)A(haddr & ~3);
404                 
405                 err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
406                 
407                 if (err)
408                         goto give_sigsegv;
409                 
410                 haddr = fdesc.addr;
411                 regs->gr[19] = fdesc.gp;
412                 DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
413                      haddr, regs->gr[19], in_syscall);
414         }
415 #endif
416
417         /* The syscall return path will create IAOQ values from r31.
418          */
419         sigframe_size = PARISC_RT_SIGFRAME_SIZE;
420 #ifdef __LP64__
421         if(personality(current->personality) == PER_LINUX32)
422                 sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
423 #endif
424         if (in_syscall) {
425                 regs->gr[31] = haddr;
426 #ifdef __LP64__
427                 if(personality(current->personality) == PER_LINUX)
428                         sigframe_size |= 1;
429 #endif
430         } else {
431                 unsigned long psw = USER_PSW;
432 #ifdef __LP64__
433                 if(personality(current->personality) == PER_LINUX)
434                         psw |= PSW_W;
435 #endif
436
437                 regs->gr[0] = psw;
438                 regs->iaoq[0] = haddr | 3;
439                 regs->iaoq[1] = regs->iaoq[0] + 4;
440         }
441
442         regs->gr[2]  = rp;                /* userland return pointer */
443         regs->gr[26] = sig;               /* signal number */
444         
445 #ifdef __LP64__
446         if(personality(current->personality) == PER_LINUX32){
447                 regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
448                 regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
449         } else
450 #endif
451         {               
452                 regs->gr[25] = A(&frame->info); /* siginfo pointer */
453                 regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
454         }
455         
456         DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
457                regs->gr[30], sigframe_size,
458                regs->gr[30] + sigframe_size);
459         /* Raise the user stack pointer to make a proper call frame. */
460         regs->gr[30] = (A(frame) + sigframe_size);
461
462
463         DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
464                current->comm, current->pid, frame, regs->gr[30],
465                regs->iaoq[0], regs->iaoq[1], rp);
466
467         return 1;
468
469 give_sigsegv:
470         DBG(1,"setup_rt_frame: sending SIGSEGV\n");
471         if (sig == SIGSEGV)
472                 ka->sa.sa_handler = SIG_DFL;
473         si.si_signo = SIGSEGV;
474         si.si_errno = 0;
475         si.si_code = SI_KERNEL;
476         si.si_pid = current->pid;
477         si.si_uid = current->uid;
478         si.si_addr = frame;
479         force_sig_info(SIGSEGV, &si, current);
480         return 0;
481 }
482
483 /*
484  * OK, we're invoking a handler.
485  */     
486
487 static long
488 handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
489               struct pt_regs *regs, int in_syscall)
490 {
491         struct k_sigaction *ka = &current->sighand->action[sig-1];
492
493         DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
494                sig, ka, info, oldset, regs);
495         
496         /* Set up the stack frame */
497         if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
498                 return 0;
499
500         if (ka->sa.sa_flags & SA_ONESHOT)
501                 ka->sa.sa_handler = SIG_DFL;
502
503         if (!(ka->sa.sa_flags & SA_NODEFER)) {
504                 spin_lock_irq(&current->sighand->siglock);
505                 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
506                 sigaddset(&current->blocked,sig);
507                 recalc_sigpending();
508                 spin_unlock_irq(&current->sighand->siglock);
509         }
510         return 1;
511 }
512
513 /*
514  * Note that 'init' is a special process: it doesn't get signals it doesn't
515  * want to handle. Thus you cannot kill init even with a SIGKILL even by
516  * mistake.
517  *
518  * We need to be able to restore the syscall arguments (r21-r26) to
519  * restart syscalls.  Thus, the syscall path should save them in the
520  * pt_regs structure (it's okay to do so since they are caller-save
521  * registers).  As noted below, the syscall number gets restored for
522  * us due to the magic of delayed branching.
523  */
524
525 asmlinkage int
526 do_signal(sigset_t *oldset, struct pt_regs *regs, int in_syscall)
527 {
528         siginfo_t info;
529         struct k_sigaction *ka;
530         int signr;
531
532         DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
533                oldset, regs, regs->sr[7], in_syscall);
534
535         /* Everyone else checks to see if they are in kernel mode at
536            this point and exits if that's the case.  I'm not sure why
537            we would be called in that case, but for some reason we
538            are. */
539
540         if (!oldset)
541                 oldset = &current->blocked;
542
543         DBG(1,"do_signal: oldset %08lx / %08lx\n", 
544                 oldset->sig[0], oldset->sig[1]);
545
546
547         signr = get_signal_to_deliver(&info, regs, NULL);
548         DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
549         
550         if (signr > 0) {
551                 /* Restart a system call if necessary. */
552                 if (in_syscall) {
553                         /* Check the return code */
554                         switch (regs->gr[28]) {
555                         case -ERESTART_RESTARTBLOCK:
556                                 current_thread_info()->restart_block.fn = do_no_restart_syscall;
557                         case -ERESTARTNOHAND:
558                                 DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
559                                 regs->gr[28] = -EINTR;
560                                 break;
561
562                         case -ERESTARTSYS:
563                                 ka = &current->sighand->action[signr-1];
564                                 if (!(ka->sa.sa_flags & SA_RESTART)) {
565                                         DBG(1,"ERESTARTSYS: putting -EINTR\n");
566                                         regs->gr[28] = -EINTR;
567                                         break;
568                                 }
569                         /* fallthrough */
570                         case -ERESTARTNOINTR:
571                                 /* A syscall is just a branch, so all
572                                    we have to do is fiddle the return
573                                    pointer. */
574                                 regs->gr[31] -= 8; /* delayed branching */
575                                 /* Preserve original r28. */
576                                 regs->gr[28] = regs->orig_r28;
577                                 break;
578                         }
579                 }
580                 /* Whee!  Actually deliver the signal.  If the
581                    delivery failed, we need to continue to iterate in
582                    this loop so we can deliver the SIGSEGV... */
583                 if (handle_signal(signr, &info, oldset, regs, in_syscall)) {
584                         DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
585                                 regs->gr[28]);
586                         return 1;
587                 }
588         }
589
590         /* Did we come from a system call? */
591         if (in_syscall) {
592                 /* Restart the system call - no handlers present */
593                 if (regs->gr[28] == -ERESTART_RESTARTBLOCK) {
594                         unsigned int *usp = (unsigned int *)regs->gr[30];
595
596                         /* Setup a trampoline to restart the syscall
597                          * with __NR_restart_syscall
598                          *
599                          *  0: <return address (orig r31)>
600                          *  4: <2nd half for 64-bit>
601                          *  8: ldw 0(%sp), %r31
602                          * 12: be 0x100(%sr2, %r0)
603                          * 16: ldi __NR_restart_syscall, %r20
604                          */
605 #ifndef __LP64__
606                         put_user(regs->gr[31], &usp[0]);
607                         put_user(0x0fc0109f, &usp[2]);
608 #else
609                         put_user(regs->gr[31] >> 32, &usp[0]);
610                         put_user(regs->gr[31] & 0xffffffff, &usp[1]);
611                         put_user(0x0fc010df, &usp[2]);
612 #endif
613                         put_user(0xe0008200, &usp[3]);
614                         put_user(0x34140000, &usp[4]);
615
616                         /* Stack is 64-byte aligned, and we only 
617                          * need to flush 1 cache line */
618                         asm("fdc 0(%%sr3, %0)\n"
619                             "fic 0(%%sr3, %0)\n"
620                             "sync\n"
621                             : : "r"(regs->gr[30]));
622
623                         regs->gr[31] = regs->gr[30] + 8;
624                         /* Preserve original r28. */
625                         regs->gr[28] = regs->orig_r28;
626                 } else if (regs->gr[28] == -ERESTARTNOHAND ||
627                            regs->gr[28] == -ERESTARTSYS ||
628                            regs->gr[28] == -ERESTARTNOINTR) {
629                         /* Hooray for delayed branching.  We don't
630                            have to restore %r20 (the system call
631                            number) because it gets loaded in the delay
632                            slot of the branch external instruction. */
633                         regs->gr[31] -= 8;
634                         /* Preserve original r28. */
635                         regs->gr[28] = regs->orig_r28;
636                 }
637         }
638         
639         DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
640                 regs->gr[28]);
641
642         return 0;
643 }