From ecf2308ee8de31d74bb3d59b5e5d2e66615d1141 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Mon, 8 Nov 2021 17:27:41 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Avoid switching to guest context if guest is already loaded Typically, TLB invalidation of guest stage-2 mappings using nVHE is performed by a hypercall originating from the host. For the invalidation instruction to be effective, therefore, __tlb_switch_to_{guest,host}() swizzle the active stage-2 context around the TLBI instruction. With guest-to-host memory sharing hypercalls originating from the guest under pKVM, there is no need to change the context when invalidating the TLB and restoring the host context is, in fact, harmful. Check the currently running vCPU in __tlb_switch_to_{guest,host}() and avoid switching the context if a vCPU is already loaded. Signed-off-by: Will Deacon Bug: 209580772 Change-Id: I4cfb36f0f88a2d50d50ea85a0d84e3e8191152a3 Signed-off-by: Will Deacon --- arch/arm64/kvm/hyp/nvhe/tlb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c index d296d617f589..82f8a5195505 100644 --- a/arch/arm64/kvm/hyp/nvhe/tlb.c +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c @@ -17,6 +17,17 @@ struct tlb_inv_context { static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu, struct tlb_inv_context *cxt) { + struct kvm_cpu_context *host_ctxt; + struct kvm_vcpu *vcpu; + + host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt; + vcpu = host_ctxt->__hyp_running_vcpu; + + if (vcpu) { + WARN_ON(vcpu->arch.hw_mmu->vmid.vmid != mmu->vmid.vmid); + return; + } + if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { u64 val; @@ -45,6 +56,12 @@ static void __tlb_switch_to_guest(struct kvm_s2_mmu *mmu, static void __tlb_switch_to_host(struct tlb_inv_context *cxt) { + struct kvm_cpu_context *host_ctxt; + + host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt; + if (host_ctxt->__hyp_running_vcpu) + return; + __load_host_stage2(); if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {