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