• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/mn10300/kernel/
1/* MN10300 Signal handling
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/sched.h>
13#include <linux/mm.h>
14#include <linux/smp.h>
15#include <linux/kernel.h>
16#include <linux/signal.h>
17#include <linux/errno.h>
18#include <linux/wait.h>
19#include <linux/ptrace.h>
20#include <linux/unistd.h>
21#include <linux/stddef.h>
22#include <linux/tty.h>
23#include <linux/personality.h>
24#include <linux/suspend.h>
25#include <linux/tracehook.h>
26#include <asm/cacheflush.h>
27#include <asm/ucontext.h>
28#include <asm/uaccess.h>
29#include <asm/fpu.h>
30#include "sigframe.h"
31
32#define DEBUG_SIG 0
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36/*
37 * atomically swap in the new signal mask, and wait for a signal.
38 */
39asmlinkage long sys_sigsuspend(int history0, int history1, old_sigset_t mask)
40{
41	mask &= _BLOCKABLE;
42	spin_lock_irq(&current->sighand->siglock);
43	current->saved_sigmask = current->blocked;
44	siginitset(&current->blocked, mask);
45	recalc_sigpending();
46	spin_unlock_irq(&current->sighand->siglock);
47
48	current->state = TASK_INTERRUPTIBLE;
49	schedule();
50	set_thread_flag(TIF_RESTORE_SIGMASK);
51	return -ERESTARTNOHAND;
52}
53
54/*
55 * set signal action syscall
56 */
57asmlinkage long sys_sigaction(int sig,
58			      const struct old_sigaction __user *act,
59			      struct old_sigaction __user *oact)
60{
61	struct k_sigaction new_ka, old_ka;
62	int ret;
63
64	if (act) {
65		old_sigset_t mask;
66		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
67		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
68		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
69		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
70		    __get_user(mask, &act->sa_mask))
71			return -EFAULT;
72		siginitset(&new_ka.sa.sa_mask, mask);
73	}
74
75	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
76
77	if (!ret && oact) {
78		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
79		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
80		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
81		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
82		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
83			return -EFAULT;
84	}
85
86	return ret;
87}
88
89/*
90 * set alternate signal stack syscall
91 */
92asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t *uoss)
93{
94	return do_sigaltstack(uss, uoss, __frame->sp);
95}
96
97/*
98 * do a signal return; undo the signal stack.
99 */
100static int restore_sigcontext(struct pt_regs *regs,
101			      struct sigcontext __user *sc, long *_d0)
102{
103	unsigned int err = 0;
104
105	/* Always make any pending restarted system calls return -EINTR */
106	current_thread_info()->restart_block.fn = do_no_restart_syscall;
107
108	if (is_using_fpu(current))
109		fpu_kill_state(current);
110
111#define COPY(x) err |= __get_user(regs->x, &sc->x)
112	COPY(d1); COPY(d2); COPY(d3);
113	COPY(a0); COPY(a1); COPY(a2); COPY(a3);
114	COPY(e0); COPY(e1); COPY(e2); COPY(e3);
115	COPY(e4); COPY(e5); COPY(e6); COPY(e7);
116	COPY(lar); COPY(lir);
117	COPY(mdr); COPY(mdrq);
118	COPY(mcvf); COPY(mcrl); COPY(mcrh);
119	COPY(sp); COPY(pc);
120#undef COPY
121
122	{
123		unsigned int tmpflags;
124#ifndef CONFIG_MN10300_USING_JTAG
125#define USER_EPSW (EPSW_FLAG_Z | EPSW_FLAG_N | EPSW_FLAG_C | EPSW_FLAG_V | \
126		   EPSW_T | EPSW_nAR)
127#else
128#define USER_EPSW (EPSW_FLAG_Z | EPSW_FLAG_N | EPSW_FLAG_C | EPSW_FLAG_V | \
129		   EPSW_nAR)
130#endif
131		err |= __get_user(tmpflags, &sc->epsw);
132		regs->epsw = (regs->epsw & ~USER_EPSW) |
133		  (tmpflags & USER_EPSW);
134		regs->orig_d0 = -1;		/* disable syscall checks */
135	}
136
137	{
138		struct fpucontext *buf;
139		err |= __get_user(buf, &sc->fpucontext);
140		if (buf) {
141			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
142				goto badframe;
143			err |= fpu_restore_sigcontext(buf);
144		}
145	}
146
147	err |= __get_user(*_d0, &sc->d0);
148	return err;
149
150badframe:
151	return 1;
152}
153
154/*
155 * standard signal return syscall
156 */
157asmlinkage long sys_sigreturn(void)
158{
159	struct sigframe __user *frame = (struct sigframe __user *) __frame->sp;
160	sigset_t set;
161	long d0;
162
163	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
164		goto badframe;
165	if (__get_user(set.sig[0], &frame->sc.oldmask))
166		goto badframe;
167
168	if (_NSIG_WORDS > 1 &&
169	    __copy_from_user(&set.sig[1], &frame->extramask,
170			     sizeof(frame->extramask)))
171		goto badframe;
172
173	sigdelsetmask(&set, ~_BLOCKABLE);
174	spin_lock_irq(&current->sighand->siglock);
175	current->blocked = set;
176	recalc_sigpending();
177	spin_unlock_irq(&current->sighand->siglock);
178
179	if (restore_sigcontext(__frame, &frame->sc, &d0))
180		goto badframe;
181
182	return d0;
183
184badframe:
185	force_sig(SIGSEGV, current);
186	return 0;
187}
188
189/*
190 * realtime signal return syscall
191 */
192asmlinkage long sys_rt_sigreturn(void)
193{
194	struct rt_sigframe __user *frame =
195		(struct rt_sigframe __user *) __frame->sp;
196	sigset_t set;
197	unsigned long d0;
198
199	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
200		goto badframe;
201	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
202		goto badframe;
203
204	sigdelsetmask(&set, ~_BLOCKABLE);
205	spin_lock_irq(&current->sighand->siglock);
206	current->blocked = set;
207	recalc_sigpending();
208	spin_unlock_irq(&current->sighand->siglock);
209
210	if (restore_sigcontext(__frame, &frame->uc.uc_mcontext, &d0))
211		goto badframe;
212
213	if (do_sigaltstack(&frame->uc.uc_stack, NULL, __frame->sp) == -EFAULT)
214		goto badframe;
215
216	return d0;
217
218badframe:
219	force_sig(SIGSEGV, current);
220	return 0;
221}
222
223/*
224 * store the userspace context into a signal frame
225 */
226static int setup_sigcontext(struct sigcontext __user *sc,
227			    struct fpucontext *fpuctx,
228			    struct pt_regs *regs,
229			    unsigned long mask)
230{
231	int tmp, err = 0;
232
233#define COPY(x) err |= __put_user(regs->x, &sc->x)
234	COPY(d0); COPY(d1); COPY(d2); COPY(d3);
235	COPY(a0); COPY(a1); COPY(a2); COPY(a3);
236	COPY(e0); COPY(e1); COPY(e2); COPY(e3);
237	COPY(e4); COPY(e5); COPY(e6); COPY(e7);
238	COPY(lar); COPY(lir);
239	COPY(mdr); COPY(mdrq);
240	COPY(mcvf); COPY(mcrl); COPY(mcrh);
241	COPY(sp); COPY(epsw); COPY(pc);
242#undef COPY
243
244	tmp = fpu_setup_sigcontext(fpuctx);
245	if (tmp < 0)
246		err = 1;
247	else
248		err |= __put_user(tmp ? fpuctx : NULL, &sc->fpucontext);
249
250	/* non-iBCS2 extensions.. */
251	err |= __put_user(mask, &sc->oldmask);
252
253	return err;
254}
255
256/*
257 * determine which stack to use..
258 */
259static inline void __user *get_sigframe(struct k_sigaction *ka,
260					struct pt_regs *regs,
261					size_t frame_size)
262{
263	unsigned long sp;
264
265	/* default to using normal stack */
266	sp = regs->sp;
267
268	/* this is the X/Open sanctioned signal stack switching.  */
269	if (ka->sa.sa_flags & SA_ONSTACK) {
270		if (sas_ss_flags(sp) == 0)
271			sp = current->sas_ss_sp + current->sas_ss_size;
272	}
273
274	return (void __user *) ((sp - frame_size) & ~7UL);
275}
276
277/*
278 * set up a normal signal frame
279 */
280static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
281		       struct pt_regs *regs)
282{
283	struct sigframe __user *frame;
284	int rsig;
285
286	frame = get_sigframe(ka, regs, sizeof(*frame));
287
288	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
289		goto give_sigsegv;
290
291	rsig = sig;
292	if (sig < 32 &&
293	    current_thread_info()->exec_domain &&
294	    current_thread_info()->exec_domain->signal_invmap)
295		rsig = current_thread_info()->exec_domain->signal_invmap[sig];
296
297	if (__put_user(rsig, &frame->sig) < 0 ||
298	    __put_user(&frame->sc, &frame->psc) < 0)
299		goto give_sigsegv;
300
301	if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
302		goto give_sigsegv;
303
304	if (_NSIG_WORDS > 1) {
305		if (__copy_to_user(frame->extramask, &set->sig[1],
306				   sizeof(frame->extramask)))
307			goto give_sigsegv;
308	}
309
310	/* set up to return from userspace.  If provided, use a stub already in
311	 * userspace */
312	if (ka->sa.sa_flags & SA_RESTORER) {
313		if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
314			goto give_sigsegv;
315	} else {
316		if (__put_user((void (*)(void))frame->retcode,
317			       &frame->pretcode))
318			goto give_sigsegv;
319		/* this is mov $,d0; syscall 0 */
320		if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
321		    __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
322		    __put_user(0x00, (char *)(frame->retcode + 2)) ||
323		    __put_user(0xf0, (char *)(frame->retcode + 3)) ||
324		    __put_user(0xe0, (char *)(frame->retcode + 4)))
325			goto give_sigsegv;
326		flush_icache_range((unsigned long) frame->retcode,
327				   (unsigned long) frame->retcode + 5);
328	}
329
330	/* set up registers for signal handler */
331	regs->sp = (unsigned long) frame;
332	regs->pc = (unsigned long) ka->sa.sa_handler;
333	regs->d0 = sig;
334	regs->d1 = (unsigned long) &frame->sc;
335
336	/* the tracer may want to single-step inside the handler */
337	if (test_thread_flag(TIF_SINGLESTEP))
338		ptrace_notify(SIGTRAP);
339
340#if DEBUG_SIG
341	printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
342	       sig, current->comm, current->pid, frame, regs->pc,
343	       frame->pretcode);
344#endif
345
346	return 0;
347
348give_sigsegv:
349	force_sigsegv(sig, current);
350	return -EFAULT;
351}
352
353/*
354 * set up a realtime signal frame
355 */
356static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
357			  sigset_t *set, struct pt_regs *regs)
358{
359	struct rt_sigframe __user *frame;
360	int rsig;
361
362	frame = get_sigframe(ka, regs, sizeof(*frame));
363
364	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
365		goto give_sigsegv;
366
367	rsig = sig;
368	if (sig < 32 &&
369	    current_thread_info()->exec_domain &&
370	    current_thread_info()->exec_domain->signal_invmap)
371		rsig = current_thread_info()->exec_domain->signal_invmap[sig];
372
373	if (__put_user(rsig, &frame->sig) ||
374	    __put_user(&frame->info, &frame->pinfo) ||
375	    __put_user(&frame->uc, &frame->puc) ||
376	    copy_siginfo_to_user(&frame->info, info))
377		goto give_sigsegv;
378
379	/* create the ucontext.  */
380	if (__put_user(0, &frame->uc.uc_flags) ||
381	    __put_user(0, &frame->uc.uc_link) ||
382	    __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp) ||
383	    __put_user(sas_ss_flags(regs->sp), &frame->uc.uc_stack.ss_flags) ||
384	    __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size) ||
385	    setup_sigcontext(&frame->uc.uc_mcontext,
386			     &frame->fpuctx, regs, set->sig[0]) ||
387	    __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
388		goto give_sigsegv;
389
390	/* set up to return from userspace.  If provided, use a stub already in
391	 * userspace */
392	if (ka->sa.sa_flags & SA_RESTORER) {
393		if (__put_user(ka->sa.sa_restorer, &frame->pretcode))
394			goto give_sigsegv;
395	} else {
396		if (__put_user((void(*)(void))frame->retcode,
397			       &frame->pretcode) ||
398		    /* This is mov $,d0; syscall 0 */
399		    __put_user(0x2c, (char *)(frame->retcode + 0)) ||
400		    __put_user(__NR_rt_sigreturn,
401			       (char *)(frame->retcode + 1)) ||
402		    __put_user(0x00, (char *)(frame->retcode + 2)) ||
403		    __put_user(0xf0, (char *)(frame->retcode + 3)) ||
404		    __put_user(0xe0, (char *)(frame->retcode + 4)))
405			goto give_sigsegv;
406
407		flush_icache_range((u_long) frame->retcode,
408				   (u_long) frame->retcode + 5);
409	}
410
411	/* Set up registers for signal handler */
412	regs->sp = (unsigned long) frame;
413	regs->pc = (unsigned long) ka->sa.sa_handler;
414	regs->d0 = sig;
415	regs->d1 = (long) &frame->info;
416
417	/* the tracer may want to single-step inside the handler */
418	if (test_thread_flag(TIF_SINGLESTEP))
419		ptrace_notify(SIGTRAP);
420
421#if DEBUG_SIG
422	printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
423	       sig, current->comm, current->pid, frame, regs->pc,
424	       frame->pretcode);
425#endif
426
427	return 0;
428
429give_sigsegv:
430	force_sigsegv(sig, current);
431	return -EFAULT;
432}
433
434static inline void stepback(struct pt_regs *regs)
435{
436	regs->pc -= 2;
437	regs->orig_d0 = -1;
438}
439
440/*
441 * handle the actual delivery of a signal to userspace
442 */
443static int handle_signal(int sig,
444			 siginfo_t *info, struct k_sigaction *ka,
445			 sigset_t *oldset, struct pt_regs *regs)
446{
447	int ret;
448
449	/* Are we from a system call? */
450	if (regs->orig_d0 >= 0) {
451		/* If so, check system call restarting.. */
452		switch (regs->d0) {
453		case -ERESTART_RESTARTBLOCK:
454		case -ERESTARTNOHAND:
455			regs->d0 = -EINTR;
456			break;
457
458		case -ERESTARTSYS:
459			if (!(ka->sa.sa_flags & SA_RESTART)) {
460				regs->d0 = -EINTR;
461				break;
462			}
463
464			/* fallthrough */
465		case -ERESTARTNOINTR:
466			regs->d0 = regs->orig_d0;
467			stepback(regs);
468		}
469	}
470
471	/* Set up the stack frame */
472	if (ka->sa.sa_flags & SA_SIGINFO)
473		ret = setup_rt_frame(sig, ka, info, oldset, regs);
474	else
475		ret = setup_frame(sig, ka, oldset, regs);
476
477	if (ret == 0) {
478		spin_lock_irq(&current->sighand->siglock);
479		sigorsets(&current->blocked, &current->blocked,
480			  &ka->sa.sa_mask);
481		if (!(ka->sa.sa_flags & SA_NODEFER))
482			sigaddset(&current->blocked, sig);
483		recalc_sigpending();
484		spin_unlock_irq(&current->sighand->siglock);
485	}
486
487	return ret;
488}
489
490/*
491 * handle a potential signal
492 */
493static void do_signal(struct pt_regs *regs)
494{
495	struct k_sigaction ka;
496	siginfo_t info;
497	sigset_t *oldset;
498	int signr;
499
500	/* we want the common case to go fast, which is why we may in certain
501	 * cases get here from kernel mode */
502	if (!user_mode(regs))
503		return;
504
505	if (test_thread_flag(TIF_RESTORE_SIGMASK))
506		oldset = &current->saved_sigmask;
507	else
508		oldset = &current->blocked;
509
510	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
511	if (signr > 0) {
512		if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
513			/* a signal was successfully delivered; the saved
514			 * sigmask will have been stored in the signal frame,
515			 * and will be restored by sigreturn, so we can simply
516			 * clear the TIF_RESTORE_SIGMASK flag */
517			if (test_thread_flag(TIF_RESTORE_SIGMASK))
518				clear_thread_flag(TIF_RESTORE_SIGMASK);
519
520			tracehook_signal_handler(signr, &info, &ka, regs,
521						 test_thread_flag(TIF_SINGLESTEP));
522		}
523
524		return;
525	}
526
527	/* did we come from a system call? */
528	if (regs->orig_d0 >= 0) {
529		/* restart the system call - no handlers present */
530		switch (regs->d0) {
531		case -ERESTARTNOHAND:
532		case -ERESTARTSYS:
533		case -ERESTARTNOINTR:
534			regs->d0 = regs->orig_d0;
535			stepback(regs);
536			break;
537
538		case -ERESTART_RESTARTBLOCK:
539			regs->d0 = __NR_restart_syscall;
540			stepback(regs);
541			break;
542		}
543	}
544
545	/* if there's no signal to deliver, we just put the saved sigmask
546	 * back */
547	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
548		clear_thread_flag(TIF_RESTORE_SIGMASK);
549		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
550	}
551}
552
553/*
554 * notification of userspace execution resumption
555 * - triggered by current->work.notify_resume
556 */
557asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
558{
559	/* Pending single-step? */
560	if (thread_info_flags & _TIF_SINGLESTEP) {
561#ifndef CONFIG_MN10300_USING_JTAG
562		regs->epsw |= EPSW_T;
563		clear_thread_flag(TIF_SINGLESTEP);
564#else
565		BUG(); /* no h/w single-step if using JTAG unit */
566#endif
567	}
568
569	/* deal with pending signal delivery */
570	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
571		do_signal(regs);
572
573	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
574		clear_thread_flag(TIF_NOTIFY_RESUME);
575		tracehook_notify_resume(__frame);
576		if (current->replacement_session_keyring)
577			key_replace_session_keyring();
578	}
579}
580