mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
KVM: arm64: Remove VM-wide VNCR mapping counter
The global VNCR mapping counter is used to decide whether an L1
provided VNCR page is mapped in L0 on any CPU at the point of
dealing with a TLB invalidation. It is incremented when a mapping
is made in the fixmap, and decremented when unmapped.
As it turns out, this tracking has several flaws:
- we are trying to invalidate TLBs, and the mapping is only an
opportunistic consequence of the TLB. Checking this counter to
decide whether a TLB needs to be invalidated may result in missed
invalidations.
- an L1 vcpu invalidating its own TLB (a very likely case) will not
succeed in invalidating the VNCR pseudo TLB because that page is
not mapped in L0 at this stage.
Given that this tracking fails at delivering the minimum guarantees
that are required and is only a performance optimisation, remove it
completely.
Fixes: 4ffa72ad8f ("KVM: arm64: nv: Add S1 TLB invalidation primitive for VNCR_EL2")
Reviewed-by: Yuan Yao <yaoyuan@linux.alibaba.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Cc: stable@vger.kernel.org
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Link: https://patch.msgid.link/20260806091026.620700-2-maz@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
This commit is contained in:
parent
f5098b6bae
commit
c55bc773b6
|
|
@ -411,9 +411,6 @@ struct kvm_arch {
|
|||
/* Masks for VNCR-backed and general EL2 sysregs */
|
||||
struct kvm_sysreg_masks *sysreg_masks;
|
||||
|
||||
/* Count the number of VNCR_EL2 currently mapped */
|
||||
atomic_t vncr_map_count;
|
||||
|
||||
/*
|
||||
* For an untrusted host VM, 'pkvm.handle' is used to lookup
|
||||
* the associated pKVM instance in the hypervisor.
|
||||
|
|
|
|||
|
|
@ -427,8 +427,7 @@ static bool kvm_hyp_handle_tlbi_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
|
|||
* If we have to check for any VNCR mapping being invalidated,
|
||||
* go back to the slow path for further processing.
|
||||
*/
|
||||
if (vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu) &&
|
||||
atomic_read(&vcpu->kvm->arch.vncr_map_count))
|
||||
if (vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu))
|
||||
return false;
|
||||
|
||||
__kvm_skip_instr(vcpu);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ void kvm_init_nested(struct kvm *kvm)
|
|||
{
|
||||
kvm->arch.nested_mmus = NULL;
|
||||
kvm->arch.nested_mmus_size = 0;
|
||||
atomic_set(&kvm->arch.vncr_map_count, 0);
|
||||
}
|
||||
|
||||
static int init_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
|
||||
|
|
@ -890,7 +889,6 @@ static void this_cpu_reset_vncr_fixmap(struct kvm_vcpu *vcpu)
|
|||
clear_fixmap(vncr_fixmap(vcpu->arch.vncr_tlb->cpu));
|
||||
vcpu->arch.vncr_tlb->cpu = -1;
|
||||
host_data_clear_flag(L1_VNCR_MAPPED);
|
||||
atomic_dec(&vcpu->kvm->arch.vncr_map_count);
|
||||
}
|
||||
|
||||
void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
|
||||
|
|
@ -1592,7 +1590,6 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu)
|
|||
if (pgprot_val(prot) != pgprot_val(PAGE_NONE)) {
|
||||
__set_fixmap(vncr_fixmap(vt->cpu), vt->hpa, prot);
|
||||
host_data_set_flag(L1_VNCR_MAPPED);
|
||||
atomic_inc(&vcpu->kvm->arch.vncr_map_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user