2 * linux/arch/m68k/kernel/signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
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
12 * Derived from m68k/kernel/signal.c and the original authors are credited
15 * Coldfire support by:
16 * Matt Waddel Matt.Waddel@freescale.com
17 * Copyright Freescale Semiconductor, Inc 2007
20 #include <linux/sched.h>
22 #include <linux/kernel.h>
23 #include <linux/signal.h>
24 #include <linux/syscalls.h>
25 #include <linux/errno.h>
26 #include <linux/wait.h>
27 #include <linux/ptrace.h>
28 #include <linux/unistd.h>
29 #include <linux/stddef.h>
30 #include <linux/highuid.h>
31 #include <linux/personality.h>
32 #include <linux/tty.h>
33 #include <linux/binfmts.h>
35 #include <asm/setup.h>
36 #include <asm/cf_uaccess.h>
37 #include <asm/cf_pgtable.h>
38 #include <asm/traps.h>
39 #include <asm/ucontext.h>
40 #include <asm/cacheflush.h>
42 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
46 const int frame_extra_sizes[16] = {
48 [2] = sizeof(((struct frame *)0)->un.fmt2),
49 [3] = sizeof(((struct frame *)0)->un.fmt3),
53 [7] = sizeof(((struct frame *)0)->un.fmt7),
55 [9] = sizeof(((struct frame *)0)->un.fmt9),
56 [10] = sizeof(((struct frame *)0)->un.fmta),
57 [11] = sizeof(((struct frame *)0)->un.fmtb),
65 * Atomically swap in the new signal mask, and wait for a signal.
67 asmlinkage int do_sigsuspend(struct pt_regs *regs)
69 old_sigset_t mask = regs->d3;
73 spin_lock_irq(¤t->sighand->siglock);
74 saveset = current->blocked;
75 siginitset(¤t->blocked, mask);
77 spin_unlock_irq(¤t->sighand->siglock);
81 current->state = TASK_INTERRUPTIBLE;
83 if (do_signal(&saveset, regs))
89 do_rt_sigsuspend(struct pt_regs *regs)
91 sigset_t __user *unewset = (sigset_t __user *)regs->d1;
92 size_t sigsetsize = (size_t)regs->d2;
93 sigset_t saveset, newset;
95 /* XXX: Don't preclude handling different sized sigset_t's. */
96 if (sigsetsize != sizeof(sigset_t))
99 if (copy_from_user(&newset, unewset, sizeof(newset)))
101 sigdelsetmask(&newset, ~_BLOCKABLE);
103 spin_lock_irq(¤t->sighand->siglock);
104 saveset = current->blocked;
105 current->blocked = newset;
107 spin_unlock_irq(¤t->sighand->siglock);
111 current->state = TASK_INTERRUPTIBLE;
113 if (do_signal(&saveset, regs))
119 sys_sigaction(int sig, const struct old_sigaction __user *act,
120 struct old_sigaction __user *oact)
122 struct k_sigaction new_ka, old_ka;
127 if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
128 __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
129 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
131 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
132 __get_user(mask, &act->sa_mask);
133 siginitset(&new_ka.sa.sa_mask, mask);
136 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
139 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
140 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
141 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
143 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
144 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
151 sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
153 return do_sigaltstack(uss, uoss, rdusp());
158 * Do a signal return; undo the signal stack.
160 * Keep the return code on the stack quadword aligned!
161 * That makes the cache flush below easier.
166 char __user *pretcode;
169 struct sigcontext __user *psc;
171 unsigned long extramask[_NSIG_WORDS-1];
172 struct sigcontext sc;
177 char __user *pretcode;
179 struct siginfo __user *pinfo;
186 #define FPCONTEXT_SIZE 216
187 #define uc_fpstate uc_filler[0]
188 #define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
189 #define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
192 static unsigned char fpu_version; /* version num of fpu, set by setup_frame */
194 static inline int restore_fpu_state(struct sigcontext *sc)
199 /* restore registers */
200 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
201 memcpy(current->thread.fp, sc->sc_fpregs, 24);
205 if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
206 /* Verify the frame format. */
207 if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
209 if (CPU_IS_020_OR_030) {
210 if (m68k_fputype & FPU_68881 &&
211 !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
213 if (m68k_fputype & FPU_68882 &&
214 !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
216 } else if (CPU_IS_040) {
217 if (!(sc->sc_fpstate[1] == 0x00 ||
218 sc->sc_fpstate[1] == 0x28 ||
219 sc->sc_fpstate[1] == 0x60))
221 } else if (CPU_IS_060) {
222 if (!(sc->sc_fpstate[3] == 0x00 ||
223 sc->sc_fpstate[3] == 0x60 ||
224 sc->sc_fpstate[3] == 0xe0))
236 static inline int rt_restore_fpu_state(struct ucontext __user *uc)
238 unsigned char fpstate[FPCONTEXT_SIZE];
239 int context_size = CPU_IS_060 ? 8 : 0;
244 /* restore fpu control register */
245 if (__copy_from_user(current->thread.fpcntl,
246 uc->uc_mcontext.fpregs.f_fpcntl, 12))
248 /* restore all other fpu register */
249 if (__copy_from_user(current->thread.fp,
250 uc->uc_mcontext.fpregs.f_fpregs, 96))
255 if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
257 if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
259 context_size = fpstate[1];
260 /* Verify the frame format. */
261 if (!CPU_IS_060 && (fpstate[0] != fpu_version))
263 if (CPU_IS_020_OR_030) {
264 if (m68k_fputype & FPU_68881 &&
265 !(context_size == 0x18 || context_size == 0xb4))
267 if (m68k_fputype & FPU_68882 &&
268 !(context_size == 0x38 || context_size == 0xd4))
270 } else if (CPU_IS_040) {
271 if (!(context_size == 0x00 ||
272 context_size == 0x28 ||
273 context_size == 0x60))
275 } else if (CPU_IS_060) {
276 if (!(fpstate[3] == 0x00 ||
277 fpstate[3] == 0x60 ||
282 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
287 __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
298 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc,
299 void __user *fp, int *pd0)
301 int fsize, formatvec;
302 struct sigcontext context;
305 /* get previous context */
306 if (copy_from_user(&context, usc, sizeof(context)))
309 /* restore passed registers */
310 regs->d1 = context.sc_d1;
311 regs->a0 = context.sc_a0;
312 regs->a1 = context.sc_a1;
313 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
314 regs->pc = context.sc_pc;
315 regs->orig_d0 = -1; /* disable syscall checks */
316 wrusp(context.sc_usp);
317 formatvec = context.sc_formatvec;
318 regs->format = formatvec >> 12;
319 regs->vector = formatvec & 0xfff;
322 err = restore_fpu_state(&context);
325 fsize = frame_extra_sizes[regs->format];
328 * user process trying to return with weird frame format
331 printk(KERN_DEBUG "user process returning with weird \
337 /* OK. Make room on the supervisor stack for the extra junk,
342 struct switch_stack *sw = (struct switch_stack *)regs - 1;
343 regs->d0 = context.sc_d0;
344 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
346 (" movel %0,%/sp\n\t"
347 " bra ret_from_signal\n"
349 ".section __ex_table,\"a\"\n"
353 : /* no outputs, it doesn't ever return */
354 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
355 "n" (frame_offset), "a" (fp)
359 * If we ever get here an exception occurred while
360 * building the above stack-frame.
365 *pd0 = context.sc_d0;
373 rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
374 struct ucontext __user *uc, int *pd0)
377 greg_t __user *gregs = uc->uc_mcontext.gregs;
381 err = __get_user(temp, &uc->uc_mcontext.version);
382 if (temp != MCONTEXT_VERSION)
384 /* restore passed registers */
385 err |= __get_user(regs->d0, &gregs[0]);
386 err |= __get_user(regs->d1, &gregs[1]);
387 err |= __get_user(regs->d2, &gregs[2]);
388 err |= __get_user(regs->d3, &gregs[3]);
389 err |= __get_user(regs->d4, &gregs[4]);
390 err |= __get_user(regs->d5, &gregs[5]);
391 err |= __get_user(sw->d6, &gregs[6]);
392 err |= __get_user(sw->d7, &gregs[7]);
393 err |= __get_user(regs->a0, &gregs[8]);
394 err |= __get_user(regs->a1, &gregs[9]);
395 err |= __get_user(regs->a2, &gregs[10]);
396 err |= __get_user(sw->a3, &gregs[11]);
397 err |= __get_user(sw->a4, &gregs[12]);
398 err |= __get_user(sw->a5, &gregs[13]);
399 err |= __get_user(sw->a6, &gregs[14]);
400 err |= __get_user(usp, &gregs[15]);
402 err |= __get_user(regs->pc, &gregs[16]);
403 err |= __get_user(temp, &gregs[17]);
404 regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
405 regs->orig_d0 = -1; /* disable syscall checks */
406 err |= __get_user(temp, &uc->uc_formatvec);
407 regs->format = temp >> 12;
408 regs->vector = temp & 0xfff;
411 err |= rt_restore_fpu_state(uc);
414 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
417 fsize = frame_extra_sizes[regs->format];
420 * user process trying to return with weird frame format
423 printk(KERN_DEBUG "user process returning with weird \
429 /* OK. Make room on the supervisor stack for the extra junk,
434 #define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
436 (" movel %0,%/sp\n\t"
437 " bra ret_from_signal\n"
439 ".section __ex_table,\"a\"\n"
443 : /* no outputs, it doesn't ever return */
444 : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
445 "n" (frame_offset), "a" (&uc->uc_extra)
449 * If we ever get here an exception occurred while
450 * building the above stack-frame.
462 asmlinkage int do_sigreturn(unsigned long __unused)
464 struct switch_stack *sw = (struct switch_stack *) &__unused;
465 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
466 unsigned long usp = rdusp();
467 struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
471 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
473 if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
475 __copy_from_user(&set.sig[1], &frame->extramask,
476 sizeof(frame->extramask))))
479 sigdelsetmask(&set, ~_BLOCKABLE);
480 spin_lock_irq(¤t->sighand->siglock);
481 current->blocked = set;
483 spin_unlock_irq(¤t->sighand->siglock);
485 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
490 force_sig(SIGSEGV, current);
494 asmlinkage int do_rt_sigreturn(unsigned long __unused)
496 struct switch_stack *sw = (struct switch_stack *) &__unused;
497 struct pt_regs *regs = (struct pt_regs *) (sw + 1);
498 unsigned long usp = rdusp();
499 struct rt_sigframe __user *frame =
500 (struct rt_sigframe __user *)(usp - 4);
504 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
506 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
509 sigdelsetmask(&set, ~_BLOCKABLE);
510 spin_lock_irq(¤t->sighand->siglock);
511 current->blocked = set;
513 spin_unlock_irq(¤t->sighand->siglock);
515 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
520 force_sig(SIGSEGV, current);
526 * Set up a signal frame.
529 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
533 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
534 memcpy(sc->sc_fpregs, current->thread.fp, 24);
539 static inline int rt_save_fpu_state(struct ucontext __user *uc,
540 struct pt_regs *regs)
545 /* save fpu control register */
546 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
547 current->thread.fpcntl, 12);
548 /* save all other fpu register */
549 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
550 current->thread.fp, 96);
558 static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
562 sc->sc_usp = rdusp();
563 sc->sc_d0 = regs->d0;
564 sc->sc_d1 = regs->d1;
565 sc->sc_a0 = regs->a0;
566 sc->sc_a1 = regs->a1;
567 sc->sc_sr = regs->sr;
568 sc->sc_pc = regs->pc;
569 sc->sc_formatvec = regs->format << 12 | regs->vector;
571 save_fpu_state(sc, regs);
575 static inline int rt_setup_ucontext(struct ucontext __user *uc,
576 struct pt_regs *regs)
578 struct switch_stack *sw = (struct switch_stack *)regs - 1;
579 greg_t __user *gregs = uc->uc_mcontext.gregs;
582 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
583 err |= __put_user(regs->d0, &gregs[0]);
584 err |= __put_user(regs->d1, &gregs[1]);
585 err |= __put_user(regs->d2, &gregs[2]);
586 err |= __put_user(regs->d3, &gregs[3]);
587 err |= __put_user(regs->d4, &gregs[4]);
588 err |= __put_user(regs->d5, &gregs[5]);
589 err |= __put_user(sw->d6, &gregs[6]);
590 err |= __put_user(sw->d7, &gregs[7]);
591 err |= __put_user(regs->a0, &gregs[8]);
592 err |= __put_user(regs->a1, &gregs[9]);
593 err |= __put_user(regs->a2, &gregs[10]);
594 err |= __put_user(sw->a3, &gregs[11]);
595 err |= __put_user(sw->a4, &gregs[12]);
596 err |= __put_user(sw->a5, &gregs[13]);
597 err |= __put_user(sw->a6, &gregs[14]);
598 err |= __put_user(rdusp(), &gregs[15]);
599 err |= __put_user(regs->pc, &gregs[16]);
600 err |= __put_user(regs->sr, &gregs[17]);
601 err |= __put_user((regs->format << 12) | regs->vector,
604 err |= rt_save_fpu_state(uc, regs);
609 static inline void push_cache(unsigned long vaddr)
612 // JKM -- need to add into the old cpushl cache stuff
613 cf_cache_push(__pa(vaddr), 8);
617 static inline void __user *
618 get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
622 /* Default to using normal stack. */
625 /* This is the X/Open sanctioned signal stack switching. */
626 if (ka->sa.sa_flags & SA_ONSTACK) {
627 if (!sas_ss_flags(usp))
628 usp = current->sas_ss_sp + current->sas_ss_size;
630 return (void __user *)((usp - frame_size) & -8UL);
633 static void setup_frame(int sig, struct k_sigaction *ka,
634 sigset_t *set, struct pt_regs *regs)
636 struct sigframe __user *frame;
637 int fsize = frame_extra_sizes[regs->format];
638 struct sigcontext context;
643 printk(KERN_DEBUG "setup_frame: Unknown frame format %#x\n",
649 frame = get_sigframe(ka, regs, sizeof(*frame));
651 err |= __put_user((current_thread_info()->exec_domain
652 && current_thread_info()->exec_domain->signal_invmap
654 ? current_thread_info()->exec_domain->signal_invmap[sig]
658 err |= __put_user(regs->vector, &frame->code);
659 err |= __put_user(&frame->sc, &frame->psc);
662 err |= copy_to_user(frame->extramask, &set->sig[1],
663 sizeof(frame->extramask));
665 setup_sigcontext(&context, regs, set->sig[0]);
666 err |= copy_to_user(&frame->sc, &context, sizeof(context));
668 /* Set up to return from userspace. */
669 err |= __put_user(frame->retcode, &frame->pretcode);
670 /* moveq #,d0; trap #0 */
671 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
672 (long __user *)(frame->retcode));
677 push_cache((unsigned long) &frame->retcode);
679 /* Set up registers for signal handler */
680 wrusp((unsigned long) frame);
681 regs->pc = (unsigned long) ka->sa.sa_handler;
684 /* Prepare to skip over the extra stuff in the exception frame. */
686 struct pt_regs *tregs =
687 (struct pt_regs *)((ulong)regs + regs->stkadj);
689 printk(KERN_DEBUG "Performing stackadjust=%04x\n",
692 /* This must be copied with decreasing addresses to
696 tregs->pc = regs->pc;
697 tregs->sr = regs->sr;
702 force_sigsegv(sig, current);
706 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
707 sigset_t *set, struct pt_regs *regs)
709 struct rt_sigframe __user *frame;
710 int fsize = frame_extra_sizes[regs->format];
715 printk(KERN_DEBUG "setup_frame: Unknown frame format %#x\n",
721 frame = get_sigframe(ka, regs, sizeof(*frame));
724 err |= copy_to_user(&frame->uc.uc_extra, regs + 1, fsize);
725 regs->stkadj = fsize;
728 err |= __put_user((current_thread_info()->exec_domain
729 && current_thread_info()->exec_domain->signal_invmap
731 ? current_thread_info()->exec_domain->signal_invmap[sig]
734 err |= __put_user(&frame->info, &frame->pinfo);
735 err |= __put_user(&frame->uc, &frame->puc);
736 err |= copy_siginfo_to_user(&frame->info, info);
738 /* Create the ucontext. */
739 err |= __put_user(0, &frame->uc.uc_flags);
740 err |= __put_user(NULL, &frame->uc.uc_link);
741 err |= __put_user((void __user *)current->sas_ss_sp,
742 &frame->uc.uc_stack.ss_sp);
743 err |= __put_user(sas_ss_flags(rdusp()),
744 &frame->uc.uc_stack.ss_flags);
745 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
746 err |= rt_setup_ucontext(&frame->uc, regs);
747 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
749 /* Set up to return from userspace. */
750 err |= __put_user(frame->retcode, &frame->pretcode);
752 /* moveq #,d0; andi.l #,D0; trap #0 */
753 err |= __put_user(0x70AD0280, (long *)(frame->retcode + 0));
754 err |= __put_user(0x000000ff, (long *)(frame->retcode + 4));
755 err |= __put_user(0x4e400000, (long *)(frame->retcode + 8));
760 push_cache((unsigned long) &frame->retcode);
762 /* Set up registers for signal handler */
763 wrusp((unsigned long) frame);
764 regs->pc = (unsigned long) ka->sa.sa_handler;
767 /* Prepare to skip over the extra stuff in the exception frame. */
769 struct pt_regs *tregs =
770 (struct pt_regs *)((ulong)regs + regs->stkadj);
772 printk(KERN_DEBUG "Performing stackadjust=%04x\n",
775 /* This must be copied with decreasing addresses to
779 tregs->pc = regs->pc;
780 tregs->sr = regs->sr;
785 force_sigsegv(sig, current);
790 handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
793 case -ERESTARTNOHAND:
800 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
805 case -ERESTARTNOINTR:
807 regs->d0 = regs->orig_d0;
814 * OK, we're invoking a handler
817 handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
818 sigset_t *oldset, struct pt_regs *regs)
820 /* are we from a system call? */
821 if (regs->orig_d0 >= 0)
822 /* If so, check system call restarting.. */
823 handle_restart(regs, ka, 1);
825 /* set up the stack frame */
826 if (ka->sa.sa_flags & SA_SIGINFO)
827 setup_rt_frame(sig, ka, info, oldset, regs);
829 setup_frame(sig, ka, oldset, regs);
831 if (ka->sa.sa_flags & SA_ONESHOT)
832 ka->sa.sa_handler = SIG_DFL;
834 spin_lock_irq(¤t->sighand->siglock);
835 sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
836 if (!(ka->sa.sa_flags & SA_NODEFER))
837 sigaddset(¤t->blocked, sig);
839 spin_unlock_irq(¤t->sighand->siglock);
843 * Note that 'init' is a special process: it doesn't get signals it doesn't
844 * want to handle. Thus you cannot kill init even with a SIGKILL even by
847 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
850 struct k_sigaction ka;
853 current->thread.esp0 = (unsigned long) regs;
856 oldset = ¤t->blocked;
858 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
860 /* Whee! Actually deliver the signal. */
861 handle_signal(signr, &ka, &info, oldset, regs);
865 /* Did we come from a system call? */
866 if (regs->orig_d0 >= 0)
867 /* Restart the system call - no handlers present */
868 handle_restart(regs, NULL, 0);