head_32.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __HEAD_32_H__
  3. #define __HEAD_32_H__
  4. #include <asm/ptrace.h> /* for STACK_FRAME_REGS_MARKER */
  5. /*
  6. * Exception entry code. This code runs with address translation
  7. * turned off, i.e. using physical addresses.
  8. * We assume sprg3 has the physical address of the current
  9. * task's thread_struct.
  10. */
  11. .macro EXCEPTION_PROLOG trapno name handle_dar_dsisr=0
  12. EXCEPTION_PROLOG_0 handle_dar_dsisr=\handle_dar_dsisr
  13. EXCEPTION_PROLOG_1
  14. EXCEPTION_PROLOG_2 \trapno \name handle_dar_dsisr=\handle_dar_dsisr
  15. .endm
  16. .macro EXCEPTION_PROLOG_0 handle_dar_dsisr=0
  17. mtspr SPRN_SPRG_SCRATCH0,r10
  18. mtspr SPRN_SPRG_SCRATCH1,r11
  19. mfspr r10, SPRN_SPRG_THREAD
  20. .if \handle_dar_dsisr
  21. #ifdef CONFIG_40x
  22. mfspr r11, SPRN_DEAR
  23. #else
  24. mfspr r11, SPRN_DAR
  25. #endif
  26. stw r11, DAR(r10)
  27. #ifdef CONFIG_40x
  28. mfspr r11, SPRN_ESR
  29. #else
  30. mfspr r11, SPRN_DSISR
  31. #endif
  32. stw r11, DSISR(r10)
  33. .endif
  34. mfspr r11, SPRN_SRR0
  35. stw r11, SRR0(r10)
  36. mfspr r11, SPRN_SRR1 /* check whether user or kernel */
  37. stw r11, SRR1(r10)
  38. mfcr r10
  39. andi. r11, r11, MSR_PR
  40. .endm
  41. .macro EXCEPTION_PROLOG_1
  42. mtspr SPRN_SPRG_SCRATCH2,r1
  43. subi r1, r1, INT_FRAME_SIZE /* use r1 if kernel */
  44. beq 1f
  45. mfspr r1,SPRN_SPRG_THREAD
  46. lwz r1,TASK_STACK-THREAD(r1)
  47. addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
  48. 1:
  49. #ifdef CONFIG_VMAP_STACK
  50. mtcrf 0x3f, r1
  51. bt 32 - THREAD_ALIGN_SHIFT, vmap_stack_overflow
  52. #endif
  53. .endm
  54. .macro EXCEPTION_PROLOG_2 trapno name handle_dar_dsisr=0
  55. #ifdef CONFIG_PPC_8xx
  56. .if \handle_dar_dsisr
  57. li r11, RPN_PATTERN
  58. mtspr SPRN_DAR, r11 /* Tag DAR, to be used in DTLB Error */
  59. .endif
  60. #endif
  61. LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~MSR_RI) /* re-enable MMU */
  62. mtspr SPRN_SRR1, r11
  63. lis r11, 1f@h
  64. ori r11, r11, 1f@l
  65. mtspr SPRN_SRR0, r11
  66. mfspr r11, SPRN_SPRG_SCRATCH2
  67. rfi
  68. .text
  69. \name\()_virt:
  70. 1:
  71. stw r11,GPR1(r1)
  72. stw r11,0(r1)
  73. mr r11, r1
  74. stw r10,_CCR(r11) /* save registers */
  75. stw r12,GPR12(r11)
  76. stw r9,GPR9(r11)
  77. mfspr r10,SPRN_SPRG_SCRATCH0
  78. mfspr r12,SPRN_SPRG_SCRATCH1
  79. stw r10,GPR10(r11)
  80. stw r12,GPR11(r11)
  81. mflr r10
  82. stw r10,_LINK(r11)
  83. mfspr r12, SPRN_SPRG_THREAD
  84. tovirt(r12, r12)
  85. .if \handle_dar_dsisr
  86. lwz r10, DAR(r12)
  87. stw r10, _DAR(r11)
  88. lwz r10, DSISR(r12)
  89. stw r10, _DSISR(r11)
  90. .endif
  91. lwz r9, SRR1(r12)
  92. lwz r12, SRR0(r12)
  93. #ifdef CONFIG_40x
  94. rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */
  95. #elif defined(CONFIG_PPC_8xx)
  96. mtspr SPRN_EID, r2 /* Set MSR_RI */
  97. #else
  98. li r10, MSR_KERNEL /* can take exceptions */
  99. mtmsr r10 /* (except for mach check in rtas) */
  100. #endif
  101. COMMON_EXCEPTION_PROLOG_END \trapno
  102. _ASM_NOKPROBE_SYMBOL(\name\()_virt)
  103. .endm
  104. .macro COMMON_EXCEPTION_PROLOG_END trapno
  105. stw r0,GPR0(r1)
  106. lis r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
  107. addi r10,r10,STACK_FRAME_REGS_MARKER@l
  108. stw r10,8(r1)
  109. li r10, \trapno
  110. stw r10,_TRAP(r1)
  111. SAVE_GPRS(3, 8, r1)
  112. SAVE_NVGPRS(r1)
  113. stw r2,GPR2(r1)
  114. stw r12,_NIP(r1)
  115. stw r9,_MSR(r1)
  116. mfctr r10
  117. mfspr r2,SPRN_SPRG_THREAD
  118. stw r10,_CTR(r1)
  119. tovirt(r2, r2)
  120. mfspr r10,SPRN_XER
  121. addi r2, r2, -THREAD
  122. stw r10,_XER(r1)
  123. addi r3,r1,STACK_FRAME_OVERHEAD
  124. .endm
  125. .macro prepare_transfer_to_handler
  126. #ifdef CONFIG_PPC_BOOK3S_32
  127. andi. r12,r9,MSR_PR
  128. bne 777f
  129. bl prepare_transfer_to_handler
  130. #ifdef CONFIG_PPC_KUEP
  131. b 778f
  132. 777:
  133. bl __kuep_lock
  134. 778:
  135. #endif
  136. 777:
  137. #endif
  138. .endm
  139. .macro SYSCALL_ENTRY trapno
  140. mfspr r9, SPRN_SRR1
  141. mfspr r12, SPRN_SRR0
  142. LOAD_REG_IMMEDIATE(r11, MSR_KERNEL) /* can take exceptions */
  143. lis r10, 1f@h
  144. ori r10, r10, 1f@l
  145. mtspr SPRN_SRR1, r11
  146. mtspr SPRN_SRR0, r10
  147. mfspr r10,SPRN_SPRG_THREAD
  148. mr r11, r1
  149. lwz r1,TASK_STACK-THREAD(r10)
  150. tovirt(r10, r10)
  151. addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
  152. rfi
  153. 1:
  154. stw r12,_NIP(r1)
  155. mfcr r12
  156. rlwinm r12,r12,0,4,2 /* Clear SO bit in CR */
  157. stw r12,_CCR(r1)
  158. b transfer_to_syscall /* jump to handler */
  159. .endm
  160. /*
  161. * Note: code which follows this uses cr0.eq (set if from kernel),
  162. * r11, r12 (SRR0), and r9 (SRR1).
  163. *
  164. * Note2: once we have set r1 we are in a position to take exceptions
  165. * again, and we could thus set MSR:RI at that point.
  166. */
  167. /*
  168. * Exception vectors.
  169. */
  170. #ifdef CONFIG_PPC_BOOK3S
  171. #define START_EXCEPTION(n, label) \
  172. __HEAD; \
  173. . = n; \
  174. DO_KVM n; \
  175. label:
  176. #else
  177. #define START_EXCEPTION(n, label) \
  178. __HEAD; \
  179. . = n; \
  180. label:
  181. #endif
  182. #define EXCEPTION(n, label, hdlr) \
  183. START_EXCEPTION(n, label) \
  184. EXCEPTION_PROLOG n label; \
  185. prepare_transfer_to_handler; \
  186. bl hdlr; \
  187. b interrupt_return
  188. .macro vmap_stack_overflow_exception
  189. __HEAD
  190. vmap_stack_overflow:
  191. #ifdef CONFIG_SMP
  192. mfspr r1, SPRN_SPRG_THREAD
  193. lwz r1, TASK_CPU - THREAD(r1)
  194. slwi r1, r1, 3
  195. addis r1, r1, emergency_ctx-PAGE_OFFSET@ha
  196. #else
  197. lis r1, emergency_ctx-PAGE_OFFSET@ha
  198. #endif
  199. lwz r1, emergency_ctx-PAGE_OFFSET@l(r1)
  200. addi r1, r1, THREAD_SIZE - INT_FRAME_SIZE
  201. EXCEPTION_PROLOG_2 0 vmap_stack_overflow
  202. prepare_transfer_to_handler
  203. bl stack_overflow_exception
  204. b interrupt_return
  205. .endm
  206. #endif /* __HEAD_32_H__ */