arm: KVM: Allow hyp teardown
authorMarc Zyngier <marc.zyngier@arm.com>
Thu, 30 Jun 2016 17:40:48 +0000 (18:40 +0100)
committerChristoffer Dall <christoffer.dall@linaro.org>
Sun, 3 Jul 2016 21:41:27 +0000 (23:41 +0200)
So far, KVM was getting in the way of kexec on 32bit (and the arm64
kexec hackers couldn't be bothered to fix it on 32bit...).

With simpler page tables, tearing KVM down becomes very easy, so
let's just do it.

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

index 3d5a5cd071bd15d648658473bc5a747e0ef1ff81..58faff5f1eb2f39e5e82e691ddc3ce000a3a5b7a 100644 (file)
@@ -66,6 +66,8 @@ extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
 extern void __init_stage2_translation(void);
+
+extern void __kvm_hyp_reset(unsigned long);
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
index eafbfd5ad34aa67f83d17a20ef95fdfa9aef5706..58d0b69e7428ce5c3b0224d1b75e5c4642fd1b58 100644 (file)
@@ -266,12 +266,10 @@ static inline void __cpu_init_stage2(void)
        kvm_call_hyp(__init_stage2_translation);
 }
 
-static inline void __cpu_reset_hyp_mode(phys_addr_t phys_idmap_start)
+static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
+                                       phys_addr_t phys_idmap_start)
 {
-       /*
-        * TODO
-        * kvm_call_reset(phys_idmap_start);
-        */
+       kvm_call_hyp((void *)virt_to_idmap(__kvm_hyp_reset), vector_ptr);
 }
 
 static inline int kvm_arch_dev_ioctl_check_extension(long ext)
index 9b8c53798f50781666fc0323623ef4fffbe746d4..7cf266c502d6de5eb985f15f4a03949dc43e9e7a 100644 (file)
@@ -1074,7 +1074,8 @@ static void cpu_hyp_reinit(void)
 static void cpu_hyp_reset(void)
 {
        if (!is_kernel_in_hyp_mode())
-               __cpu_reset_hyp_mode(kvm_get_idmap_start());
+               __cpu_reset_hyp_mode(hyp_default_vectors,
+                                    kvm_get_idmap_start());
 }
 
 static void _kvm_arch_hardware_enable(void *discard)
index b82a99dcfb61c386fe681fb3c44fda3402ccd61e..bf89c919efc1a2254b3b0cc37eef53d0a0efd912 100644 (file)
@@ -112,6 +112,21 @@ __do_hyp_init:
 
        eret
 
+       @ r0 : stub vectors address
+ENTRY(__kvm_hyp_reset)
+       /* We're now in idmap, disable MMU */
+       mrc     p15, 4, r1, c1, c0, 0   @ HSCTLR
+       ldr     r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
+       bic     r1, r1, r2
+       mcr     p15, 4, r1, c1, c0, 0   @ HSCTLR
+
+       /* Install stub vectors */
+       mcr     p15, 4, r0, c12, c0, 0  @ HVBAR
+       isb
+
+       eret
+ENDPROC(__kvm_hyp_reset)
+
        .ltorg
 
        .globl __kvm_hyp_init_end
index 6731d4e1c7464ec980b84cb8d473fbf02c2f6d9f..69d5cc2d2e17f9557da82b25177e02e8cd490727 100644 (file)
@@ -359,7 +359,8 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 }
 
 void __kvm_hyp_teardown(void);
-static inline void __cpu_reset_hyp_mode(phys_addr_t phys_idmap_start)
+static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
+                                       phys_addr_t phys_idmap_start)
 {
        kvm_call_hyp(__kvm_hyp_teardown, phys_idmap_start);
 }