hyp-entry.S 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (C) 2015 - ARM Ltd
  3. * Author: Marc Zyngier <marc.zyngier@arm.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <linux/linkage.h>
  18. #include <asm/alternative.h>
  19. #include <asm/assembler.h>
  20. #include <asm/cpufeature.h>
  21. #include <asm/kvm_arm.h>
  22. #include <asm/kvm_asm.h>
  23. #include <asm/kvm_mmu.h>
  24. .text
  25. .pushsection .hyp.text, "ax"
  26. .macro do_el2_call
  27. /*
  28. * Shuffle the parameters before calling the function
  29. * pointed to in x0. Assumes parameters in x[1,2,3].
  30. */
  31. mov lr, x0
  32. mov x0, x1
  33. mov x1, x2
  34. mov x2, x3
  35. blr lr
  36. .endm
  37. ENTRY(__vhe_hyp_call)
  38. str lr, [sp, #-16]!
  39. do_el2_call
  40. ldr lr, [sp], #16
  41. /*
  42. * We used to rely on having an exception return to get
  43. * an implicit isb. In the E2H case, we don't have it anymore.
  44. * rather than changing all the leaf functions, just do it here
  45. * before returning to the rest of the kernel.
  46. */
  47. isb
  48. ret
  49. ENDPROC(__vhe_hyp_call)
  50. /*
  51. * Compute the idmap address of __kvm_hyp_reset based on the idmap
  52. * start passed as a parameter, and jump there.
  53. *
  54. * x0: HYP phys_idmap_start
  55. */
  56. ENTRY(__kvm_hyp_teardown)
  57. mov x4, x0
  58. adr_l x3, __kvm_hyp_reset
  59. /* insert __kvm_hyp_reset()s offset into phys_idmap_start */
  60. bfi x4, x3, #0, #PAGE_SHIFT
  61. br x4
  62. ENDPROC(__kvm_hyp_teardown)
  63. el1_sync: // Guest trapped into EL2
  64. stp x0, x1, [sp, #-16]!
  65. alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
  66. mrs x1, esr_el2
  67. alternative_else
  68. mrs x1, esr_el1
  69. alternative_endif
  70. lsr x0, x1, #ESR_ELx_EC_SHIFT
  71. cmp x0, #ESR_ELx_EC_HVC64
  72. b.ne el1_trap
  73. mrs x1, vttbr_el2 // If vttbr is valid, the 64bit guest
  74. cbnz x1, el1_trap // called HVC
  75. /* Here, we're pretty sure the host called HVC. */
  76. ldp x0, x1, [sp], #16
  77. cmp x0, #HVC_GET_VECTORS
  78. b.ne 1f
  79. mrs x0, vbar_el2
  80. b 2f
  81. 1:
  82. /*
  83. * Perform the EL2 call
  84. */
  85. kern_hyp_va x0
  86. do_el2_call
  87. 2: eret
  88. el1_trap:
  89. /*
  90. * x0: ESR_EC
  91. */
  92. /*
  93. * We trap the first access to the FP/SIMD to save the host context
  94. * and restore the guest context lazily.
  95. * If FP/SIMD is not implemented, handle the trap and inject an
  96. * undefined instruction exception to the guest.
  97. */
  98. alternative_if_not ARM64_HAS_NO_FPSIMD
  99. cmp x0, #ESR_ELx_EC_FP_ASIMD
  100. b.eq __fpsimd_guest_restore
  101. alternative_else_nop_endif
  102. mrs x1, tpidr_el2
  103. mov x0, #ARM_EXCEPTION_TRAP
  104. b __guest_exit
  105. el1_irq:
  106. stp x0, x1, [sp, #-16]!
  107. mrs x1, tpidr_el2
  108. mov x0, #ARM_EXCEPTION_IRQ
  109. b __guest_exit
  110. el1_error:
  111. stp x0, x1, [sp, #-16]!
  112. mrs x1, tpidr_el2
  113. mov x0, #ARM_EXCEPTION_EL1_SERROR
  114. b __guest_exit
  115. el2_error:
  116. /*
  117. * Only two possibilities:
  118. * 1) Either we come from the exit path, having just unmasked
  119. * PSTATE.A: change the return code to an EL2 fault, and
  120. * carry on, as we're already in a sane state to handle it.
  121. * 2) Or we come from anywhere else, and that's a bug: we panic.
  122. *
  123. * For (1), x0 contains the original return code and x1 doesn't
  124. * contain anything meaningful at that stage. We can reuse them
  125. * as temp registers.
  126. * For (2), who cares?
  127. */
  128. mrs x0, elr_el2
  129. adr x1, abort_guest_exit_start
  130. cmp x0, x1
  131. adr x1, abort_guest_exit_end
  132. ccmp x0, x1, #4, ne
  133. b.ne __hyp_panic
  134. mov x0, #(1 << ARM_EXIT_WITH_SERROR_BIT)
  135. eret
  136. ENTRY(__hyp_do_panic)
  137. mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
  138. PSR_MODE_EL1h)
  139. msr spsr_el2, lr
  140. ldr lr, =panic
  141. msr elr_el2, lr
  142. eret
  143. ENDPROC(__hyp_do_panic)
  144. .macro invalid_vector label, target = __hyp_panic
  145. .align 2
  146. \label:
  147. b \target
  148. ENDPROC(\label)
  149. .endm
  150. /* None of these should ever happen */
  151. invalid_vector el2t_sync_invalid
  152. invalid_vector el2t_irq_invalid
  153. invalid_vector el2t_fiq_invalid
  154. invalid_vector el2t_error_invalid
  155. invalid_vector el2h_sync_invalid
  156. invalid_vector el2h_irq_invalid
  157. invalid_vector el2h_fiq_invalid
  158. invalid_vector el1_sync_invalid
  159. invalid_vector el1_irq_invalid
  160. invalid_vector el1_fiq_invalid
  161. .ltorg
  162. .align 11
  163. ENTRY(__kvm_hyp_vector)
  164. ventry el2t_sync_invalid // Synchronous EL2t
  165. ventry el2t_irq_invalid // IRQ EL2t
  166. ventry el2t_fiq_invalid // FIQ EL2t
  167. ventry el2t_error_invalid // Error EL2t
  168. ventry el2h_sync_invalid // Synchronous EL2h
  169. ventry el2h_irq_invalid // IRQ EL2h
  170. ventry el2h_fiq_invalid // FIQ EL2h
  171. ventry el2_error // Error EL2h
  172. ventry el1_sync // Synchronous 64-bit EL1
  173. ventry el1_irq // IRQ 64-bit EL1
  174. ventry el1_fiq_invalid // FIQ 64-bit EL1
  175. ventry el1_error // Error 64-bit EL1
  176. ventry el1_sync // Synchronous 32-bit EL1
  177. ventry el1_irq // IRQ 32-bit EL1
  178. ventry el1_fiq_invalid // FIQ 32-bit EL1
  179. ventry el1_error // Error 32-bit EL1
  180. ENDPROC(__kvm_hyp_vector)