1/*
2 * arch/ubicom32/kernel/signal.c
3 *   Ubicom32 architecture signal handling implementation.
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 * Copyright (C) 1991, 1992  Linus Torvalds
7 * Linux/m68k support by Hamish Macdonald
8 * 68060 fixes by Jesper Skov
9 * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
10 * mathemu support by Roman Zippel
11 * ++roman (07/09/96): implemented signal stacks
12 *
13 * This file is part of the Ubicom32 Linux Kernel Port.
14 *
15 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
16 * it and/or modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation, either version 2 of the
18 * License, or (at your option) any later version.
19 *
20 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
21 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
22 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
23 * the GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with the Ubicom32 Linux Kernel Port.  If not,
27 * see <http://www.gnu.org/licenses/>.
28 *
29 * Ubicom32 implementation derived from (with many thanks):
30 *   arch/m68knommu
31 *   arch/blackfin
32 *   arch/parisc
33 *
34 * mathemu support by Roman Zippel
35 *  (Note: fpstate in the signal context is completely ignored for the emulator
36 *         and the internal floating point format is put on stack)
37 *
38 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
39 * Atari :-) Current limitation: Only one sigstack can be active at one time.
40 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
41 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
42 * signal handlers!
43 */
44
45#include <linux/module.h>
46#include <linux/sched.h>
47#include <linux/mm.h>
48#include <linux/kernel.h>
49#include <linux/signal.h>
50#include <linux/syscalls.h>
51#include <linux/errno.h>
52#include <linux/wait.h>
53#include <linux/ptrace.h>
54#include <linux/unistd.h>
55#include <linux/stddef.h>
56#include <linux/highuid.h>
57#include <linux/tty.h>
58#include <linux/personality.h>
59#include <linux/binfmts.h>
60
61#include <asm/setup.h>
62#include <asm/uaccess.h>
63#include <asm/pgtable.h>
64#include <asm/traps.h>
65#include <asm/ucontext.h>
66
67#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
68
69/*
70 * asm signal return handlers.
71 */
72void ret_from_user_signal(void);
73void ret_from_user_rt_signal(void);
74asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
75
76/*
77 * Common signal suspend implementation
78 */
79static int signal_suspend(sigset_t *saveset, struct pt_regs *regs)
80{
81	regs->dn[0] = -EINTR;
82	while (1) {
83		current->state = TASK_INTERRUPTIBLE;
84		schedule();
85		if (!do_signal(saveset, regs)) {
86			continue;
87		}
88		/*
89		 * If the current frame type is a signal trampoline we are
90		 * actually going to call the signal handler so we return the
91		 * desired d0 as the return value.
92		 */
93		if (regs->frame_type == UBICOM32_FRAME_TYPE_SIGTRAMP) {
94			return regs->dn[0];
95		}
96		return -EINTR;
97	}
98	/*
99	 * Should never get here
100	 */
101	BUG();
102	return 0;
103}
104
105/*
106 * Atomically swap in the new signal mask, and wait for a signal.
107 */
108asmlinkage int do_sigsuspend(struct pt_regs *regs)
109{
110	old_sigset_t mask = regs->dn[0];
111	sigset_t saveset;
112
113	mask &= _BLOCKABLE;
114	spin_lock_irq(&current->sighand->siglock);
115	saveset = current->blocked;
116	siginitset(&current->blocked, mask);
117	recalc_sigpending();
118	spin_unlock_irq(&current->sighand->siglock);
119
120	/*
121	 * Call common handler
122	 */
123	return signal_suspend(&saveset, regs);
124}
125
126asmlinkage int
127do_rt_sigsuspend(struct pt_regs *regs)
128{
129	sigset_t *unewset = (sigset_t *)regs->dn[0];
130	size_t sigsetsize = (size_t)regs->dn[1];
131	sigset_t saveset, newset;
132
133	/* XXX: Don't preclude handling different sized sigset_t's.  */
134	if (sigsetsize != sizeof(sigset_t))
135		return -EINVAL;
136
137	if (copy_from_user(&newset, unewset, sizeof(newset)))
138		return -EFAULT;
139	sigdelsetmask(&newset, ~_BLOCKABLE);
140
141	spin_lock_irq(&current->sighand->siglock);
142	saveset = current->blocked;
143	current->blocked = newset;
144	recalc_sigpending();
145	spin_unlock_irq(&current->sighand->siglock);
146
147	/*
148	 * Call common handler
149	 */
150	return signal_suspend(&saveset, regs);
151}
152
153asmlinkage int
154sys_sigaction(int sig, const struct old_sigaction *act,
155	      struct old_sigaction *oact)
156{
157	struct k_sigaction new_ka, old_ka;
158	int ret;
159
160	if (act) {
161		old_sigset_t mask;
162		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
163		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
164		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
165			return -EFAULT;
166		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
167		__get_user(mask, &act->sa_mask);
168		siginitset(&new_ka.sa.sa_mask, mask);
169	}
170
171	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
172
173	if (!ret && oact) {
174		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
175		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
176		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
177			return -EFAULT;
178		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
179		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
180	}
181
182	return ret;
183}
184
185asmlinkage int
186do_sys_sigaltstack(struct pt_regs *regs)
187{
188	const stack_t *uss = (stack_t *) regs->dn[0];
189	stack_t *uoss = (stack_t *)regs->dn[1];
190	return do_sigaltstack(uss, uoss, regs->an[7]);
191}
192
193/*
194 * fdpic_func_descriptor describes sa_handler when the application is FDPIC
195 */
196struct fdpic_func_descriptor {
197	unsigned long	text;
198	unsigned long	GOT;
199};
200
201/*
202 * rt_sigframe is stored on the user stack immediately before (above)
203 * the signal handlers stack.
204 */
205struct rt_sigframe
206{
207	unsigned long syscall_number;	/* This holds __NR_rt_sigreturn. */
208	unsigned long restore_all_regs; /* This field gets set to 1 if the frame
209					 * type is TRAP or INTERRUPT. */
210	siginfo_t *info;
211	struct ucontext uc;
212	int sig;
213	void *pretcode;
214};
215
216/*
217 * Do a signal return; undo the signal stack.
218 */
219asmlinkage int do_sigreturn(unsigned long __unused)
220{
221	BUG();
222	return 0;
223}
224
225asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
226{
227	unsigned long usp = regs->an[7];
228	struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
229	sigset_t set;
230
231	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
232		goto badframe;
233	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
234		goto badframe;
235
236	sigdelsetmask(&set, ~_BLOCKABLE);
237	spin_lock_irq(&current->sighand->siglock);
238	current->blocked = set;
239	recalc_sigpending();
240	spin_unlock_irq(&current->sighand->siglock);
241
242	if (copy_from_user(regs, &frame->uc.uc_mcontext, sizeof(struct pt_regs)))
243		goto badframe;
244	return regs->dn[0];
245
246badframe:
247	force_sig(SIGSEGV, current);
248	return 0;
249}
250
251static inline void *
252get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
253{
254	unsigned long usp;
255
256	/* Default to using normal stack.  */
257	usp = regs->an[7];
258
259	/* This is the X/Open sanctioned signal stack switching.  */
260	if (ka->sa.sa_flags & SA_ONSTACK) {
261		if (!sas_ss_flags(usp))
262			usp = current->sas_ss_sp + current->sas_ss_size;
263	}
264	return (void *)((usp - frame_size) & ~0x3);
265}
266
267/*
268 * signal_trampoline:  Defined in ubicom32_syscall.S
269 */
270asmlinkage void signal_trampoline(void)__attribute__((naked));
271
272static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
273			    sigset_t *set, struct pt_regs *regs)
274{
275	struct rt_sigframe *frame;
276	int err = 0;
277
278	frame = (struct rt_sigframe *) get_sigframe(ka, regs, sizeof(*frame));
279
280	/*
281	 * The 'err |=' have been may criticized as bad code style, but I
282	 * strongly suspect that we want this code to be fast.  So for
283	 * now it stays as is.
284	 */
285	err |= __put_user( (  (current_thread_info()->exec_domain)
286			   && (current_thread_info()->exec_domain->signal_invmap)
287			   && (sig < 32) )
288			   ? current_thread_info()->exec_domain->signal_invmap[sig]
289			   : sig, &frame->sig);
290	err |= __put_user(info, &frame->info);
291
292	/* Create the ucontext.  */
293	err |= __put_user(0, &frame->uc.uc_flags);
294	err |= __put_user(0, &frame->uc.uc_link);
295	err |= __put_user((void *)current->sas_ss_sp,
296			  &frame->uc.uc_stack.ss_sp);
297	err |= __put_user(sas_ss_flags(regs->an[7]),
298			  &frame->uc.uc_stack.ss_flags);
299	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
300	err |= __put_user(__NR_rt_sigreturn, &frame->syscall_number);
301	if ((regs->frame_type == UBICOM32_FRAME_TYPE_TRAP) ||
302	    (regs->frame_type == UBICOM32_FRAME_TYPE_INTERRUPT)) {
303		err |= __put_user(1, &frame->restore_all_regs);
304	} else {
305		err |= __put_user(0, &frame->restore_all_regs);
306	}
307	err |= copy_to_user (&frame->uc.uc_mcontext.sc_regs, regs, sizeof(struct pt_regs));
308	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
309
310	if (err)
311		goto give_sigsegv;
312
313	/*
314	 * Set up registers for signal handler NOTE: Do not modify dn[14], it
315	 * contains the userspace tls pointer, so it important that it carries
316	 * over to the signal handler.
317	 */
318	regs->an[7] = (unsigned long)frame;
319	regs->pc = (unsigned long) signal_trampoline;
320	regs->an[5] = (unsigned long) signal_trampoline;
321	regs->dn[0] = sig;
322	regs->dn[1] = (unsigned long) frame->info;
323	regs->dn[2] = (unsigned int) &frame->uc;
324
325	/*
326	 * If this is FDPIC then the signal handler is actually a function
327	 * descriptor.
328	 */
329	if (current->personality & FDPIC_FUNCPTRS) {
330		struct fdpic_func_descriptor __user *funcptr =
331			(struct fdpic_func_descriptor *) ka->sa.sa_handler;
332		err |= __get_user(regs->dn[3], &funcptr->text);
333		err |= __get_user(regs->an[0], &funcptr->GOT);
334		if (err)
335			goto give_sigsegv;
336
337		/*
338		 * The funcdesc must be in a3 as this is required for the lazy
339		 * resolver in ld.so, if the application is not FDPIC a3 is not
340		 * used.
341		 */
342		regs->an[3] = (unsigned long) funcptr;
343
344	} else {
345		regs->dn[3] = (unsigned long)ka->sa.sa_handler;
346		regs->an[0] = 0;
347	}
348
349	regs->frame_type =  UBICOM32_FRAME_TYPE_SIGTRAMP;
350
351	return;
352
353give_sigsegv:
354	/* user space exception */
355	force_sigsegv(sig, current);
356}
357
358static inline void
359handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
360{
361	switch (regs->dn[0]) {
362	case -ERESTARTNOHAND:
363		if (!has_handler)
364			goto do_restart;
365		regs->dn[0] = -EINTR;
366		break;
367
368	case -ERESTARTSYS:
369		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
370			regs->dn[0] = -EINTR;
371			break;
372		}
373	/* fallthrough */
374	case -ERESTARTNOINTR:
375	do_restart:
376		regs->dn[0] = regs->original_dn_0;
377		regs->pc -= 8;
378		regs->an[5] -= 8;
379		break;
380	}
381}
382
383/*
384 * OK, we're invoking a handler
385 */
386static void
387handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
388	      sigset_t *oldset, struct pt_regs *regs)
389{
390	/* are we from a system call? */
391	if (regs->frame_type == -1)
392		/* If so, check system call restarting.. */
393		handle_restart(regs, ka, 1);
394
395	/* set up the stack frame */
396	setup_rt_frame(sig, ka, info, oldset, regs);
397
398	if (ka->sa.sa_flags & SA_ONESHOT)
399		ka->sa.sa_handler = SIG_DFL;
400
401	spin_lock_irq(&current->sighand->siglock);
402	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
403	if (!(ka->sa.sa_flags & SA_NODEFER))
404		sigaddset(&current->blocked,sig);
405	recalc_sigpending();
406	spin_unlock_irq(&current->sighand->siglock);
407}
408
409/*
410 * Note that 'init' is a special process: it doesn't get signals it doesn't
411 * want to handle. Thus you cannot kill init even with a SIGKILL even by
412 * mistake.
413 */
414asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
415{
416	struct k_sigaction ka;
417	siginfo_t info;
418	int signr;
419
420	/*
421	 * We want the common case to go fast, which
422	 * is why we may in certain cases get here from
423	 * kernel mode. Just return without doing anything
424	 * if so.
425	 */
426	if (!user_mode(regs))
427		return 1;
428
429	if (!oldset)
430		oldset = &current->blocked;
431
432	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
433	if (signr > 0) {
434		/* Whee!  Actually deliver the signal.  */
435		handle_signal(signr, &ka, &info, oldset, regs);
436		return 1;
437	}
438
439	/* Did we come from a system call? */
440	if (regs->frame_type == -1) {
441		/* Restart the system call - no handlers present */
442		handle_restart(regs, NULL, 0);
443	}
444
445	return 0;
446}
447
448/*
449 * sys_sigreturn()
450 *	Return handler for signal clean-up.
451 *
452 * NOTE: Ubicom32 does not use this syscall.  Instead we rely
453 * on do_rt_sigreturn().
454 */
455asmlinkage long sys_sigreturn(void)
456{
457	return -ENOSYS;
458}
459