signal-common.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 1991, 1992 Linus Torvalds
  7. * Copyright (C) 1994 - 2000 Ralf Baechle
  8. * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9. */
  10. static inline int
  11. setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
  12. {
  13. int err = 0;
  14. err |= __put_user(regs->cp0_epc, &sc->sc_pc);
  15. err |= __put_user(regs->cp0_status, &sc->sc_status);
  16. #define save_gp_reg(i) do { \
  17. err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
  18. } while(0)
  19. __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
  20. save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
  21. save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
  22. save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
  23. save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
  24. save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
  25. save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
  26. save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
  27. save_gp_reg(31);
  28. #undef save_gp_reg
  29. err |= __put_user(regs->hi, &sc->sc_mdhi);
  30. err |= __put_user(regs->lo, &sc->sc_mdlo);
  31. err |= __put_user(regs->cp0_cause, &sc->sc_cause);
  32. err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
  33. err |= __put_user(!!used_math(), &sc->sc_used_math);
  34. if (!used_math())
  35. goto out;
  36. /*
  37. * Save FPU state to signal context. Signal handler will "inherit"
  38. * current FPU state.
  39. */
  40. preempt_disable();
  41. if (!is_fpu_owner()) {
  42. own_fpu();
  43. restore_fp(current);
  44. }
  45. err |= save_fp_context(sc);
  46. preempt_enable();
  47. out:
  48. return err;
  49. }
  50. static inline int
  51. restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
  52. {
  53. int err = 0;
  54. unsigned int used_math;
  55. /* Always make any pending restarted system calls return -EINTR */
  56. current_thread_info()->restart_block.fn = do_no_restart_syscall;
  57. err |= __get_user(regs->cp0_epc, &sc->sc_pc);
  58. err |= __get_user(regs->hi, &sc->sc_mdhi);
  59. err |= __get_user(regs->lo, &sc->sc_mdlo);
  60. #define restore_gp_reg(i) do { \
  61. err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
  62. } while(0)
  63. restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
  64. restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
  65. restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
  66. restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
  67. restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
  68. restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
  69. restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
  70. restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
  71. restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
  72. restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
  73. restore_gp_reg(31);
  74. #undef restore_gp_reg
  75. err |= __get_user(used_math, &sc->sc_used_math);
  76. conditional_used_math(used_math);
  77. preempt_disable();
  78. if (used_math()) {
  79. /* restore fpu context if we have used it before */
  80. own_fpu();
  81. err |= restore_fp_context(sc);
  82. } else {
  83. /* signal handler may have used FPU. Give it up. */
  84. lose_fpu();
  85. }
  86. preempt_enable();
  87. return err;
  88. }
  89. /*
  90. * Determine which stack to use..
  91. */
  92. static inline void *
  93. get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
  94. {
  95. unsigned long sp, almask;
  96. /* Default to using normal stack */
  97. sp = regs->regs[29];
  98. /*
  99. * FPU emulator may have it's own trampoline active just
  100. * above the user stack, 16-bytes before the next lowest
  101. * 16 byte boundary. Try to avoid trashing it.
  102. */
  103. sp -= 32;
  104. /* This is the X/Open sanctioned signal stack switching. */
  105. if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
  106. sp = current->sas_ss_sp + current->sas_ss_size;
  107. if (PLAT_TRAMPOLINE_STUFF_LINE)
  108. almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
  109. else
  110. almask = ALMASK;
  111. return (void *)((sp - frame_size) & almask);
  112. }