Skip to content

Commit 6ded46b

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: nv: Keep reference on stage-2 MMU when scheduled out
If a vCPU is scheduling out and not in WFI emulation, it is highly likely it will get scheduled again soon and reuse the MMU it had before. Dropping the MMU at vcpu_put() can have some unfortunate consequences, as the MMU could get reclaimed and used in a different context, forcing another 'cold start' on an otherwise active MMU. Avoid that altogether by keeping a reference on the MMU if the vCPU is scheduling out, ensuring that another vCPU cannot reclaim it while the current vCPU is away. Since there are more MMUs than vCPUs, this does not affect the guarantee that an unused MMU is available at any time. Furthermore, this makes the vcpu->arch.hw_mmu ~stable in preemptible code, at least for where it matters in the stage-2 abort path. Yes, the MMU can change across WFI emulation, but there isn't even a use case where this would matter. Signed-off-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent ae8f8b3 commit 6ded46b

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

arch/arm64/kvm/nested.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,13 @@ void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu)
663663

664664
void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
665665
{
666+
/*
667+
* The vCPU kept its reference on the MMU after the last put, keep
668+
* rolling with it.
669+
*/
670+
if (vcpu->arch.hw_mmu)
671+
return;
672+
666673
if (is_hyp_ctxt(vcpu)) {
667674
vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
668675
} else {
@@ -674,10 +681,18 @@ void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
674681

675682
void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
676683
{
677-
if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) {
684+
/*
685+
* Keep a reference on the associated stage-2 MMU if the vCPU is
686+
* scheduling out and not in WFI emulation, suggesting it is likely to
687+
* reuse the MMU sometime soon.
688+
*/
689+
if (vcpu->scheduled_out && !vcpu_get_flag(vcpu, IN_WFI))
690+
return;
691+
692+
if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu))
678693
atomic_dec(&vcpu->arch.hw_mmu->refcnt);
679-
vcpu->arch.hw_mmu = NULL;
680-
}
694+
695+
vcpu->arch.hw_mmu = NULL;
681696
}
682697

683698
/*

0 commit comments

Comments
 (0)