Re: [PATCH v3 22/27] KVM: nSVM: Flush the TLB if L1 changes L2's ASID in vmcb12
From: Jim Mattson
Date: Thu Oct 15 2026 - 19:10:06 EST
On Mon, Oct 12, 2026 at 4:36 PM Yosry Ahmed <yosry@xxxxxxxxxx> wrote:
>
> KVM uses a single ASID for L2 guests per-vCPU. Hence, when L1 changes
> L2's ASID in vmcb12 (e.g. due to switching to a different L2
> vCPU or simply to avoid flushing an existing ASID), KVM needs to flush
> the L2 ASID to correctly emulate different ASIDs as different TLB
> domains.
>
> Additionally, the nested NPT needs to be resync'd, as the MMU context
> is not tagged by ASID, and KVM cannot reuse nested NPT entries across
> different L2 ASIDs.
>
> Essentially, L1 switching L2's ASID is treated exactly the same as L1
> flushing L2's ASID, which is consistent with the APM:
>
> Software may effectively flush the guest's TLB entries by allocating a
> new ASID for the guest and not reusing the old ASID until the entire
> TLB has been flushed at least once.
>
> This is similar to nVMX's handling of last_vpid, except that when L1
> changes VPID12, KVM does *not* need to resync the nested EPT, because
> VMX VPIDs, unlike SVM ASIDs, do not tag guest-physical translations
> (i.e. nGPA to GPA translations).
>
> Reset last_asid when nested VMRUN fails to force a flush and sync on the
> next nested VMRUN. The TLB flush request survives the failure, but the
> request to sync the nested NPT does not, as it ends up being serviced in
> L1's MMU context after the synthesized VM-Exit.
>
> Drop the commentary about vmcb12's ASID being copied around only for the
> consistency checks, as they no longer apply, and opportunistically fix
> whitespace alignment.
>
> This is currently functionally a noop, as a full flush and sync is
> triggered on every nested transition, but is a step toward eliminating
> that.
>
> Signed-off-by: Yosry Ahmed <yosry@xxxxxxxxxx>
> ---
> arch/x86/kvm/svm/nested.c | 29 +++++++++++++++++++++++------
> arch/x86/kvm/svm/svm.h | 2 ++
> 2 files changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> index e04cc4f7669ea..8e4686b0d603a 100644
> --- a/arch/x86/kvm/svm/nested.c
> +++ b/arch/x86/kvm/svm/nested.c
> @@ -556,10 +556,8 @@ void __nested_copy_vmcb_control_to_cache(struct kvm_vcpu *vcpu,
> to->nested_cr3 = from->nested_cr3;
> to->pause_filter_count = from->pause_filter_count;
> to->pause_filter_thresh = from->pause_filter_thresh;
> -
> - /* Copy asid here because nested_vmcb_check_controls() will check it */
> - to->asid = from->asid;
> - to->clean = from->clean;
> + to->asid = from->asid;
> + to->clean = from->clean;
>
> #ifdef CONFIG_KVM_HYPERV
> /* Hyper-V extensions (Enlightened VMCB) */
> @@ -691,23 +689,35 @@ static void nested_save_pending_event_to_vmcb12(struct vcpu_svm *svm,
> static void nested_svm_entry_tlb_flush(struct kvm_vcpu *vcpu)
> {
> struct vcpu_svm *svm = to_svm(vcpu);
> + bool new_asid = false;
>
> /* Handle pending Hyper-V TLB flush requests */
> kvm_hv_nested_transtion_tlb_flush(vcpu, npt_enabled);
>
> + if (svm->nested.ctl.asid != svm->nested.last_asid) {
> + svm->nested.last_asid = svm->nested.ctl.asid;
> + new_asid = true;
> + }
To make sure we don't miss a flush after restore, do we need to clear
last_asid in svm_set_nested_state()?