arm64: KVM: VHE: Patch out use of HVC
authorMarc Zyngier <marc.zyngier@arm.com>
Thu, 29 Jan 2015 13:52:12 +0000 (13:52 +0000)
committerMarc Zyngier <marc.zyngier@arm.com>
Mon, 29 Feb 2016 18:34:16 +0000 (18:34 +0000)
With VHE, the host never issues an HVC instruction to get into the
KVM code, as we can simply branch there.

Use runtime code patching to simplify things a bit.

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
arch/arm64/kvm/hyp.S
arch/arm64/kvm/hyp/hyp-entry.S

index 0ccdcbb..0689a74 100644 (file)
@@ -17,7 +17,9 @@
 
 #include <linux/linkage.h>
 
+#include <asm/alternative.h>
 #include <asm/assembler.h>
+#include <asm/cpufeature.h>
 
 /*
  * u64 kvm_call_hyp(void *hypfn, ...);
  * arch/arm64/kernel/hyp_stub.S.
  */
 ENTRY(kvm_call_hyp)
+alternative_if_not ARM64_HAS_VIRT_HOST_EXTN    
        hvc     #0
        ret
+alternative_else
+       b       __vhe_hyp_call
+       nop
+alternative_endif
 ENDPROC(kvm_call_hyp)
index 93e8d98..1bdeee7 100644 (file)
        ldp     x0, x1, [sp], #16
 .endm
 
+.macro do_el2_call
+       /*
+        * Shuffle the parameters before calling the function
+        * pointed to in x0. Assumes parameters in x[1,2,3].
+        */
+       sub     sp, sp, #16
+       str     lr, [sp]
+       mov     lr, x0
+       mov     x0, x1
+       mov     x1, x2
+       mov     x2, x3
+       blr     lr
+       ldr     lr, [sp]
+       add     sp, sp, #16
+.endm
+
+ENTRY(__vhe_hyp_call)
+       do_el2_call
+       /*
+        * We used to rely on having an exception return to get
+        * an implicit isb. In the E2H case, we don't have it anymore.
+        * rather than changing all the leaf functions, just do it here
+        * before returning to the rest of the kernel.
+        */
+       isb
+       ret
+ENDPROC(__vhe_hyp_call)
+       
 el1_sync:                              // Guest trapped into EL2
        save_x0_to_x3
 
@@ -58,19 +86,13 @@ el1_sync:                           // Guest trapped into EL2
        mrs     x0, vbar_el2
        b       2f
 
-1:     stp     lr, xzr, [sp, #-16]!
-
+1:
        /*
-        * Compute the function address in EL2, and shuffle the parameters.
+        * Perform the EL2 call
         */
        kern_hyp_va     x0
-       mov     lr, x0
-       mov     x0, x1
-       mov     x1, x2
-       mov     x2, x3
-       blr     lr
+       do_el2_call
 
-       ldp     lr, xzr, [sp], #16
 2:     eret
 
 el1_trap: