Linux Audio

Check our new training course

Loading...
v3.5.6
  1/*
  2 *  linux/arch/h8300/kernel/signal.c
  3 *
  4 *  Copyright (C) 1991, 1992  Linus Torvalds
  5 *
  6 * This file is subject to the terms and conditions of the GNU General Public
  7 * License.  See the file COPYING in the main directory of this archive
  8 * for more details.
  9 */
 10
 11/*
 12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp>
 13 *                and David McCullough <davidm@snapgear.com>
 14 *
 15 * Based on
 16 * Linux/m68k by Hamish Macdonald
 17 */
 18
 19/*
 20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
 21 * Atari :-) Current limitation: Only one sigstack can be active at one time.
 22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
 23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
 24 * signal handlers!
 25 */
 26
 27#include <linux/sched.h>
 
 28#include <linux/mm.h>
 29#include <linux/kernel.h>
 30#include <linux/signal.h>
 31#include <linux/syscalls.h>
 32#include <linux/errno.h>
 33#include <linux/wait.h>
 34#include <linux/ptrace.h>
 35#include <linux/unistd.h>
 36#include <linux/stddef.h>
 37#include <linux/highuid.h>
 38#include <linux/personality.h>
 39#include <linux/tty.h>
 40#include <linux/binfmts.h>
 41#include <linux/freezer.h>
 42#include <linux/tracehook.h>
 43
 44#include <asm/setup.h>
 45#include <asm/uaccess.h>
 46#include <asm/pgtable.h>
 47#include <asm/traps.h>
 48#include <asm/ucontext.h>
 49
 50/*
 51 * Atomically swap in the new signal mask, and wait for a signal.
 52 */
 53asmlinkage int
 54sys_sigsuspend(int unused1, int unused2, old_sigset_t mask)
 55{
 56	sigset_t blocked;
 57	siginitset(&blocked, mask);
 58	return sigsuspend(&blocked);
 59}
 60
 61asmlinkage int 
 62sys_sigaction(int sig, const struct old_sigaction *act,
 63	      struct old_sigaction *oact)
 64{
 65	struct k_sigaction new_ka, old_ka;
 66	int ret;
 67
 68	if (act) {
 69		old_sigset_t mask;
 70		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
 71		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
 72		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
 73		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
 74		    __get_user(mask, &act->sa_mask))
 75			return -EFAULT;
 76		siginitset(&new_ka.sa.sa_mask, mask);
 77	}
 78
 79	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 80
 81	if (!ret && oact) {
 82		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
 83		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
 84		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
 85		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
 86		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 87			return -EFAULT;
 88	}
 89
 90	return ret;
 91}
 92
 93asmlinkage int
 94sys_sigaltstack(const stack_t *uss, stack_t *uoss)
 95{
 96	return do_sigaltstack(uss, uoss, rdusp());
 97}
 98
 99
