1/*
2 *  linux/arch/m68knommu/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 * Linux/m68k support by Hamish Macdonald
13 *
14 * 68060 fixes by Jesper Skov
15 *
16 * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
17 *
18 * mathemu support by Roman Zippel
19 *  (Note: fpstate in the signal context is completely ignored for the emulator
20 *         and the internal floating point format is put on stack)
21 */
22
23/*
24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
25 * Atari :-) Current limitation: Only one sigstack can be active at one time.
26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
28 * signal handlers!
29 */
30
31#include <linux/sched.h>
32#include <linux/mm.h>
33#include <linux/kernel.h>
34#include <linux/signal.h>
35#include <linux/syscalls.h>
36#include <linux/errno.h>
37#include <linux/wait.h>
38#include <linux/ptrace.h>
39#include <linux/unistd.h>
40#include <linux/stddef.h>
41#include <linux/highuid.h>
42#include <linux/tty.h>
43#include <linux/personality.h>
44#include <linux/binfmts.h>
45
46#include <asm/setup.h>
47#include <asm/uaccess.h>
48#include <asm/pgtable.h>
49#include <asm/traps.h>
50#include <asm/ucontext.h>
51
52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
53
54asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
55
56/*
57 * Atomically swap in the new signal mask, and wait for a signal.
58 */
59asmlinkage int do_sigsuspend(struct pt_regs *regs)
60{
61	old_sigset_t mask = regs->d3;
62	sigset_t saveset;
63
64	mask &= _BLOCKABLE;
65	spin_lock_irq(&current->sighand->siglock);
66	saveset = current->blocked;
67	siginitset(&current->blocked, mask);
68	recalc_sigpending();
69	spin_unlock_irq(&current->sighand->siglock);
70
71	regs->d0 = -EINTR;
72	while (1) {
73		current->state = TASK_INTERRUPTIBLE;
74		schedule();
75		if (do_signal(&saveset, regs))
76			return -EINTR;
77	}
78}
79
80asmlinkage int
81do_rt_sigsuspend(struct pt_regs *regs)
82{
83	sigset_t *unewset = (sigset_t *)regs->d1;
84	size_t sigsetsize = (size_t)regs->d2;
85	sigset_t saveset, newset;
86
87	if (sigsetsize != sizeof(sigset_t))
88		return -EINVAL;
89
90	if (copy_from_user(&newset, unewset, sizeof(newset)))
91		return -EFAULT;
92	sigdelsetmask(&newset, ~_BLOCKABLE);
93
94	spin_lock_irq(&current->sighand->siglock);
95	saveset = current->blocked;
96	current->blocked = newset;
97	recalc_sigpending();
98	spin_unlock_irq(&current->sighand->siglock);
99
100	regs->d0 = -EINTR;
101	while (1) {
102		current->state = TASK_INTERRUPTIBLE;
103		schedule();
104		if (do_signal(&saveset, regs))
105			return -EINTR;
106	}
107}
108
109asmlinkage int
110sys_sigaction(int sig, const struct old_sigaction *act,
111	      struct old_sigaction *oact)
112{
113	struct k_sigaction new_ka, old_ka;
114	int ret;
115
116	if (act) {
117		old_sigset_t mask;
118		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
119		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
120		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
121			return -EFAULT;
122		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
123		__get_user(mask, &act->sa_mask);
124		siginitset(&new_ka.sa.sa_mask, mask);
125	}
126
127	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
128
129	if (!ret && oact) {
130		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
131		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
132		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
133			return -EFAULT;
134		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
135		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
136	}
137
138	return ret;
139}
140
141asmlinkage int
142sys_sigaltstack(const stack_t *uss, stack_t *uoss)
143{
144	return do_sigaltstack(uss, uoss, rdusp());
145}
146
147
148/*
149 * Do a signal return; undo the signal stack.
150 *
151 * Keep the return code on the stack quadword aligned!
152 * That makes the cache flush below easier.
153 */
154
155struct sigframe
156{
157	char *pretcode;
158	int sig;
159	int code;
160	struct sigcontext *psc;
161	char retcode[8];
162	unsigned long extramask[_NSIG_WORDS-1];
163	struct sigcontext sc;
164};
165
166struct rt_sigframe
167{
168	char *pretcode;
169	int sig;
170	struct siginfo *pinfo;
171	void *puc;
172	char retcode[8];
173	struct siginfo info;
174	struct ucontext uc;
175};
176
177#ifdef CONFIG_FPU
178
179static unsigned char fpu_version = 0;	/* version number of fpu, set by setup_frame */
180
181static inline int restore_fpu_state(struct sigcontext *sc)
182{
183	int err = 1;
184
185	if (FPU_IS_EMU) {
186	    /* restore registers */
187	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
188	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
189	    return 0;
190	}
191
192	if (sc->sc_fpstate[0]) {
193	    /* Verify the frame format.  */
194	    if (sc->sc_fpstate[0] != fpu_version)
195		goto out;
196
197	    __asm__ volatile (".chip 68k/68881\n\t"
198			      "fmovemx %0,%/fp0-%/fp1\n\t"
199			      "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
200			      ".chip 68k"
201			      : /* no outputs */
202			      : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
203	}
204	__asm__ volatile (".chip 68k/68881\n\t"
205			  "frestore %0\n\t"
206			  ".chip 68k" : : "m" (*sc->sc_fpstate));
207	err = 0;
208
209out:
210	return err;
211}
212
213#define FPCONTEXT_SIZE	216
214#define uc_fpstate	uc_filler[0]
215#define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
216#define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
217
218static inline int rt_restore_fpu_state(struct ucontext *uc)
219{
220	unsigned char fpstate[FPCONTEXT_SIZE];
221	int context_size = 0;
222	fpregset_t fpregs;
223	int err = 1;
224
225	if (FPU_IS_EMU) {
226		/* restore fpu control register */
227		if (__copy_from_user(current->thread.fpcntl,
228				&uc->uc_mcontext.fpregs.f_pcr, 12))
229			goto out;
230		/* restore all other fpu register */
231		if (__copy_from_user(current->thread.fp,
232				uc->uc_mcontext.fpregs.f_fpregs, 96))
233			goto out;
234		return 0;
235	}
236
237	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
238		goto out;
239	if (fpstate[0]) {
240		context_size = fpstate[1];
241
242		/* Verify the frame format.  */
243		if (fpstate[0] != fpu_version)
244			goto out;
245		if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
246		     sizeof(fpregs)))
247			goto out;
248		__asm__ volatile (".chip 68k/68881\n\t"
249				  "fmovemx %0,%/fp0-%/fp7\n\t"
250				  "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
251				  ".chip 68k"
252				  : /* no outputs */
253				  : "m" (*fpregs.f_fpregs),
254				    "m" (fpregs.f_pcr));
255	}
256	if (context_size &&
257	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
258			     context_size))
259		goto out;
260	__asm__ volatile (".chip 68k/68881\n\t"
261			  "frestore %0\n\t"
262			  ".chip 68k" : : "m" (*fpstate));
263	err = 0;
264
265out:
266	return err;
267}
268
269#endif
270
271static inline int
272restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
273		   int *pd0)
274{
275	int formatvec;
276	struct sigcontext context;
277	int err = 0;
278
279	/* get previous context */
280	if (copy_from_user(&context, usc, sizeof(context)))
281		goto badframe;
282
283	/* restore passed registers */
284	regs->d1 = context.sc_d1;
285	regs->a0 = context.sc_a0;
286	regs->a1 = context.sc_a1;
287	((struct switch_stack *)regs - 1)->a5 = context.sc_a5;
288	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
289	regs->pc = context.sc_pc;
290	regs->orig_d0 = -1;		/* disable syscall checks */
291	wrusp(context.sc_usp);
292	formatvec = context.sc_formatvec;
293	regs->format = formatvec >> 12;
294	regs->vector = formatvec & 0xfff;
295
296#ifdef CONFIG_FPU
297	err = restore_fpu_state(&context);
298#endif
299
300	*pd0 = context.sc_d0;
301	return err;
302
303badframe:
304	return 1;
305}
306
307static inline int
308rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
309		    struct ucontext *uc, int *pd0)
310{
311	int temp;
312	greg_t *gregs = uc->uc_mcontext.gregs;
313	unsigned long usp;
314	int err;
315
316	err = __get_user(temp, &uc->uc_mcontext.version);
317	if (temp != MCONTEXT_VERSION)
318		goto badframe;
319	/* restore passed registers */
320	err |= __get_user(regs->d0, &gregs[0]);
321	err |= __get_user(regs->d1, &gregs[1]);
322	err |= __get_user(regs->d2, &gregs[2]);
323	err |= __get_user(regs->d3, &gregs[3]);
324	err |= __get_user(regs->d4, &gregs[4]);
325	err |= __get_user(regs->d5, &gregs[5]);
326	err |= __get_user(sw->d6, &gregs[6]);
327	err |= __get_user(sw->d7, &gregs[7]);
328	err |= __get_user(regs->a0, &gregs[8]);
329	err |= __get_user(regs->a1, &gregs[9]);
330	err |= __get_user(regs->a2, &gregs[10]);
331	err |= __get_user(sw->a3, &gregs[11]);
332	err |= __get_user(sw->a4, &gregs[12]);
333	err |= __get_user(sw->a5, &gregs[13]);
334	err |= __get_user(sw->a6, &gregs[14]);
335	err |= __get_user(usp, &gregs[15]);
336	wrusp(usp);
337	err |= __get_user(regs->pc, &gregs[16]);
338	err |= __get_user(temp, &gregs[17]);
339	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
340	regs->orig_d0 = -1;		/* disable syscall checks */
341	regs->format = temp >> 12;
342	regs->vector = temp & 0xfff;
343
344	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
345		goto badframe;
346
347	*pd0 = regs->d0;
348	return err;
349
350badframe:
351	return 1;
352}
353
354asmlinkage int do_sigreturn(unsigned long __unused)
355{
356	struct switch_stack *sw = (struct switch_stack *) &__unused;
357	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
358	unsigned long usp = rdusp();
359	struct sigframe *frame = (struct sigframe *)(usp - 4);
360	sigset_t set;
361	int d0;
362
363	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
364		goto badframe;
365	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
366	    (_NSIG_WORDS > 1 &&
367	     __copy_from_user(&set.sig[1], &frame->extramask,
368			      sizeof(frame->extramask))))
369		goto badframe;
370
371	sigdelsetmask(&set, ~_BLOCKABLE);
372	spin_lock_irq(&current->sighand->siglock);
373	current->blocked = set;
374	recalc_sigpending();
375	spin_unlock_irq(&current->sighand->siglock);
376
377	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
378		goto badframe;
379	return d0;
380
381badframe:
382	force_sig(SIGSEGV, current);
383	return 0;
384}
385
386asmlinkage int do_rt_sigreturn(unsigned long __unused)
387{
388	struct switch_stack *sw = (struct switch_stack *) &__unused;
389	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
390	unsigned long usp = rdusp();
391	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
392	sigset_t set;
393	int d0;
394
395	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
396		goto badframe;
397	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
398		goto badframe;
399
400	sigdelsetmask(&set, ~_BLOCKABLE);
401	spin_lock_irq(&current->sighand->siglock);
402	current->blocked = set;
403	recalc_sigpending();
404	spin_unlock_irq(&current->sighand->siglock);
405
406	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
407		goto badframe;
408	return d0;
409
410badframe:
411	force_sig(SIGSEGV, current);
412	return 0;
413}
414
415#ifdef CONFIG_FPU
416/*
417 * Set up a signal frame.
418 */
419
420static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
421{
422	if (FPU_IS_EMU) {
423		/* save registers */
424		memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
425		memcpy(sc->sc_fpregs, current->thread.fp, 24);
426		return;
427	}
428
429	__asm__ volatile (".chip 68k/68881\n\t"
430			  "fsave %0\n\t"
431			  ".chip 68k"
432			  : : "m" (*sc->sc_fpstate) : "memory");
433
434	if (sc->sc_fpstate[0]) {
435		fpu_version = sc->sc_fpstate[0];
436		__asm__ volatile (".chip 68k/68881\n\t"
437				  "fmovemx %/fp0-%/fp1,%0\n\t"
438				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
439				  ".chip 68k"
440				  : /* no outputs */
441				  : "m" (*sc->sc_fpregs),
442				    "m" (*sc->sc_fpcntl)
443				  : "memory");
444	}
445}
446
447static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
448{
449	unsigned char fpstate[FPCONTEXT_SIZE];
450	int context_size = 0;
451	int err = 0;
452
453	if (FPU_IS_EMU) {
454		/* save fpu control register */
455		err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
456				current->thread.fpcntl, 12);
457		/* save all other fpu register */
458		err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
459				current->thread.fp, 96);
460		return err;
461	}
462
463	__asm__ volatile (".chip 68k/68881\n\t"
464			  "fsave %0\n\t"
465			  ".chip 68k"
466			  : : "m" (*fpstate) : "memory");
467
468	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
469	if (fpstate[0]) {
470		fpregset_t fpregs;
471		context_size = fpstate[1];
472		fpu_version = fpstate[0];
473		__asm__ volatile (".chip 68k/68881\n\t"
474				  "fmovemx %/fp0-%/fp7,%0\n\t"
475				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
476				  ".chip 68k"
477				  : /* no outputs */
478				  : "m" (*fpregs.f_fpregs),
479				    "m" (fpregs.f_pcr)
480				  : "memory");
481		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
482				    sizeof(fpregs));
483	}
484	if (context_size)
485		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
486				    context_size);
487	return err;
488}
489
490#endif
491
492static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
493			     unsigned long mask)
494{
495	sc->sc_mask = mask;
496	sc->sc_usp = rdusp();
497	sc->sc_d0 = regs->d0;
498	sc->sc_d1 = regs->d1;
499	sc->sc_a0 = regs->a0;
500	sc->sc_a1 = regs->a1;
501	sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5;
502	sc->sc_sr = regs->sr;
503	sc->sc_pc = regs->pc;
504	sc->sc_formatvec = regs->format << 12 | regs->vector;
505#ifdef CONFIG_FPU
506	save_fpu_state(sc, regs);
507#endif
508}
509
510static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
511{
512	struct switch_stack *sw = (struct switch_stack *)regs - 1;
513	greg_t *gregs = uc->uc_mcontext.gregs;
514	int err = 0;
515
516	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
517	err |= __put_user(regs->d0, &gregs[0]);
518	err |= __put_user(regs->d1, &gregs[1]);
519	err |= __put_user(regs->d2, &gregs[2]);
520	err |= __put_user(regs->d3, &gregs[3]);
521	err |= __put_user(regs->d4, &gregs[4]);
522	err |= __put_user(regs->d5, &gregs[5]);
523	err |= __put_user(sw->d6, &gregs[6]);
524	err |= __put_user(sw->d7, &gregs[7]);
525	err |= __put_user(regs->a0, &gregs[8]);
526	err |= __put_user(regs->a1, &gregs[9]);
527	err |= __put_user(regs->a2, &gregs[10]);
528	err |= __put_user(sw->a3, &gregs[11]);
529	err |= __put_user(sw->a4, &gregs[12]);
530	err |= __put_user(sw->a5, &gregs[13]);
531	err |= __put_user(sw->a6, &gregs[14]);
532	err |= __put_user(rdusp(), &gregs[15]);
533	err |= __put_user(regs->pc, &gregs[16]);
534	err |= __put_user(regs->sr, &gregs[17]);
535#ifdef CONFIG_FPU
536	err |= rt_save_fpu_state(uc, regs);
537#endif
538	return err;
539}
540
541static inline void push_cache (unsigned long vaddr)
542{
543}
544
545static inline void *
546get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
547{
548	unsigned long usp;
549
550	/* Default to using normal stack.  */
551	usp = rdusp();
552
553	/* This is the X/Open sanctioned signal stack switching.  */
554	if (ka->sa.sa_flags & SA_ONSTACK) {
555		if (!sas_ss_flags(usp))
556			usp = current->sas_ss_sp + current->sas_ss_size;
557	}
558	return (void *)((usp - frame_size) & -8UL);
559}
560
561static void setup_frame (int sig, struct k_sigaction *ka,
562			 sigset_t *set, struct pt_regs *regs)
563{
564	struct sigframe *frame;
565	struct sigcontext context;
566	int err = 0;
567
568	frame = get_sigframe(ka, regs, sizeof(*frame));
569
570	err |= __put_user((current_thread_info()->exec_domain
571			   && current_thread_info()->exec_domain->signal_invmap
572			   && sig < 32
573			   ? current_thread_info()->exec_domain->signal_invmap[sig]
574			   : sig),
575			  &frame->sig);
576
577	err |= __put_user(regs->vector, &frame->code);
578	err |= __put_user(&frame->sc, &frame->psc);
579
580	if (_NSIG_WORDS > 1)
581		err |= copy_to_user(frame->extramask, &set->sig[1],
582				    sizeof(frame->extramask));
583
584	setup_sigcontext(&context, regs, set->sig[0]);
585	err |= copy_to_user (&frame->sc, &context, sizeof(context));
586
587	/* Set up to return from userspace.  */
588	err |= __put_user(frame->retcode, &frame->pretcode);
589	/* moveq #,d0; trap #0 */
590	err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
591			  (long *)(frame->retcode));
592
593	if (err)
594		goto give_sigsegv;
595
596	push_cache ((unsigned long) &frame->retcode);
597
598	/* Set up registers for signal handler */
599	wrusp ((unsigned long) frame);
600	regs->pc = (unsigned long) ka->sa.sa_handler;
601	((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
602	regs->format = 0x4; /*set format byte to make stack appear modulo 4
603						which it will be when doing the rte */
604
605adjust_stack:
606	/* Prepare to skip over the extra stuff in the exception frame.  */
607	if (regs->stkadj) {
608		struct pt_regs *tregs =
609			(struct pt_regs *)((ulong)regs + regs->stkadj);
610#if defined(DEBUG)
611		printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
612#endif
613		/* This must be copied with decreasing addresses to
614                   handle overlaps.  */
615		tregs->vector = 0;
616		tregs->format = 0;
617		tregs->pc = regs->pc;
618		tregs->sr = regs->sr;
619	}
620	return;
621
622give_sigsegv:
623	force_sigsegv(sig, current);
624	goto adjust_stack;
625}
626
627static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
628			    sigset_t *set, struct pt_regs *regs)
629{
630	struct rt_sigframe *frame;
631	int err = 0;
632
633	frame = get_sigframe(ka, regs, sizeof(*frame));
634
635	err |= __put_user((current_thread_info()->exec_domain
636			   && current_thread_info()->exec_domain->signal_invmap
637			   && sig < 32
638			   ? current_thread_info()->exec_domain->signal_invmap[sig]
639			   : sig),
640			  &frame->sig);
641	err |= __put_user(&frame->info, &frame->pinfo);
642	err |= __put_user(&frame->uc, &frame->puc);
643	err |= copy_siginfo_to_user(&frame->info, info);
644
645	/* Create the ucontext.  */
646	err |= __put_user(0, &frame->uc.uc_flags);
647	err |= __put_user(0, &frame->uc.uc_link);
648	err |= __put_user((void *)current->sas_ss_sp,
649			  &frame->uc.uc_stack.ss_sp);
650	err |= __put_user(sas_ss_flags(rdusp()),
651			  &frame->uc.uc_stack.ss_flags);
652	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
653	err |= rt_setup_ucontext(&frame->uc, regs);
654	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
655
656	/* Set up to return from userspace.  */
657	err |= __put_user(frame->retcode, &frame->pretcode);
658	/* moveq #,d0; notb d0; trap #0 */
659	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
660			  (long *)(frame->retcode + 0));
661	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
662
663	if (err)
664		goto give_sigsegv;
665
666	push_cache ((unsigned long) &frame->retcode);
667
668	/* Set up registers for signal handler */
669	wrusp ((unsigned long) frame);
670	regs->pc = (unsigned long) ka->sa.sa_handler;
671	((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
672	regs->format = 0x4; /*set format byte to make stack appear modulo 4
673						which it will be when doing the rte */
674
675adjust_stack:
676	/* Prepare to skip over the extra stuff in the exception frame.  */
677	if (regs->stkadj) {
678		struct pt_regs *tregs =
679			(struct pt_regs *)((ulong)regs + regs->stkadj);
680#if defined(DEBUG)
681		printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
682#endif
683		/* This must be copied with decreasing addresses to
684                   handle overlaps.  */
685		tregs->vector = 0;
686		tregs->format = 0;
687		tregs->pc = regs->pc;
688		tregs->sr = regs->sr;
689	}
690	return;
691
692give_sigsegv:
693	force_sigsegv(sig, current);
694	goto adjust_stack;
695}
696
697static inline void
698handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
699{
700	switch (regs->d0) {
701	case -ERESTARTNOHAND:
702		if (!has_handler)
703			goto do_restart;
704		regs->d0 = -EINTR;
705		break;
706
707	case -ERESTARTSYS:
708		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
709			regs->d0 = -EINTR;
710			break;
711		}
712	/* fallthrough */
713	case -ERESTARTNOINTR:
714	do_restart:
715		regs->d0 = regs->orig_d0;
716		regs->pc -= 2;
717		break;
718	}
719}
720
721/*
722 * OK, we're invoking a handler
723 */
724static void
725handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
726	      sigset_t *oldset, struct pt_regs *regs)
727{
728	/* are we from a system call? */
729	if (regs->orig_d0 >= 0)
730		/* If so, check system call restarting.. */
731		handle_restart(regs, ka, 1);
732
733	/* set up the stack frame */
734	if (ka->sa.sa_flags & SA_SIGINFO)
735		setup_rt_frame(sig, ka, info, oldset, regs);
736	else
737		setup_frame(sig, ka, oldset, regs);
738
739	if (ka->sa.sa_flags & SA_ONESHOT)
740		ka->sa.sa_handler = SIG_DFL;
741
742	spin_lock_irq(&current->sighand->siglock);
743	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
744	if (!(ka->sa.sa_flags & SA_NODEFER))
745		sigaddset(&current->blocked,sig);
746	recalc_sigpending();
747	spin_unlock_irq(&current->sighand->siglock);
748}
749
750/*
751 * Note that 'init' is a special process: it doesn't get signals it doesn't
752 * want to handle. Thus you cannot kill init even with a SIGKILL even by
753 * mistake.
754 */
755asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
756{
757	struct k_sigaction ka;
758	siginfo_t info;
759	int signr;
760
761	/*
762	 * We want the common case to go fast, which
763	 * is why we may in certain cases get here from
764	 * kernel mode. Just return without doing anything
765	 * if so.
766	 */
767	if (!user_mode(regs))
768		return 1;
769
770	if (!oldset)
771		oldset = &current->blocked;
772
773	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
774	if (signr > 0) {
775		/* Whee!  Actually deliver the signal.  */
776		handle_signal(signr, &ka, &info, oldset, regs);
777		return 1;
778	}
779
780	/* Did we come from a system call? */
781	if (regs->orig_d0 >= 0) {
782		/* Restart the system call - no handlers present */
783		if (regs->d0 == -ERESTARTNOHAND
784		    || regs->d0 == -ERESTARTSYS
785		    || regs->d0 == -ERESTARTNOINTR) {
786			regs->d0 = regs->orig_d0;
787			regs->pc -= 2;
788		} else if (regs->d0 == -ERESTART_RESTARTBLOCK) {
789			regs->d0 = __NR_restart_syscall;
790			regs->pc -= 2;
791		}
792	}
793	return 0;
794}
795