signal.h 6.5 KB

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