]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/arm64/kvm/hyp-init.S
arm64: hyp-stub/KVM: Kill __hyp_get_vectors
[karo-tx-linux.git] / arch / arm64 / kvm / hyp-init.S
index 6b29d3d9e1f285c0f1e61c3509cfbaf99402ea86..3734e6315cd7aef6f135d67c7abd5586a73d683e 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/kvm_mmu.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/sysreg.h>
+#include <asm/virt.h>
 
        .text
        .pushsection    .hyp.idmap.text, "ax"
@@ -58,6 +59,9 @@ __invalid:
         * x2: HYP vectors
         */
 __do_hyp_init:
+       /* Check for a stub HVC call */
+       cmp     x0, #HVC_STUB_HCALL_NR
+       b.lo    __kvm_handle_stub_hvc
 
        msr     ttbr0_el2, x0
 
@@ -119,23 +123,45 @@ __do_hyp_init:
        eret
 ENDPROC(__kvm_hyp_init)
 
+ENTRY(__kvm_handle_stub_hvc)
+       cmp     x0, #HVC_SOFT_RESTART
+       b.ne    1f
+
+       /* This is where we're about to jump, staying at EL2 */
+       msr     elr_el2, x1
+       mov     x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL2h)
+       msr     spsr_el2, x0
+
+       /* Shuffle the arguments, and don't come back */
+       mov     x0, x2
+       mov     x1, x3
+       mov     x2, x4
+       b       reset
+
+1:     cmp     x0, #HVC_RESET_VECTORS
+       b.ne    1f
+reset:
        /*
-        * Reset kvm back to the hyp stub.
+        * Reset kvm back to the hyp stub. Do not clobber x0-x4 in
+        * case we coming via HVC_SOFT_RESTART.
         */
-ENTRY(__kvm_hyp_reset)
-       /* We're now in idmap, disable MMU */
-       mrs     x0, sctlr_el2
-       ldr     x1, =SCTLR_ELx_FLAGS
-       bic     x0, x0, x1              // Clear SCTL_M and etc
-       msr     sctlr_el2, x0
+       mrs     x5, sctlr_el2
+       ldr     x6, =SCTLR_ELx_FLAGS
+       bic     x5, x5, x6              // Clear SCTL_M and etc
+       msr     sctlr_el2, x5
        isb
 
        /* Install stub vectors */
-       adr_l   x0, __hyp_stub_vectors
-       msr     vbar_el2, x0
+       adr_l   x5, __hyp_stub_vectors
+       msr     vbar_el2, x5
+       b       exit
+
+1:     /* Bad stub call */
+       ldr     x0, =HVC_STUB_ERR
 
+exit:
        eret
-ENDPROC(__kvm_hyp_reset)
+ENDPROC(__kvm_handle_stub_hvc)
 
        .ltorg