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(¤t->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(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);
1013 if (!(ka->sa.sa_flags & SA_NODEFER))
1014 sigaddset(¤t->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 = ¤t->blocked;
1036
1037 for (;;) {
1038 int signr;
1039
1040 signr = dequeue_signal(¤t->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 ¤t->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(¤t->blocked, signr)) {
1091 send_sig_info(signr, &info, current);
1092 continue;
1093 }
1094 }
1095
1096 ka = ¤t->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