head_32.h 4.6 KB

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