arm64: KVM: Simplify HYP init/teardown
authorMarc Zyngier <marc.zyngier@arm.com>
Thu, 30 Jun 2016 17:40:44 +0000 (18:40 +0100)
committerChristoffer Dall <christoffer.dall@linaro.org>
Sun, 3 Jul 2016 21:41:27 +0000 (23:41 +0200)
Now that we only have the "merged page tables" case to deal with,
there is a bunch of things we can simplify in the HYP code (both
at init and teardown time).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/hyp-init.S
arch/arm64/kvm/hyp/entry.S
arch/arm64/kvm/hyp/hyp-entry.S
arch/arm64/kvm/reset.c

index 49095fc4b482d3f455aa4d7d0fe48aa6f0252abc..88462c307510244e52ea7f334f3e06c8c8489a66 100644 (file)
@@ -48,7 +48,6 @@
 int __attribute_const__ kvm_target_cpu(void);
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu);
 int kvm_arch_dev_ioctl_check_extension(long ext);
-unsigned long kvm_hyp_reset_entry(void);
 void __extended_idmap_trampoline(phys_addr_t boot_pgd, phys_addr_t idmap_start);
 
 struct kvm_arch {
@@ -357,19 +356,14 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr,
         * Call initialization code, and switch to the full blown
         * HYP code.
         */
-       __kvm_call_hyp((void *)boot_pgd_ptr, pgd_ptr,
-                      hyp_stack_ptr, vector_ptr);
+       __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
+void __kvm_hyp_teardown(void);
 static inline void __cpu_reset_hyp_mode(phys_addr_t boot_pgd_ptr,
                                        phys_addr_t phys_idmap_start)
 {
-       /*
-        * Call reset code, and switch back to stub hyp vectors.
-        * Uses __kvm_call_hyp() to avoid kaslr's kvm_ksym_ref() translation.
-        */
-       __kvm_call_hyp((void *)kvm_hyp_reset_entry(),
-                      boot_pgd_ptr, phys_idmap_start);
+       kvm_call_hyp(__kvm_hyp_teardown, phys_idmap_start);
 }
 
 static inline void kvm_arch_hardware_unsetup(void) {}
index a873a6d8be908da6549fb5fa02a437de11d4f91c..6b29d3d9e1f285c0f1e61c3509cfbaf99402ea86 100644 (file)
@@ -53,10 +53,9 @@ __invalid:
        b       .
 
        /*
-        * x0: HYP boot pgd
-        * x1: HYP pgd
-        * x2: HYP stack
-        * x3: HYP vectors
+        * x0: HYP pgd
+        * x1: HYP stack
+        * x2: HYP vectors
         */
 __do_hyp_init:
 
@@ -110,71 +109,27 @@ __do_hyp_init:
        msr     sctlr_el2, x4
        isb
 
-       /* Skip the trampoline dance if we merged the boot and runtime PGDs */
-       cmp     x0, x1
-       b.eq    merged
-
-       /* MMU is now enabled. Get ready for the trampoline dance */
-       ldr     x4, =TRAMPOLINE_VA
-       adr     x5, target
-       bfi     x4, x5, #0, #PAGE_SHIFT
-       br      x4
-
-target: /* We're now in the trampoline code, switch page tables */
-       msr     ttbr0_el2, x1
-       isb
-
-       /* Invalidate the old TLBs */
-       tlbi    alle2
-       dsb     sy
-
-merged:
        /* Set the stack and new vectors */
+       kern_hyp_va     x1
+       mov     sp, x1
        kern_hyp_va     x2
-       mov     sp, x2
-       kern_hyp_va     x3
-       msr     vbar_el2, x3
+       msr     vbar_el2, x2
 
        /* Hello, World! */
        eret
 ENDPROC(__kvm_hyp_init)
 
        /*
-        * Reset kvm back to the hyp stub. This is the trampoline dance in
-        * reverse. If kvm used an extended idmap, __extended_idmap_trampoline
-        * calls this code directly in the idmap. In this case switching to the
-        * boot tables is a no-op.
-        *
-        * x0: HYP boot pgd
-        * x1: HYP phys_idmap_start
+        * Reset kvm back to the hyp stub.
         */
 ENTRY(__kvm_hyp_reset)
-       /* We're in trampoline code in VA, switch back to boot page tables */
-       msr     ttbr0_el2, x0
-       isb
-
-       /* Ensure the PA branch doesn't find a stale tlb entry or stale code. */
-       ic      iallu
-       tlbi    alle2
-       dsb     sy
-       isb
-
-       /* Branch into PA space */
-       adr     x0, 1f
-       bfi     x1, x0, #0, #PAGE_SHIFT
-       br      x1
-
        /* We're now in idmap, disable MMU */
-1:     mrs     x0, sctlr_el2
+       mrs     x0, sctlr_el2
        ldr     x1, =SCTLR_ELx_FLAGS
        bic     x0, x0, x1              // Clear SCTL_M and etc
        msr     sctlr_el2, x0
        isb
 
-       /* Invalidate the old TLBs */
-       tlbi    alle2
-       dsb     sy
-
        /* Install stub vectors */
        adr_l   x0, __hyp_stub_vectors
        msr     vbar_el2, x0
index 70254a65bd5b927387b975a0c395bba6cb7d7de0..ce9e5e5f28cfb782c15090aea84bb282cd0b56c2 100644 (file)
@@ -164,22 +164,3 @@ alternative_endif
 
        eret
 ENDPROC(__fpsimd_guest_restore)
-
-/*
- * When using the extended idmap, we don't have a trampoline page we can use
- * while we switch pages tables during __kvm_hyp_reset. Accessing the idmap
- * directly would be ideal, but if we're using the extended idmap then the
- * idmap is located above HYP_PAGE_OFFSET, and the address will be masked by
- * kvm_call_hyp using kern_hyp_va.
- *
- * x0: HYP boot pgd
- * x1: HYP phys_idmap_start
- */
-ENTRY(__extended_idmap_trampoline)
-       mov     x4, x1
-       adr_l   x3, __kvm_hyp_reset
-
-       /* insert __kvm_hyp_reset()s offset into phys_idmap_start */
-       bfi     x4, x3, #0, #PAGE_SHIFT
-       br      x4
-ENDPROC(__extended_idmap_trampoline)
index 2d87f36d5cb494d5451ac756490056afffb87734..f6d9694ae3b13f32771f2661a4f905b8983cfba4 100644 (file)
@@ -62,6 +62,21 @@ ENTRY(__vhe_hyp_call)
        isb
        ret
 ENDPROC(__vhe_hyp_call)
+
+/*
+ * Compute the idmap address of __kvm_hyp_reset based on the idmap
+ * start passed as a parameter, and jump there.
+ *
+ * x0: HYP phys_idmap_start
+ */
+ENTRY(__kvm_hyp_teardown)
+       mov     x4, x0
+       adr_l   x3, __kvm_hyp_reset
+
+       /* insert __kvm_hyp_reset()s offset into phys_idmap_start */
+       bfi     x4, x3, #0, #PAGE_SHIFT
+       br      x4
+ENDPROC(__kvm_hyp_teardown)
        
 el1_sync:                              // Guest trapped into EL2
        save_x0_to_x3
index 8ed7e4a92e9556208270d4e0de6fe04311059ee3..79f324823340de8bbd8359058ad47d7919a5a49c 100644 (file)
@@ -132,14 +132,3 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
        /* Reset timer */
        return kvm_timer_vcpu_reset(vcpu, cpu_vtimer_irq);
 }
-
-unsigned long kvm_hyp_reset_entry(void)
-{
-       /*
-        * KVM is running with merged page tables, which don't have the
-        * trampoline page mapped. We know the idmap is still mapped,
-        * but can't be called into directly. Use
-        * __extended_idmap_trampoline to do the call.
-        */
-       return (unsigned long)kvm_ksym_ref(__extended_idmap_trampoline);
-}