signal.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:31k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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