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