100/*
101 * Do a signal return; undo the signal stack.
102 *
103 * Keep the return code on the stack quadword aligned!
104 * That makes the cache flush below easier.
105 */
106
107struct sigframe
108{
109	long dummy_er0;
110	long dummy_vector;
111#if defined(CONFIG_CPU_H8S)
112	short dummy_exr;
113#endif
114	long dummy_pc;
115	char *pretcode;
116	unsigned char retcode[8];
117	unsigned long extramask[_NSIG_WORDS-1];
118	struct sigcontext sc;
119	int sig;
120} __attribute__((aligned(2),packed));
121
122struct rt_sigframe
123{
124	long dummy_er0;
125	long dummy_vector;
126#if defined(CONFIG_CPU_H8S)
127	short dummy_exr;
128#endif
129	long dummy_pc;
130	char *pretcode;
131	struct siginfo *pinfo;
132	void *puc;
133	unsigned char retcode[8];
134	struct siginfo info;
135	struct ucontext uc;
136	int sig;
137} __attribute__((aligned(2),packed));
138
139static inline int
140restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc,
141		   int *pd0)
142{
 
143	int err = 0;
144	unsigned int ccr;
145	unsigned int usp;
146	unsigned int er0;
147
148	/* Always make any pending restarted system calls return -EINTR */
149	current_thread_info()->restart_block.fn = do_no_restart_syscall;
150
151#define COPY(r) err |= __get_user(regs->r, &usc->sc_##r)    /* restore passed registers */
 
152	COPY(er1);
153	COPY(er2);
154	COPY(er3);
155	COPY(er5);
156	COPY(pc);
157	ccr = regs->ccr & 0x10;
158	COPY(ccr);
159#undef COPY
160	regs->ccr &= 0xef;
161	regs->ccr |= ccr;
162	regs->orig_er0 = -1;		/* disable syscall checks */
163	err |= __get_user(usp, &usc->sc_usp);
164	wrusp(usp);
165
166	err |= __get_user(er0, &usc->sc_er0);
167	*pd0 = er0;
168	return err;
169}
170
171asmlinkage int do_sigreturn(unsigned long __unused,...)
172{
173	struct pt_regs *regs = (struct pt_regs *) (&__unused - 1);
174	unsigned long usp = rdusp();
175	struct sigframe *frame = (struct sigframe *)(usp - 4);
176	sigset_t set;
177	int er0;
178
179	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
180		goto badframe;
181	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
182	    (_NSIG_WORDS > 1 &&
183	     __copy_from_user(&set.sig[1], &frame->extramask,
184			      sizeof(frame->extramask))))
185		goto badframe;
186
187	set_current_blocked(&set);
188	
189	if (restore_sigcontext(regs, &frame->sc, &er0))
190		goto badframe;
191	return er0;
192
193badframe:
194	force_sig(SIGSEGV, current);
195	return 0;
196}
197
198asmlinkage int do_rt_sigreturn(unsigned long __unused,...)
199{
200	struct pt_regs *regs = (struct pt_regs *) &__unused;
201	unsigned long usp = rdusp();
202	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
203	sigset_t set;
204	int er0;
205
206	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
207		goto badframe;
208	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
209		goto badframe;
210
211	set_current_blocked(&set);
212	
213	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &er0))
214		goto badframe;
215
216	if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
217		goto badframe;
218
219	return er0;
220
221badframe:
222	force_sig(SIGSEGV, current);
223	return 0;
224}
225
226static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
227			     unsigned long mask)
228{
229	int err = 0;
230
231	err |= __put_user(regs->er0, &sc->sc_er0);
232	err |= __put_user(regs->er1, &sc->sc_er1);
233	err |= __put_user(regs->er2, &sc->sc_er2);
234	err |= __put_user(regs->er3, &sc->sc_er3);
235	err |= __put_user(regs->er4, &sc->sc_er4);
236	err |= __put_user(regs->er5, &sc->sc_er5);
237	err |= __put_user(regs->er6, &sc->sc_er6);
238	err |= __put_user(rdusp(),   &sc->sc_usp);
239	err |= __put_user(regs->pc,  &sc->sc_pc);
240	err |= __put_user(regs->ccr, &sc->sc_ccr);
241	err |= __put_user(mask,      &sc->sc_mask);
242
243	return err;
244}
245
246static inline void *
247get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
248{
249	unsigned long usp;
250
251	/* Default to using normal stack.  */
252	usp = rdusp();
253
254	/* This is the X/Open sanctioned signal stack switching.  */
255	if (ka->sa.sa_flags & SA_ONSTACK) {
256		if (!sas_ss_flags(usp))
257			usp = current->sas_ss_sp + current->sas_ss_size;
258	}
259	return (void *)((usp - frame_size) & -8UL);
260}
261
262static int setup_frame (int sig, struct k_sigaction *ka,
263			 sigset_t *set, struct pt_regs *regs)
264{
265	struct sigframe *frame;
266	int err = 0;
267	int usig;
268	unsigned char *ret;
269
270	frame = get_sigframe(ka, regs, sizeof(*frame));
271
272	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
273		goto give_sigsegv;
274
275	usig = current_thread_info()->exec_domain
276		&& current_thread_info()->exec_domain->signal_invmap
277		&& sig < 32
278		? current_thread_info()->exec_domain->signal_invmap[sig]
279		: sig;
280
281	err |= __put_user(usig, &frame->sig);
282	if (err)
283		goto give_sigsegv;
284
285	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
286	if (err)
287		goto give_sigsegv;
288
289	if (_NSIG_WORDS > 1) {
290		err |= copy_to_user(frame->extramask, &set->sig[1],
291				    sizeof(frame->extramask));
292		if (err)
293			goto give_sigsegv;
294	}
295
296	ret = frame->retcode;
297	if (ka->sa.sa_flags & SA_RESTORER)
298		ret = (unsigned char *)(ka->sa.sa_restorer);
299	else {
300		/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
301		err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
302				  (unsigned long *)(frame->retcode + 0));
303		err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
304	}
305
306	/* Set up to return from userspace.  */
307	err |= __put_user(ret, &frame->pretcode);
308
309	if (err)
310		goto give_sigsegv;
311
312	/* Set up registers for signal handler */
313	wrusp ((unsigned long) frame);
314	regs->pc = (unsigned long) ka->sa.sa_handler;
315	regs->er0 = (current_thread_info()->exec_domain
316			   && current_thread_info()->exec_domain->signal_invmap
317			   && sig < 32
318			   ? current_thread_info()->exec_domain->signal_invmap[sig]
319		          : sig);
320	regs->er1 = (unsigned long)&(frame->sc);
321	regs->er5 = current->mm->start_data;	/* GOT base */
322
323	return 0;
324
325give_sigsegv:
326	force_sigsegv(sig, current);
327	return -EFAULT;
328}
329
330static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
331			    sigset_t *set, struct pt_regs *regs)
332{
333	struct rt_sigframe *frame;
334	int err = 0;
335	int usig;
336	unsigned char *ret;
337
338	frame = get_sigframe(ka, regs, sizeof(*frame));
339
340	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
341		goto give_sigsegv;
342
343	usig = current_thread_info()->exec_domain
344		&& current_thread_info()->exec_domain->signal_invmap
345		&& sig < 32
346		? current_thread_info()->exec_domain->signal_invmap[sig]
347		: sig;
348
349	err |= __put_user(usig, &frame->sig);
350	if (err)
351		goto give_sigsegv;
352
353	err |= __put_user(&frame->info, &frame->pinfo);
354	err |= __put_user(&frame->uc, &frame->puc);
355	err |= copy_siginfo_to_user(&frame->info, info);
356	if (err)
357		goto give_sigsegv;
358
359	/* Create the ucontext.  */
360	err |= __put_user(0, &frame->uc.uc_flags);
361	err |= __put_user(0, &frame->uc.uc_link);
362	err |= __put_user((void *)current->sas_ss_sp,
363			  &frame->uc.uc_stack.ss_sp);
364	err |= __put_user(sas_ss_flags(rdusp()),
365			  &frame->uc.uc_stack.ss_flags);
366	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
367	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
368	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
369	if (err)
370		goto give_sigsegv;
371
372	/* Set up to return from userspace.  */
373	ret = frame->retcode;
374	if (ka->sa.sa_flags & SA_RESTORER)
375		ret = (unsigned char *)(ka->sa.sa_restorer);
376	else {
377		/* sub.l er0,er0; mov.b #__NR_sigreturn,r0l; trapa #0 */
378		err |= __put_user(0x1a80f800 + (__NR_sigreturn & 0xff),
379				  (unsigned long *)(frame->retcode + 0));
380		err |= __put_user(0x5700, (unsigned short *)(frame->retcode + 4));
 
381	}
382	err |= __put_user(ret, &frame->pretcode);
383
384	if (err)
385		goto give_sigsegv;
386
387	/* Set up registers for signal handler */
388	wrusp ((unsigned long) frame);
389	regs->pc  = (unsigned long) ka->sa.sa_handler;
390	regs->er0 = (current_thread_info()->exec_domain
391		     && current_thread_info()->exec_domain->signal_invmap
392		     && sig < 32
393		     ? current_thread_info()->exec_domain->signal_invmap[sig]
394		     : sig);
395	regs->er1 = (unsigned long)&(frame->info);
396	regs->er2 = (unsigned long)&frame->uc;
397	regs->er5 = current->mm->start_data;	/* GOT base */
398
399	return 0;
 
400
401give_sigsegv:
402	force_sigsegv(sig, current);
403	return -EFAULT;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404}
405
406/*
407 * OK, we're invoking a handler
408 */
409static void
410handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
411	      struct pt_regs * regs)
412{
413	sigset_t *oldset = sigmask_to_save();
414	int ret;
415	/* are we from a system call? */
416	if (regs->orig_er0 >= 0) {
417		switch (regs->er0) {
418		        case -ERESTART_RESTARTBLOCK:
419			case -ERESTARTNOHAND:
420				regs->er0 = -EINTR;
421				break;
422
423			case -ERESTARTSYS:
424				if (!(ka->sa.sa_flags & SA_RESTART)) {
425					regs->er0 = -EINTR;
426					break;
427				}
428			/* fallthrough */
429			case -ERESTARTNOINTR:
430				regs->er0 = regs->orig_er0;
431				regs->pc -= 2;
432		}
433	}
434
435	/* set up the stack frame */
436	if (ka->sa.sa_flags & SA_SIGINFO)
437		ret = setup_rt_frame(sig, ka, info, oldset, regs);
438	else
439		ret = setup_frame(sig, ka, oldset, regs);
440
441	if (!ret)
442		signal_delivered(sig, info, ka, regs, 0);
443}
444
445/*
446 * Note that 'init' is a special process: it doesn't get signals it doesn't
447 * want to handle. Thus you cannot kill init even with a SIGKILL even by
448 * mistake.
449 */
450static void do_signal(struct pt_regs *regs)
451{
452	siginfo_t info;
453	int signr;
454	struct k_sigaction ka;
455
456	/*
457	 * We want the common case to go fast, which
458	 * is why we may in certain cases get here from
459	 * kernel mode. Just return without doing anything
460	 * if so.
461	 */
462	if ((regs->ccr & 0x10))
463		return;
464
465	current->thread.esp0 = (unsigned long) regs;
466
467	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
468	if (signr > 0) {
469		/* Whee!  Actually deliver the signal.  */
470		handle_signal(signr, &info, &ka, regs);
471		return;
472	}
473	/* Did we come from a system call? */
474	if (regs->orig_er0 >= 0) {
475		/* Restart the system call - no handlers present */
476		if (regs->er0 == -ERESTARTNOHAND ||
477		    regs->er0 == -ERESTARTSYS ||
478		    regs->er0 == -ERESTARTNOINTR) {
479			regs->er0 = regs->orig_er0;
480			regs->pc -= 2;
481		}
482		if (regs->er0 == -ERESTART_RESTARTBLOCK){
483			regs->er0 = __NR_restart_syscall;
484			regs->pc -= 2;
485		}
486	}
487
488	/* If there's no signal to deliver, we just restore the saved mask.  */
489	restore_saved_sigmask();
490}
491
492asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
493{
494	if (thread_info_flags & _TIF_SIGPENDING)
495		do_signal(regs);
496
497	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
498		clear_thread_flag(TIF_NOTIFY_RESUME);
499		tracehook_notify_resume(regs);
500	}
501}
v4.17
  1/*
  2 *  linux/arch/h8300/kernel/signal.c
  3 *
  4 *  Copyright (C) 1991, 1992  Linus Torvalds
  5 *
  6 * This file is subject to the terms and conditions of the GNU General Public
  7 * License.  See the file COPYING in the main directory of this archive
  8 * for more details.
  9 */
 10
 11/*
 12 * uClinux H8/300 support by Yoshinori Sato <ysato@users.sourceforge.jp>
 13 *                and David McCullough <davidm@snapgear.com>
 14 *
 15 * Based on
 16 * Linux/m68k by Hamish Macdonald
 17 */
 18
 19/*
 20 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
 21 * Atari :-) Current limitation: Only one sigstack can be active at one time.
 22 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
 23 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
 24 * signal handlers!
 25 */
 26
 27#include <linux/sched.h>
 28#include <linux/sched/task_stack.h>
 29#include <linux/mm.h>
 30#include <linux/kernel.h>
 31#include <linux/signal.h>
 32#include <linux/syscalls.h>
 33#include <linux/errno.h>
 34#include <linux/wait.h>
 35#include <linux/ptrace.h>
 36#include <linux/unistd.h>
 37#include <linux/stddef.h>
 38#include <linux/highuid.h>
 39#include <linux/personality.h>
 40#include <linux/tty.h>
 41#include <linux/binfmts.h>
 
 42#include <linux/tracehook.h>
 43
 44#include <asm/setup.h>
 45#include <linux/uaccess.h>
 46#include <asm/pgtable.h>
 47#include <asm/traps.h>
 48#include <asm/ucontext.h>
 49
 50/*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 51 * Do a signal return; undo the signal stack.
 52 *
 53 * Keep the return code on the stack quadword aligned!
 54 * That makes the cache flush below easier.
 55 */
 56
 57struct rt_sigframe {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 58	long dummy_er0;
 59	long dummy_vector;
 60#if defined(CONFIG_CPU_H8S)
 61	short dummy_exr;
 62#endif
 63	long dummy_pc;
 64	char *pretcode;
 65	struct siginfo *pinfo;
 66	void *puc;
 67	unsigned char retcode[8];
 68	struct siginfo info;
 69	struct ucontext uc;
 70	int sig;
 71} __packed __aligned(2);
 72
 73static inline int
 74restore_sigcontext(struct sigcontext *usc, int *pd0)
 
 75{
 76	struct pt_regs *regs = current_pt_regs();
 77	int err = 0;
 78	unsigned int ccr;
 79	unsigned int usp;
 80	unsigned int er0;
 81
 82	/* Always make any pending restarted system calls return -EINTR */
 83	current->restart_block.fn = do_no_restart_syscall;
 84
 85	/* restore passed registers */
 86#define COPY(r)  do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
 87	COPY(er1);
 88	COPY(er2);
 89	COPY(er3);
 90	COPY(er5);
 91	COPY(pc);
 92	ccr = regs->ccr & 0x10;
 93	COPY(ccr);
 94#undef COPY
 95	regs->ccr &= 0xef;
 96	regs->ccr |= ccr;
 97	regs->orig_er0 = -1;		/* disable syscall checks */
 98	err |= __get_user(usp, &usc->sc_usp);
 99	regs->sp = usp;
100
101	err |= __get_user(er0, &usc->sc_er0);
102	*pd0 = er0;
103	return err;
104}
105
106asmlinkage int sys_rt_sigreturn(void)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107{
 
108	unsigned long usp = rdusp();
109	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
110	sigset_t set;
111	int er0;
112
113	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
114		goto badframe;
115	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
116		goto badframe;
117
118	set_current_blocked(&set);
119
120	if (restore_sigcontext(&frame->uc.uc_mcontext, &er0))
121		goto badframe;
122
123	if (restore_altstack(&frame->uc.uc_stack))
124		goto badframe;
125
126	return er0;
127
128badframe:
129	force_sig(SIGSEGV, current);
130	return 0;
131}
132
133static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
134			     unsigned long mask)
135{
136	int err = 0;
137
138	err |= __put_user(regs->er0, &sc->sc_er0);
139	err |= __put_user(regs->er1, &sc->sc_er1);
140	err |= __put_user(regs->er2, &sc->sc_er2);
141	err |= __put_user(regs->er3, &sc->sc_er3);
142	err |= __put_user(regs->er4, &sc->sc_er4);
143	err |= __put_user(regs->er5, &sc->sc_er5);
144	err |= __put_user(regs->er6, &sc->sc_er6);
145	err |= __put_user(rdusp(),   &sc->sc_usp);
146	err |= __put_user(regs->pc,  &sc->sc_pc);
147	err |= __put_user(regs->ccr, &sc->sc_ccr);
148	err |= __put_user(mask,      &sc->sc_mask);
149
150	return err;
151}
152
153static inline void __user *
154get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size)
155{
156	return (void __user *)((sigsp(rdusp(), ksig) - frame_size) & -8UL);
 
 
 
 
 
 
 
 
 
 
157}
158
159static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
160			  struct pt_regs *regs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161{
162	struct rt_sigframe *frame;
163	int err = 0;
 
164	unsigned char *ret;
165
166	frame = get_sigframe(ksig, regs, sizeof(*frame));
167
168	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
169		return -EFAULT;
 
 
 
 
 
 
170
171	if (ksig->ka.sa.sa_flags & SA_SIGINFO)
172		err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 
 
 
 
 
 
 
173
174	/* Create the ucontext.  */
175	err |= __put_user(0, &frame->uc.uc_flags);
176	err |= __put_user(0, &frame->uc.uc_link);
177	err |= __save_altstack(&frame->uc.uc_stack, rdusp());
 
 
 
 
178	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
179	err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
180	if (err)
181		return -EFAULT;
182
183	/* Set up to return from userspace.  */
184	ret = (unsigned char *)&frame->retcode;
185	if (ksig->ka.sa.sa_flags & SA_RESTORER)
186		ret = (unsigned char *)(ksig->ka.sa.sa_restorer);
187	else {
188		/* sub.l er0,er0; mov.b #__NR_rt_sigreturn,r0l; trapa #0 */
189		err |= __put_user(0x1a80f800 + (__NR_rt_sigreturn & 0xff),
190				  (unsigned long *)(frame->retcode + 0));
191		err |= __put_user(0x5700,
192				  (unsigned short *)(frame->retcode + 4));
193	}
194	err |= __put_user(ret, &frame->pretcode);
195
196	if (err)
197		return -EFAULT;
198
199	/* Set up registers for signal handler */
200	regs->sp  = (unsigned long)frame;
201	regs->pc  = (unsigned long)ksig->ka.sa.sa_handler;
202	regs->er0 = ksig->sig;
 
 
 
 
203	regs->er1 = (unsigned long)&(frame->info);
204	regs->er2 = (unsigned long)&frame->uc;
205	regs->er5 = current->mm->start_data;	/* GOT base */
206
207	return 0;
208}
209
210static void
211handle_restart(struct pt_regs *regs, struct k_sigaction *ka)
212{
213	switch (regs->er0) {
214	case -ERESTARTNOHAND:
215		if (!ka)
216			goto do_restart;
217		regs->er0 = -EINTR;
218		break;
219	case -ERESTART_RESTARTBLOCK:
220		if (!ka) {
221			regs->er0 = __NR_restart_syscall;
222			regs->pc -= 2;
223		} else
224			regs->er0 = -EINTR;
225		break;
226	case -ERESTARTSYS:
227		if (!(ka->sa.sa_flags & SA_RESTART)) {
228			regs->er0 = -EINTR;
229			break;
230		}
231		/* fallthrough */
232	case -ERESTARTNOINTR:
233do_restart:
234		regs->er0 = regs->orig_er0;
235		regs->pc -= 2;
236		break;
237	}
238}
239
240/*
241 * OK, we're invoking a handler
242 */
243static void
244handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 
245{
246	sigset_t *oldset = sigmask_to_save();
247	int ret;
248	/* are we from a system call? */
249	if (regs->orig_er0 >= 0)
250		handle_restart(regs, &ksig->ka);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
252	ret = setup_rt_frame(ksig, oldset, regs);
 
 
 
 
253
254	signal_setup_done(ret, ksig, 0);
 
255}
256
257/*
258 * Note that 'init' is a special process: it doesn't get signals it doesn't
259 * want to handle. Thus you cannot kill init even with a SIGKILL even by
260 * mistake.
261 */
262static void do_signal(struct pt_regs *regs)
263{
264	struct ksignal ksig;
 
 
 
 
 
 
 
 
 
 
 
265
266	current->thread.esp0 = (unsigned long) regs;
267
268	if (get_signal(&ksig)) {
 
269		/* Whee!  Actually deliver the signal.  */
270		handle_signal(&ksig, regs);
271		return;
272	}
273	/* Did we come from a system call? */
274	if (regs->orig_er0 >= 0)
275		handle_restart(regs, NULL);
 
 
 
 
 
 
 
 
 
 
 
276
277	/* If there's no signal to deliver, we just restore the saved mask.  */
278	restore_saved_sigmask();
279}
280
281asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
282{
283	if (thread_info_flags & _TIF_SIGPENDING)
284		do_signal(regs);
285
286	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
287		clear_thread_flag(TIF_NOTIFY_RESUME);
288		tracehook_notify_resume(regs);
289	}
290}