signal.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
  3. * Extracted from signal_32.c and signal_64.c
  4. *
  5. * This file is subject to the terms and conditions of the GNU General
  6. * Public License. See the file README.legal in the main directory of
  7. * this archive for more details.
  8. */
  9. #ifndef _POWERPC_ARCH_SIGNAL_H
  10. #define _POWERPC_ARCH_SIGNAL_H
  11. void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
  12. size_t frame_size, int is_32);
  13. extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
  14. struct task_struct *tsk);
  15. extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
  16. struct task_struct *tsk);
  17. static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)
  18. {
  19. BUILD_BUG_ON(sizeof(sigset_t) != sizeof(u64));
  20. return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
  21. }
  22. #define unsafe_get_user_sigset(dst, src, label) do { \
  23. sigset_t *__dst = dst; \
  24. const sigset_t __user *__src = src; \
  25. int i; \
  26. \
  27. for (i = 0; i < _NSIG_WORDS; i++) \
  28. unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \
  29. } while (0)
  30. #ifdef CONFIG_VSX
  31. extern unsigned long copy_vsx_to_user(void __user *to,
  32. struct task_struct *task);
  33. extern unsigned long copy_ckvsx_to_user(void __user *to,
  34. struct task_struct *task);
  35. extern unsigned long copy_vsx_from_user(struct task_struct *task,
  36. void __user *from);
  37. extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
  38. void __user *from);
  39. unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
  40. unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
  41. unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
  42. unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
  43. #define unsafe_copy_fpr_to_user(to, task, label) do { \
  44. struct task_struct *__t = task; \
  45. u64 __user *buf = (u64 __user *)to; \
  46. int i; \
  47. \
  48. for (i = 0; i < ELF_NFPREG - 1 ; i++) \
  49. unsafe_put_user(__t->thread.TS_FPR(i), &buf[i], label); \
  50. unsafe_put_user(__t->thread.fp_state.fpscr, &buf[i], label); \
  51. } while (0)
  52. #define unsafe_copy_vsx_to_user(to, task, label) do { \
  53. struct task_struct *__t = task; \
  54. u64 __user *buf = (u64 __user *)to; \
  55. int i; \
  56. \
  57. for (i = 0; i < ELF_NVSRHALFREG ; i++) \
  58. unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
  59. &buf[i], label);\
  60. } while (0)
  61. #define unsafe_copy_fpr_from_user(task, from, label) do { \
  62. struct task_struct *__t = task; \
  63. u64 __user *buf = (u64 __user *)from; \
  64. int i; \
  65. \
  66. for (i = 0; i < ELF_NFPREG - 1; i++) \
  67. unsafe_get_user(__t->thread.TS_FPR(i), &buf[i], label); \
  68. unsafe_get_user(__t->thread.fp_state.fpscr, &buf[i], label); \
  69. } while (0)
  70. #define unsafe_copy_vsx_from_user(task, from, label) do { \
  71. struct task_struct *__t = task; \
  72. u64 __user *buf = (u64 __user *)from; \
  73. int i; \
  74. \
  75. for (i = 0; i < ELF_NVSRHALFREG ; i++) \
  76. unsafe_get_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
  77. &buf[i], label); \
  78. } while (0)
  79. #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
  80. #define unsafe_copy_ckfpr_to_user(to, task, label) do { \
  81. struct task_struct *__t = task; \
  82. u64 __user *buf = (u64 __user *)to; \
  83. int i; \
  84. \
  85. for (i = 0; i < ELF_NFPREG - 1 ; i++) \
  86. unsafe_put_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
  87. unsafe_put_user(__t->thread.ckfp_state.fpscr, &buf[i], label); \
  88. } while (0)
  89. #define unsafe_copy_ckvsx_to_user(to, task, label) do { \
  90. struct task_struct *__t = task; \
  91. u64 __user *buf = (u64 __user *)to; \
  92. int i; \
  93. \
  94. for (i = 0; i < ELF_NVSRHALFREG ; i++) \
  95. unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
  96. &buf[i], label);\
  97. } while (0)
  98. #define unsafe_copy_ckfpr_from_user(task, from, label) do { \
  99. struct task_struct *__t = task; \
  100. u64 __user *buf = (u64 __user *)from; \
  101. int i; \
  102. \
  103. for (i = 0; i < ELF_NFPREG - 1 ; i++) \
  104. unsafe_get_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
  105. unsafe_get_user(__t->thread.ckfp_state.fpscr, &buf[i], failed); \
  106. } while (0)
  107. #define unsafe_copy_ckvsx_from_user(task, from, label) do { \
  108. struct task_struct *__t = task; \
  109. u64 __user *buf = (u64 __user *)from; \
  110. int i; \
  111. \
  112. for (i = 0; i < ELF_NVSRHALFREG ; i++) \
  113. unsafe_get_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
  114. &buf[i], label); \
  115. } while (0)
  116. #endif
  117. #elif defined(CONFIG_PPC_FPU_REGS)
  118. #define unsafe_copy_fpr_to_user(to, task, label) \
  119. unsafe_copy_to_user(to, (task)->thread.fp_state.fpr, \
  120. ELF_NFPREG * sizeof(double), label)
  121. #define unsafe_copy_fpr_from_user(task, from, label) \
  122. unsafe_copy_from_user((task)->thread.fp_state.fpr, from, \
  123. ELF_NFPREG * sizeof(double), label)
  124. static inline unsigned long
  125. copy_fpr_to_user(void __user *to, struct task_struct *task)
  126. {
  127. return __copy_to_user(to, task->thread.fp_state.fpr,
  128. ELF_NFPREG * sizeof(double));
  129. }
  130. static inline unsigned long
  131. copy_fpr_from_user(struct task_struct *task, void __user *from)
  132. {
  133. return __copy_from_user(task->thread.fp_state.fpr, from,
  134. ELF_NFPREG * sizeof(double));
  135. }
  136. #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
  137. #define unsafe_copy_ckfpr_to_user(to, task, label) \
  138. unsafe_copy_to_user(to, (task)->thread.ckfp_state.fpr, \
  139. ELF_NFPREG * sizeof(double), label)
  140. inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
  141. {
  142. return __copy_to_user(to, task->thread.ckfp_state.fpr,
  143. ELF_NFPREG * sizeof(double));
  144. }
  145. static inline unsigned long
  146. copy_ckfpr_from_user(struct task_struct *task, void __user *from)
  147. {
  148. return __copy_from_user(task->thread.ckfp_state.fpr, from,
  149. ELF_NFPREG * sizeof(double));
  150. }
  151. #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
  152. #else
  153. #define unsafe_copy_fpr_to_user(to, task, label) do { if (0) goto label;} while (0)
  154. #define unsafe_copy_fpr_from_user(task, from, label) do { if (0) goto label;} while (0)
  155. static inline unsigned long
  156. copy_fpr_to_user(void __user *to, struct task_struct *task)
  157. {
  158. return 0;
  159. }
  160. static inline unsigned long
  161. copy_fpr_from_user(struct task_struct *task, void __user *from)
  162. {
  163. return 0;
  164. }
  165. #endif
  166. #ifdef CONFIG_PPC64
  167. extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
  168. struct task_struct *tsk);
  169. #else /* CONFIG_PPC64 */
  170. static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
  171. struct task_struct *tsk)
  172. {
  173. return -EFAULT;
  174. }
  175. #endif /* !defined(CONFIG_PPC64) */
  176. void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
  177. const char *where, void __user *ptr);
  178. #endif /* _POWERPC_ARCH_SIGNAL_H */