File: /usr/src/linux/arch/m68k/kernel/signal.c

1     /*
2      *  linux/arch/m68k/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 completly 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/errno.h>
36     #include <linux/wait.h>
37     #include <linux/ptrace.h>
38     #include <linux/unistd.h>
39     #include <linux/stddef.h>
40     #include <linux/highuid.h>
41     
42     #include <asm/setup.h>
43     #include <asm/uaccess.h>
44     #include <asm/pgtable.h>
45     #include <asm/traps.h>
46     #include <asm/ucontext.h>
47     
48     #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
49     
50     asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
51     
52     const int frame_extra_sizes[16] = {
53       0,
54       -1, /* sizeof(((struct frame *)0)->un.fmt1), */
55       sizeof(((struct frame *)0)->un.fmt2),
56       sizeof(((struct frame *)0)->un.fmt3),
57       sizeof(((struct frame *)0)->un.fmt4),
58       -1, /* sizeof(((struct frame *)0)->un.fmt5), */
59       -1, /* sizeof(((struct frame *)0)->un.fmt6), */
60       sizeof(((struct frame *)0)->un.fmt7),
61       -1, /* sizeof(((struct frame *)0)->un.fmt8), */
62       sizeof(((struct frame *)0)->un.fmt9),
63       sizeof(((struct frame *)0)->un.fmta),
64       sizeof(((struct frame *)0)->un.fmtb),
65       -1, /* sizeof(((struct frame *)0)->un.fmtc), */
66       -1, /* sizeof(((struct frame *)0)->un.fmtd), */
67       -1, /* sizeof(((struct frame *)0)->un.fmte), */
68       -1, /* sizeof(((struct frame *)0)->un.fmtf), */
69     };
70     
71     /*
72      * Atomically swap in the new signal mask, and wait for a signal.
73      */
74     asmlinkage int do_sigsuspend(struct pt_regs *regs)
75     {
76     	old_sigset_t mask = regs->d3;
77     	sigset_t saveset;
78     
79     	mask &= _BLOCKABLE;
80     	saveset = current->blocked;
81     	siginitset(&current->blocked, mask);
82     	recalc_sigpending(current);
83     
84     	regs->d0 = -EINTR;
85     	while (1) {
86     		current->state = TASK_INTERRUPTIBLE;
87     		schedule();
88     		if (do_signal(&saveset, regs))
89     			return -EINTR;
90     	}
91     }
92     
93     asmlinkage int
94     do_rt_sigsuspend(struct pt_regs *regs)
95     {
96     	sigset_t *unewset = (sigset_t *)regs->d1;
97     	size_t sigsetsize = (size_t)regs->d2;
98     	sigset_t saveset, newset;
99     
100     	/* XXX: Don't preclude handling different sized sigset_t's.  */
101     	if (sigsetsize != sizeof(sigset_t))
102     		return -EINVAL;
103     
104     	if (copy_from_user(&newset, unewset, sizeof(newset)))
105     		return -EFAULT;
106     	sigdelsetmask(&newset, ~_BLOCKABLE);
107     
108     	saveset = current->blocked;
109     	current->blocked = newset;
110     	recalc_sigpending(current);
111     
112     	regs->d0 = -EINTR;
113     	while (1) {
114     		current->state = TASK_INTERRUPTIBLE;
115     		schedule();
116     		if (do_signal(&saveset, regs))
117     			return -EINTR;
118     	}
119     }
120     
121     asmlinkage int 
122     sys_sigaction(int sig, const struct old_sigaction *act,
123     	      struct old_sigaction *oact)
124     {
125     	struct k_sigaction new_ka, old_ka;
126     	int ret;
127     
128     	if (act) {
129     		old_sigset_t mask;
130     		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
131     		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
132     		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
133     			return -EFAULT;
134     		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
135     		__get_user(mask, &act->sa_mask);
136     		siginitset(&new_ka.sa.sa_mask, mask);
137     	}
138     
139     	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
140     
141     	if (!ret && oact) {
142     		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
143     		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
144     		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
145     			return -EFAULT;
146     		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
147     		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
148     	}
149     
150     	return ret;
151     }
152     
153     asmlinkage int
154     sys_sigaltstack(const stack_t *uss, stack_t *uoss)
155     {
156     	return do_sigaltstack(uss, uoss, rdusp());
157     }
158     
159     
160     /*
161      * Do a signal return; undo the signal stack.
162      *
163      * Keep the return code on the stack quadword aligned!
164      * That makes the cache flush below easier.
165      */
166     
167     struct sigframe
168     {
169     	char *pretcode;
170     	int sig;
171     	int code;
172     	struct sigcontext *psc;
173     	char retcode[8];
174     	unsigned long extramask[_NSIG_WORDS-1];
175     	struct sigcontext sc;
176     };
177     
178     struct rt_sigframe
179     {
180     	char *pretcode;
181     	int sig;
182     	struct siginfo *pinfo;
183     	void *puc;
184     	char retcode[8];
185     	struct siginfo info;
186     	struct ucontext uc;
187     };
188     
189     
190     int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from)
191     {
192     	if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
193     		return -EFAULT;
194     	if (from->si_code < 0)
195     		return __copy_to_user(to, from, sizeof(siginfo_t));
196     	else {
197     		int err;
198     
199     		/* If you change siginfo_t structure, please be sure
200     		   this code is fixed accordingly.
201     		   It should never copy any pad contained in the structure
202     		   to avoid security leaks, but must copy the generic
203     		   3 ints plus the relevant union member.  */
204     		err = __put_user(from->si_signo, &to->si_signo);
205     		err |= __put_user(from->si_errno, &to->si_errno);
206     		err |= __put_user((short)from->si_code, &to->si_code);
207     		/* First 32bits of unions are always present.  */
208     		err |= __put_user(from->si_pid, &to->si_pid);
209     		switch (from->si_code >> 16) {
210     		case __SI_FAULT >> 16:
211     			break;
212     		case __SI_CHLD >> 16:
213     			err |= __put_user(from->si_utime, &to->si_utime);
214     			err |= __put_user(from->si_stime, &to->si_stime);
215     			err |= __put_user(from->si_status, &to->si_status);
216     		default:
217     			err |= __put_user(from->si_uid, &to->si_uid);
218     			break;
219     		/* case __SI_RT: This is not generated by the kernel as of now.  */
220     		}
221     		return err;
222     	}
223     }
224     
225     static unsigned char fpu_version = 0;	/* version number of fpu, set by setup_frame */
226     
227     static inline int restore_fpu_state(struct sigcontext *sc)
228     {
229     	int err = 1;
230     
231     	if (FPU_IS_EMU) {
232     	    /* restore registers */
233     	    memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
234     	    memcpy(current->thread.fp, sc->sc_fpregs, 24);
235     	    return 0;
236     	}
237     
238     	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
239     	    /* Verify the frame format.  */
240     	    if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
241     		goto out;
242     	    if (CPU_IS_020_OR_030) {
243     		if (m68k_fputype & FPU_68881 &&
244     		    !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
245     		    goto out;
246     		if (m68k_fputype & FPU_68882 &&
247     		    !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
248     		    goto out;
249     	    } else if (CPU_IS_040) {
250     		if (!(sc->sc_fpstate[1] == 0x00 ||
251                           sc->sc_fpstate[1] == 0x28 ||
252                           sc->sc_fpstate[1] == 0x60))
253     		    goto out;
254     	    } else if (CPU_IS_060) {
255     		if (!(sc->sc_fpstate[3] == 0x00 ||
256                           sc->sc_fpstate[3] == 0x60 ||
257     		      sc->sc_fpstate[3] == 0xe0))
258     		    goto out;
259     	    } else
260     		goto out;
261     
262     	    __asm__ volatile (".chip 68k/68881\n\t"
263     			      "fmovemx %0,%/fp0-%/fp1\n\t"
264     			      "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
265     			      ".chip 68k"
266     			      : /* no outputs */
267     			      : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
268     	}
269     	__asm__ volatile (".chip 68k/68881\n\t"
270     			  "frestore %0\n\t"
271     			  ".chip 68k" : : "m" (*sc->sc_fpstate));
272     	err = 0;
273     
274     out:
275     	return err;
276     }
277     
278     #define FPCONTEXT_SIZE	216
279     #define uc_fpstate	uc_filler[0]
280     #define uc_formatvec	uc_filler[FPCONTEXT_SIZE/4]
281     #define uc_extra	uc_filler[FPCONTEXT_SIZE/4+1]
282     
283     static inline int rt_restore_fpu_state(struct ucontext *uc)
284     {
285     	unsigned char fpstate[FPCONTEXT_SIZE];
286     	int context_size = CPU_IS_060 ? 8 : 0;
287     	fpregset_t fpregs;
288     	int err = 1;
289     
290     	if (FPU_IS_EMU) {
291     		/* restore fpu control register */
292     		if (__copy_from_user(current->thread.fpcntl,
293     				&uc->uc_mcontext.fpregs.f_pcr, 12))
294     			goto out;
295     		/* restore all other fpu register */
296     		if (__copy_from_user(current->thread.fp,
297     				uc->uc_mcontext.fpregs.f_fpregs, 96))
298     			goto out;
299     		return 0;
300     	}
301     
302     	if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate))
303     		goto out;
304     	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
305     		if (!CPU_IS_060)
306     			context_size = fpstate[1];
307     		/* Verify the frame format.  */
308     		if (!CPU_IS_060 && (fpstate[0] != fpu_version))
309     			goto out;
310     		if (CPU_IS_020_OR_030) {
311     			if (m68k_fputype & FPU_68881 &&
312     			    !(context_size == 0x18 || context_size == 0xb4))
313     				goto out;
314     			if (m68k_fputype & FPU_68882 &&
315     			    !(context_size == 0x38 || context_size == 0xd4))
316     				goto out;
317     		} else if (CPU_IS_040) {
318     			if (!(context_size == 0x00 ||
319     			      context_size == 0x28 ||
320     			      context_size == 0x60))
321     				goto out;
322     		} else if (CPU_IS_060) {
323     			if (!(fpstate[3] == 0x00 ||
324     			      fpstate[3] == 0x60 ||
325     			      fpstate[3] == 0xe0))
326     				goto out;
327     		} else
328     			goto out;
329     		if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
330     				     sizeof(fpregs)))
331     			goto out;
332     		__asm__ volatile (".chip 68k/68881\n\t"
333     				  "fmovemx %0,%/fp0-%/fp7\n\t"
334     				  "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t"
335     				  ".chip 68k"
336     				  : /* no outputs */
337     				  : "m" (*fpregs.f_fpregs),
338     				    "m" (fpregs.f_pcr));
339     	}
340     	if (context_size &&
341     	    __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1,
342     			     context_size))
343     		goto out;
344     	__asm__ volatile (".chip 68k/68881\n\t"
345     			  "frestore %0\n\t"
346     			  ".chip 68k" : : "m" (*fpstate));
347     	err = 0;
348     
349     out:
350     	return err;
351     }
352     
353     static inline int
354     restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp,
355     		   int *pd0)
356     {
357     	int fsize, formatvec;
358     	struct sigcontext context;
359     	int err;
360     
361     	/* get previous context */
362     	if (copy_from_user(&context, usc, sizeof(context)))
363     		goto badframe;
364     	
365     	/* restore passed registers */
366     	regs->d1 = context.sc_d1;
367     	regs->a0 = context.sc_a0;
368     	regs->a1 = context.sc_a1;
369     	regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
370     	regs->pc = context.sc_pc;
371     	regs->orig_d0 = -1;		/* disable syscall checks */
372     	wrusp(context.sc_usp);
373     	formatvec = context.sc_formatvec;
374     	regs->format = formatvec >> 12;
375     	regs->vector = formatvec & 0xfff;
376     
377     	err = restore_fpu_state(&context);
378     
379     	fsize = frame_extra_sizes[regs->format];
380     	if (fsize < 0) {
381     		/*
382     		 * user process trying to return with weird frame format
383     		 */
384     #if DEBUG
385     		printk("user process returning with weird frame format\n");
386     #endif
387     		goto badframe;
388     	}
389     
390     	/* OK.	Make room on the supervisor stack for the extra junk,
391     	 * if necessary.
392     	 */
393     
394     	if (fsize) {
395     		struct switch_stack *sw = (struct switch_stack *)regs - 1;
396     		regs->d0 = context.sc_d0;
397     #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
398     		__asm__ __volatile__
399     			("   movel %0,%/a0\n\t"
400     			 "   subl %1,%/a0\n\t"     /* make room on stack */
401     			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
402     			 /* move switch_stack and pt_regs */
403     			 "1: movel %0@+,%/a0@+\n\t"
404     			 "   dbra %2,1b\n\t"
405     			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
406     			 "   lsrl  #2,%1\n\t"
407     			 "   subql #1,%1\n\t"
408     			 "2: movesl %4@+,%2\n\t"
409     			 "3: movel %2,%/a0@+\n\t"
410     			 "   dbra %1,2b\n\t"
411     			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
412     			 "4:\n"
413     			 ".section __ex_table,\"a\"\n"
414     			 "   .align 4\n"
415     			 "   .long 2b,4b\n"
416     			 "   .long 3b,4b\n"
417     			 ".previous"
418     			 : /* no outputs, it doesn't ever return */
419     			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
420     			   "n" (frame_offset), "a" (fp)
421     			 : "a0");
422     #undef frame_offset
423     		/*
424     		 * If we ever get here an exception occurred while
425     		 * building the above stack-frame.
426     		 */
427     		goto badframe;
428     	}
429     
430     	*pd0 = context.sc_d0;
431     	return err;
432     
433     badframe:
434     	return 1;
435     }
436     
437     static inline int
438     rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
439     		    struct ucontext *uc, int *pd0)
440     {
441     	int fsize, temp;
442     	greg_t *gregs = uc->uc_mcontext.gregs;
443     	unsigned long usp;
444     	int err;
445     
446     	err = __get_user(temp, &uc->uc_mcontext.version);
447     	if (temp != MCONTEXT_VERSION)
448     		goto badframe;
449     	/* restore passed registers */
450     	err |= __get_user(regs->d0, &gregs[0]);
451     	err |= __get_user(regs->d1, &gregs[1]);
452     	err |= __get_user(regs->d2, &gregs[2]);
453     	err |= __get_user(regs->d3, &gregs[3]);
454     	err |= __get_user(regs->d4, &gregs[4]);
455     	err |= __get_user(regs->d5, &gregs[5]);
456     	err |= __get_user(sw->d6, &gregs[6]);
457     	err |= __get_user(sw->d7, &gregs[7]);
458     	err |= __get_user(regs->a0, &gregs[8]);
459     	err |= __get_user(regs->a1, &gregs[9]);
460     	err |= __get_user(regs->a2, &gregs[10]);
461     	err |= __get_user(sw->a3, &gregs[11]);
462     	err |= __get_user(sw->a4, &gregs[12]);
463     	err |= __get_user(sw->a5, &gregs[13]);
464     	err |= __get_user(sw->a6, &gregs[14]);
465     	err |= __get_user(usp, &gregs[15]);
466     	wrusp(usp);
467     	err |= __get_user(regs->pc, &gregs[16]);
468     	err |= __get_user(temp, &gregs[17]);
469     	regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
470     	regs->orig_d0 = -1;		/* disable syscall checks */
471     	err |= __get_user(temp, &uc->uc_formatvec);
472     	regs->format = temp >> 12;
473     	regs->vector = temp & 0xfff;
474     
475     	err |= rt_restore_fpu_state(uc);
476     
477     	if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
478     		goto badframe;
479     
480     	fsize = frame_extra_sizes[regs->format];
481     	if (fsize < 0) {
482     		/*
483     		 * user process trying to return with weird frame format
484     		 */
485     #if DEBUG
486     		printk("user process returning with weird frame format\n");
487     #endif
488     		goto badframe;
489     	}
490     
491     	/* OK.	Make room on the supervisor stack for the extra junk,
492     	 * if necessary.
493     	 */
494     
495     	if (fsize) {
496     #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
497     		__asm__ __volatile__
498     			("   movel %0,%/a0\n\t"
499     			 "   subl %1,%/a0\n\t"     /* make room on stack */
500     			 "   movel %/a0,%/sp\n\t"  /* set stack pointer */
501     			 /* move switch_stack and pt_regs */
502     			 "1: movel %0@+,%/a0@+\n\t"
503     			 "   dbra %2,1b\n\t"
504     			 "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
505     			 "   lsrl  #2,%1\n\t"
506     			 "   subql #1,%1\n\t"
507     			 "2: movesl %4@+,%2\n\t"
508     			 "3: movel %2,%/a0@+\n\t"
509     			 "   dbra %1,2b\n\t"
510     			 "   bral " SYMBOL_NAME_STR(ret_from_signal) "\n"
511     			 "4:\n"
512     			 ".section __ex_table,\"a\"\n"
513     			 "   .align 4\n"
514     			 "   .long 2b,4b\n"
515     			 "   .long 3b,4b\n"
516     			 ".previous"
517     			 : /* no outputs, it doesn't ever return */
518     			 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
519     			   "n" (frame_offset), "a" (&uc->uc_extra)
520     			 : "a0");
521     #undef frame_offset
522     		/*
523     		 * If we ever get here an exception occurred while
524     		 * building the above stack-frame.
525     		 */
526     		goto badframe;
527     	}
528     
529     	*pd0 = regs->d0;
530     	return err;
531     
532     badframe:
533     	return 1;
534     }
535     
536     asmlinkage int do_sigreturn(unsigned long __unused)
537     {
538     	struct switch_stack *sw = (struct switch_stack *) &__unused;
539     	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
540     	unsigned long usp = rdusp();
541     	struct sigframe *frame = (struct sigframe *)(usp - 4);
542     	sigset_t set;
543     	int d0;
544     
545     	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
546     		goto badframe;
547     	if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
548     	    (_NSIG_WORDS > 1 &&
549     	     __copy_from_user(&set.sig[1], &frame->extramask,
550     			      sizeof(frame->extramask))))
551     		goto badframe;
552     
553     	sigdelsetmask(&set, ~_BLOCKABLE);
554     	current->blocked = set;
555     	recalc_sigpending(current);
556     	
557     	if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
558     		goto badframe;
559     	return d0;
560     
561     badframe:
562     	force_sig(SIGSEGV, current);
563     	return 0;
564     }
565     
566     asmlinkage int do_rt_sigreturn(unsigned long __unused)
567     {
568     	struct switch_stack *sw = (struct switch_stack *) &__unused;
569     	struct pt_regs *regs = (struct pt_regs *) (sw + 1);
570     	unsigned long usp = rdusp();
571     	struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4);
572     	sigset_t set;
573     	int d0;
574     
575     	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
576     		goto badframe;
577     	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
578     		goto badframe;
579     
580     	sigdelsetmask(&set, ~_BLOCKABLE);
581     	current->blocked = set;
582     	recalc_sigpending(current);
583     	
584     	if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
585     		goto badframe;
586     	return d0;
587     
588     badframe:
589     	force_sig(SIGSEGV, current);
590     	return 0;
591     }
592     
593     /*
594      * Set up a signal frame.
595      */
596     
597     static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
598     {
599     	if (FPU_IS_EMU) {
600     		/* save registers */
601     		memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
602     		memcpy(sc->sc_fpregs, current->thread.fp, 24);
603     		return;
604     	}
605     
606     	__asm__ volatile (".chip 68k/68881\n\t"
607     			  "fsave %0\n\t"
608     			  ".chip 68k"
609     			  : : "m" (*sc->sc_fpstate) : "memory");
610     
611     	if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
612     		fpu_version = sc->sc_fpstate[0];
613     		if (CPU_IS_020_OR_030 &&
614     		    regs->vector >= (VEC_FPBRUC * 4) &&
615     		    regs->vector <= (VEC_FPNAN * 4)) {
616     			/* Clear pending exception in 68882 idle frame */
617     			if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
618     				sc->sc_fpstate[0x38] |= 1 << 3;
619     		}
620     		__asm__ volatile (".chip 68k/68881\n\t"
621     				  "fmovemx %/fp0-%/fp1,%0\n\t"
622     				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
623     				  ".chip 68k"
624     				  : /* no outputs */
625     				  : "m" (*sc->sc_fpregs),
626     				    "m" (*sc->sc_fpcntl)
627     				  : "memory");
628     	}
629     }
630     
631     static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs)
632     {
633     	unsigned char fpstate[FPCONTEXT_SIZE];
634     	int context_size = CPU_IS_060 ? 8 : 0;
635     	int err = 0;
636     
637     	if (FPU_IS_EMU) {
638     		/* save fpu control register */
639     		err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr,
640     				current->thread.fpcntl, 12);
641     		/* save all other fpu register */
642     		err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
643     				current->thread.fp, 96);
644     		return err;
645     	}
646     
647     	__asm__ volatile (".chip 68k/68881\n\t"
648     			  "fsave %0\n\t"
649     			  ".chip 68k"
650     			  : : "m" (*fpstate) : "memory");
651     
652     	err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate);
653     	if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
654     		fpregset_t fpregs;
655     		if (!CPU_IS_060)
656     			context_size = fpstate[1];
657     		fpu_version = fpstate[0];
658     		if (CPU_IS_020_OR_030 &&
659     		    regs->vector >= (VEC_FPBRUC * 4) &&
660     		    regs->vector <= (VEC_FPNAN * 4)) {
661     			/* Clear pending exception in 68882 idle frame */
662     			if (*(unsigned short *) fpstate == 0x1f38)
663     				fpstate[0x38] |= 1 << 3;
664     		}
665     		__asm__ volatile (".chip 68k/68881\n\t"
666     				  "fmovemx %/fp0-%/fp7,%0\n\t"
667     				  "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t"
668     				  ".chip 68k"
669     				  : /* no outputs */
670     				  : "m" (*fpregs.f_fpregs),
671     				    "m" (fpregs.f_pcr)
672     				  : "memory");
673     		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
674     				    sizeof(fpregs));
675     	}
676     	if (context_size)
677     		err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4,
678     				    context_size);
679     	return err;
680     }
681     
682     static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
683     			     unsigned long mask)
684     {
685     	sc->sc_mask = mask;
686     	sc->sc_usp = rdusp();
687     	sc->sc_d0 = regs->d0;
688     	sc->sc_d1 = regs->d1;
689     	sc->sc_a0 = regs->a0;
690     	sc->sc_a1 = regs->a1;
691     	sc->sc_sr = regs->sr;
692     	sc->sc_pc = regs->pc;
693     	sc->sc_formatvec = regs->format << 12 | regs->vector;
694     	save_fpu_state(sc, regs);
695     }
696     
697     static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
698     {
699     	struct switch_stack *sw = (struct switch_stack *)regs - 1;
700     	greg_t *gregs = uc->uc_mcontext.gregs;
701     	int err = 0;
702     
703     	err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
704     	err |= __put_user(regs->d0, &gregs[0]);
705     	err |= __put_user(regs->d1, &gregs[1]);
706     	err |= __put_user(regs->d2, &gregs[2]);
707     	err |= __put_user(regs->d3, &gregs[3]);
708     	err |= __put_user(regs->d4, &gregs[4]);
709     	err |= __put_user(regs->d5, &gregs[5]);
710     	err |= __put_user(sw->d6, &gregs[6]);
711     	err |= __put_user(sw->d7, &gregs[7]);
712     	err |= __put_user(regs->a0, &gregs[8]);
713     	err |= __put_user(regs->a1, &gregs[9]);
714     	err |= __put_user(regs->a2, &gregs[10]);
715     	err |= __put_user(sw->a3, &gregs[11]);
716     	err |= __put_user(sw->a4, &gregs[12]);
717     	err |= __put_user(sw->a5, &gregs[13]);
718     	err |= __put_user(sw->a6, &gregs[14]);
719     	err |= __put_user(rdusp(), &gregs[15]);
720     	err |= __put_user(regs->pc, &gregs[16]);
721     	err |= __put_user(regs->sr, &gregs[17]);
722     	err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
723     	err |= rt_save_fpu_state(uc, regs);
724     	return err;
725     }
726     
727     static inline void push_cache (unsigned long vaddr)
728     {
729     	/*
730     	 * Using the old cache_push_v() was really a big waste.
731     	 *
732     	 * What we are trying to do is to flush 8 bytes to ram.
733     	 * Flushing 2 cache lines of 16 bytes is much cheaper than
734     	 * flushing 1 or 2 pages, as previously done in
735     	 * cache_push_v().
736     	 *                                                     Jes
737     	 */
738     	if (CPU_IS_040) {
739     		unsigned long temp;
740     
741     		__asm__ __volatile__ (".chip 68040\n\t"
742     				      "nop\n\t"
743     				      "ptestr (%1)\n\t"
744     				      "movec %%mmusr,%0\n\t"
745     				      ".chip 68k"
746     				      : "=r" (temp)
747     				      : "a" (vaddr));
748     
749     		temp &= PAGE_MASK;
750     		temp |= vaddr & ~PAGE_MASK;
751     
752     		__asm__ __volatile__ (".chip 68040\n\t"
753     				      "nop\n\t"
754     				      "cpushl %%bc,(%0)\n\t"
755     				      ".chip 68k"
756     				      : : "a" (temp));
757     	}
758     	else if (CPU_IS_060) {
759     		unsigned long temp;
760     		__asm__ __volatile__ (".chip 68060\n\t"
761     				      "plpar (%0)\n\t"
762     				      ".chip 68k"
763     				      : "=a" (temp)
764     				      : "0" (vaddr));
765     		__asm__ __volatile__ (".chip 68060\n\t"
766     				      "cpushl %%bc,(%0)\n\t"
767     				      ".chip 68k"
768     				      : : "a" (temp));
769     	}
770     	else {
771     		/*
772     		 * 68030/68020 have no writeback cache;
773     		 * still need to clear icache.
774     		 * Note that vaddr is guaranteed to be long word aligned.
775     		 */
776     		unsigned long temp;
777     		asm volatile ("movec %%cacr,%0" : "=r" (temp));
778     		temp += 4;
779     		asm volatile ("movec %0,%%caar\n\t"
780     			      "movec %1,%%cacr"
781     			      : : "r" (vaddr), "r" (temp));
782     		asm volatile ("movec %0,%%caar\n\t"
783     			      "movec %1,%%cacr"
784     			      : : "r" (vaddr + 4), "r" (temp));
785     	}
786     }
787     
788     static inline void *
789     get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
790     {
791     	unsigned long usp;
792     
793     	/* Default to using normal stack.  */
794     	usp = rdusp();
795     
796     	/* This is the X/Open sanctioned signal stack switching.  */
797     	if (ka->sa.sa_flags & SA_ONSTACK) {
798     		if (!on_sig_stack(usp))
799     			usp = current->sas_ss_sp + current->sas_ss_size;
800     	}
801     	return (void *)((usp - frame_size) & -8UL);
802     }
803     
804     static void setup_frame (int sig, struct k_sigaction *ka,
805     			 sigset_t *set, struct pt_regs *regs)
806     {
807     	struct sigframe *frame;
808     	int fsize = frame_extra_sizes[regs->format];
809     	struct sigcontext context;
810     	int err = 0;
811     
812     	if (fsize < 0) {
813     #ifdef DEBUG
814     		printk ("setup_frame: Unknown frame format %#x\n",
815     			regs->format);
816     #endif
817     		goto give_sigsegv;
818     	}
819     
820     	frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
821     
822     	if (fsize) {
823     		err |= copy_to_user (frame + 1, regs + 1, fsize);
824     		regs->stkadj = fsize;
825     	}
826     
827     	err |= __put_user((current->exec_domain
828     			   && current->exec_domain->signal_invmap
829     			   && sig < 32
830     			   ? current->exec_domain->signal_invmap[sig]
831     			   : sig),
832     			  &frame->sig);
833     
834     	err |= __put_user(regs->vector, &frame->code);
835     	err |= __put_user(&frame->sc, &frame->psc);
836     
837     	if (_NSIG_WORDS > 1)
838     		err |= copy_to_user(frame->extramask, &set->sig[1],
839     				    sizeof(frame->extramask));
840     
841     	setup_sigcontext(&context, regs, set->sig[0]);
842     	err |= copy_to_user (&frame->sc, &context, sizeof(context));
843     
844     	/* Set up to return from userspace.  */
845     	err |= __put_user(frame->retcode, &frame->pretcode);
846     	/* moveq #,d0; trap #0 */
847     	err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
848     			  (long *)(frame->retcode));
849     
850     	if (err)
851     		goto give_sigsegv;
852     
853     	push_cache ((unsigned long) &frame->retcode);
854     
855     	/* Set up registers for signal handler */
856     	wrusp ((unsigned long) frame);
857     	regs->pc = (unsigned long) ka->sa.sa_handler;
858     
859     adjust_stack:
860     	/* Prepare to skip over the extra stuff in the exception frame.  */
861     	if (regs->stkadj) {
862     		struct pt_regs *tregs =
863     			(struct pt_regs *)((ulong)regs + regs->stkadj);
864     #if DEBUG
865     		printk("Performing stackadjust=%04x\n", regs->stkadj);
866     #endif
867     		/* This must be copied with decreasing addresses to
868                        handle overlaps.  */
869     		tregs->vector = 0;
870     		tregs->format = 0;
871     		tregs->pc = regs->pc;
872     		tregs->sr = regs->sr;
873     	}
874     	return;
875     
876     give_sigsegv:
877     	if (sig == SIGSEGV)
878     		ka->sa.sa_handler = SIG_DFL;
879     	force_sig(SIGSEGV, current);
880     	goto adjust_stack;
881     }
882     
883     static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
884     			    sigset_t *set, struct pt_regs *regs)
885     {
886     	struct rt_sigframe *frame;
887     	int fsize = frame_extra_sizes[regs->format];
888     	int err = 0;
889     
890     	if (fsize < 0) {
891     #ifdef DEBUG
892     		printk ("setup_frame: Unknown frame format %#x\n",
893     			regs->format);
894     #endif
895     		goto give_sigsegv;
896     	}
897     
898     	frame = get_sigframe(ka, regs, sizeof(*frame));
899     
900     	if (fsize) {
901     		err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
902     		regs->stkadj = fsize;
903     	}
904     
905     	err |= __put_user((current->exec_domain
906     			   && current->exec_domain->signal_invmap
907     			   && sig < 32
908     			   ? current->exec_domain->signal_invmap[sig]
909     			   : sig),
910     			  &frame->sig);
911     	err |= __put_user(&frame->info, &frame->pinfo);
912     	err |= __put_user(&frame->uc, &frame->puc);
913     	err |= copy_siginfo_to_user(&frame->info, info);
914     
915     	/* Create the ucontext.  */
916     	err |= __put_user(0, &frame->uc.uc_flags);
917     	err |= __put_user(0, &frame->uc.uc_link);
918     	err |= __put_user((void *)current->sas_ss_sp,
919     			  &frame->uc.uc_stack.ss_sp);
920     	err |= __put_user(sas_ss_flags(rdusp()),
921     			  &frame->uc.uc_stack.ss_flags);
922     	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
923     	err |= rt_setup_ucontext(&frame->uc, regs);
924     	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
925     
926     	/* Set up to return from userspace.  */
927     	err |= __put_user(frame->retcode, &frame->pretcode);
928     	/* moveq #,d0; notb d0; trap #0 */
929     	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
930     			  (long *)(frame->retcode + 0));
931     	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
932     
933     	if (err)
934     		goto give_sigsegv;
935     
936     	push_cache ((unsigned long) &frame->retcode);
937     
938     	/* Set up registers for signal handler */
939     	wrusp ((unsigned long) frame);
940     	regs->pc = (unsigned long) ka->sa.sa_handler;
941     
942     adjust_stack:
943     	/* Prepare to skip over the extra stuff in the exception frame.  */
944     	if (regs->stkadj) {
945     		struct pt_regs *tregs =
946     			(struct pt_regs *)((ulong)regs + regs->stkadj);
947     #if DEBUG
948     		printk("Performing stackadjust=%04x\n", regs->stkadj);
949     #endif
950     		/* This must be copied with decreasing addresses to
951                        handle overlaps.  */
952     		tregs->vector = 0;
953     		tregs->format = 0;
954     		tregs->pc = regs->pc;
955     		tregs->sr = regs->sr;
956     	}
957     	return;
958     
959     give_sigsegv:
960     	if (sig == SIGSEGV)
961     		ka->sa.sa_handler = SIG_DFL;
962     	force_sig(SIGSEGV, current);
963     	goto adjust_stack;
964     }
965     
966     static inline void
967     handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
968     {
969     	switch (regs->d0) {
970     	case -ERESTARTNOHAND:
971     		if (!has_handler)
972     			goto do_restart;
973     		regs->d0 = -EINTR;
974     		break;
975     
976     	case -ERESTARTSYS:
977     		if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
978     			regs->d0 = -EINTR;
979     			break;
980     		}
981     	/* fallthrough */
982     	case -ERESTARTNOINTR:
983     	do_restart:
984     		regs->d0 = regs->orig_d0;
985     		regs->pc -= 2;
986     		break;
987     	}
988     }
989     
990     /*
991      * OK, we're invoking a handler
992      */
993     static void
994     handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
995     	      sigset_t *oldset, struct pt_regs *regs)
996     {
997     	/* are we from a system call? */
998     	if (regs->orig_d0 >= 0)
999     		/* If so, check system call restarting.. */
1000     		handle_restart(regs, ka, 1);
1001     
1002     	/* set up the stack frame */
1003     	if (ka->sa.sa_flags & SA_SIGINFO)
1004     		setup_rt_frame(sig, ka, info, oldset, regs);
1005     	else
1006     		setup_frame(sig, ka, oldset, regs);
1007     
1008     	if (ka->sa.sa_flags & SA_ONESHOT)
1009     		ka->sa.sa_handler = SIG_DFL;
1010     
1011     	sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1012     	if (!(ka->sa.sa_flags & SA_NODEFER))
1013     		sigaddset(&current->blocked,sig);
1014     	recalc_sigpending(current);
1015     }
1016     
1017     /*
1018      * Note that 'init' is a special process: it doesn't get signals it doesn't
1019      * want to handle. Thus you cannot kill init even with a SIGKILL even by
1020      * mistake.
1021      *
1022      * Note that we go through the signals twice: once to check the signals
1023      * that the kernel can handle, and then we build all the user-level signal
1024      * handling stack-frames in one go after that.
1025      */
1026     asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
1027     {
1028     	siginfo_t info;
1029     	struct k_sigaction *ka;
1030     
1031     	current->thread.esp0 = (unsigned long) regs;
1032     
1033     	if (!oldset)
1034     		oldset = &current->blocked;
1035     
1036     	for (;;) {
1037     		int signr;
1038     
1039     		signr = dequeue_signal(&current->blocked, &info);
1040     
1041     		if (!signr)
1042     			break;
1043     
1044     		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
1045     			current->exit_code = signr;
1046     			current->state = TASK_STOPPED;
1047     			regs->sr &= ~PS_T;
1048     
1049     			/* Did we come from a system call? */
1050     			if (regs->orig_d0 >= 0) {
1051     				/* Restart the system call the same way as
1052     				   if the process were not traced.  */
1053     				struct k_sigaction *ka =
1054     					&current->sig->action[signr-1];
1055     				int has_handler =
1056     					(ka->sa.sa_handler != SIG_IGN &&
1057     					 ka->sa.sa_handler != SIG_DFL);
1058     				handle_restart(regs, ka, has_handler);
1059     			}
1060     			notify_parent(current, SIGCHLD);
1061     			schedule();
1062     
1063     			/* We're back.  Did the debugger cancel the sig?  */
1064     			if (!(signr = current->exit_code)) {
1065     			discard_frame:
1066     			    /* Make sure that a faulted bus cycle isn't
1067     			       restarted (only needed on the 680[23]0).  */
1068     			    if (regs->format == 10 || regs->format == 11)
1069     				regs->stkadj = frame_extra_sizes[regs->format];
1070     			    continue;
1071     			}
1072     			current->exit_code = 0;
1073     
1074     			/* The debugger continued.  Ignore SIGSTOP.  */
1075     			if (signr == SIGSTOP)
1076     				goto discard_frame;
1077     
1078     			/* Update the siginfo structure.  Is this good?  */
1079     			if (signr != info.si_signo) {
1080     				info.si_signo = signr;
1081     				info.si_errno = 0;
1082     				info.si_code = SI_USER;
1083     				info.si_pid = current->p_pptr->pid;
1084     				info.si_uid = current->p_pptr->uid;
1085     				info.si_uid16 = high2lowuid(current->p_pptr->uid);
1086     			}
1087     
1088     			/* If the (new) signal is now blocked, requeue it.  */
1089     			if (sigismember(&current->blocked, signr)) {
1090     				send_sig_info(signr, &info, current);
1091     				continue;
1092     			}
1093     		}
1094     
1095     		ka = &current->sig->action[signr-1];
1096     		if (ka->sa.sa_handler == SIG_IGN) {
1097     			if (signr != SIGCHLD)
1098     				continue;
1099     			/* Check for SIGCHLD: it's special.  */
1100     			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
1101     				/* nothing */;
1102     			continue;
1103     		}
1104     
1105     		if (ka->sa.sa_handler == SIG_DFL) {
1106     			int exit_code = signr;
1107     
1108     			if (current->pid == 1)
1109     				continue;
1110     
1111     			switch (signr) {
1112     			case SIGCONT: case SIGCHLD:
1113     			case SIGWINCH: case SIGURG:
1114     				continue;
1115     
1116     			case SIGTSTP: case SIGTTIN: case SIGTTOU:
1117     				if (is_orphaned_pgrp(current->pgrp))
1118     					continue;
1119     				/* FALLTHRU */
1120     
1121     			case SIGSTOP:
1122     				current->state = TASK_STOPPED;
1123     				current->exit_code = signr;
1124     				if (!(current->p_pptr->sig->action[SIGCHLD-1]
1125     				      .sa.sa_flags & SA_NOCLDSTOP))
1126     					notify_parent(current, SIGCHLD);
1127     				schedule();
1128     				continue;
1129     
1130     			case SIGQUIT: case SIGILL: case SIGTRAP:
1131     			case SIGIOT: case SIGFPE: case SIGSEGV:
1132     			case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
1133     				if (do_coredump(signr, regs))
1134     					exit_code |= 0x80;
1135     				/* FALLTHRU */
1136     
1137     			default:
1138     				sigaddset(&current->pending.signal, signr);
1139     				recalc_sigpending(current);
1140     				current->flags |= PF_SIGNALED;
1141     				do_exit(exit_code);
1142     				/* NOTREACHED */
1143     			}
1144     		}
1145     
1146     		/* Whee!  Actually deliver the signal.  */
1147     		handle_signal(signr, ka, &info, oldset, regs);
1148     		return 1;
1149     	}
1150     
1151     	/* Did we come from a system call? */
1152     	if (regs->orig_d0 >= 0)
1153     		/* Restart the system call - no handlers present */
1154     		handle_restart(regs, NULL, 0);
1155     
1156     	/* If we are about to discard some frame stuff we must copy
1157     	   over the remaining frame. */
1158     	if (regs->stkadj) {
1159     		struct pt_regs *tregs =
1160     		  (struct pt_regs *) ((ulong) regs + regs->stkadj);
1161     
1162     		/* This must be copied with decreasing addresses to
1163     		   handle overlaps.  */
1164     		tregs->vector = 0;
1165     		tregs->format = 0;
1166     		tregs->pc = regs->pc;
1167     		tregs->sr = regs->sr;
1168     	}
1169     	return 0;
1170     }
1171