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