From 6c9ae25dfcaea32512fc27308c64e78159c46aeb Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 3 Apr 2017 19:37:35 +0100 Subject: arm64: KVM: Move lr save/restore to do_el2_call At the moment, we only save/restore lr if on VHE, as we rely only the EL1 code to have preserved it in the non-VHE case. As we're about to get rid of the latter, let's move the save/restore code to the do_el2_call macro, unifying both code paths. Acked-by: Catalin Marinas Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm64/kvm/hyp/hyp-entry.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm64/kvm/hyp') diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 5e9052f087f2..d8ef788646c6 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -32,17 +32,17 @@ * Shuffle the parameters before calling the function * pointed to in x0. Assumes parameters in x[1,2,3]. */ + str lr, [sp, #-16]! mov lr, x0 mov x0, x1 mov x1, x2 mov x2, x3 blr lr + ldr lr, [sp], #16 .endm ENTRY(__vhe_hyp_call) - str lr, [sp, #-16]! do_el2_call - ldr lr, [sp], #16 /* * We used to rely on having an exception return to get * an implicit isb. In the E2H case, we don't have it anymore. -- cgit v1.2.3 From 5fbe9a599a30940c10ede35f90eb7014a6c2ed70 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 3 Apr 2017 19:37:42 +0100 Subject: arm64: KVM: Allow the main HYP code to use the init hyp stub implementation We now have a full hyp-stub implementation in the KVM init code, but the main KVM code only supports HVC_GET_VECTORS, which is not enough. Instead of reinventing the wheel, let's reuse the init implementation by branching to the idmap page when called with a hyp-stub hypercall. Acked-by: Catalin Marinas Reviewed-by: James Morse Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'arch/arm64/kvm/hyp') diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index d8ef788646c6..4f34c5996f86 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -87,10 +87,24 @@ alternative_endif /* Here, we're pretty sure the host called HVC. */ ldp x0, x1, [sp], #16 - cmp x0, #HVC_GET_VECTORS - b.ne 1f - mrs x0, vbar_el2 - b 2f + /* Check for a stub HVC call */ + cmp x0, #HVC_STUB_HCALL_NR + b.hs 1f + + /* + * Compute the idmap address of __kvm_handle_stub_hvc and + * jump there. Since we use kimage_voffset, do not use the + * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead + * (by loading it from the constant pool). + * + * Preserve x0-x4, which may contain stub parameters. + */ + ldr x5, =__kvm_handle_stub_hvc + ldr_l x6, kimage_voffset + + /* x5 = __pa(x5) */ + sub x5, x5, x6 + br x5 1: /* @@ -99,7 +113,7 @@ alternative_endif kern_hyp_va x0 do_el2_call -2: eret + eret el1_trap: /* -- cgit v1.2.3 From 4adb1341c7ef68af54732ef11f69faedffa6acb7 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 3 Apr 2017 19:37:43 +0100 Subject: arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors We are now able to use the hyp stub to reset HYP mode. Time to kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors. Acked-by: Catalin Marinas Reviewed-by: James Morse Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm64/include/asm/kvm_asm.h | 1 - arch/arm64/include/asm/kvm_host.h | 3 +-- arch/arm64/kvm/hyp-init.S | 2 -- arch/arm64/kvm/hyp/hyp-entry.S | 15 --------------- 4 files changed, 1 insertion(+), 20 deletions(-) (limited to 'arch/arm64/kvm/hyp') diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index b7e4ef5fcc41..26a64d0f9ab9 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -47,7 +47,6 @@ struct kvm_vcpu; extern char __kvm_hyp_init[]; extern char __kvm_hyp_init_end[]; -extern char __kvm_hyp_reset[]; extern char __kvm_hyp_vector[]; diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e7705e7bb07b..0355dd109956 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -362,11 +362,10 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr, __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr); } -void __kvm_hyp_teardown(void); 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); + __hyp_reset_vectors(); } static inline void kvm_arch_hardware_unsetup(void) {} diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S index fded932ede1b..b7a8f12293cc 100644 --- a/arch/arm64/kvm/hyp-init.S +++ b/arch/arm64/kvm/hyp-init.S @@ -134,7 +134,6 @@ ENTRY(__kvm_handle_stub_hvc) /* * Reset kvm back to the hyp stub. */ -ENTRY(__kvm_hyp_reset) /* We're now in idmap, disable MMU */ mrs x0, sctlr_el2 ldr x1, =SCTLR_ELx_FLAGS @@ -152,7 +151,6 @@ ENTRY(__kvm_hyp_reset) exit: eret -ENDPROC(__kvm_hyp_reset) ENDPROC(__kvm_handle_stub_hvc) .ltorg diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 4f34c5996f86..5170ce1021da 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -53,21 +53,6 @@ ENTRY(__vhe_hyp_call) 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 stp x0, x1, [sp, #-16]! -- cgit v1.2.3