Re: [PATCH v3 06/27] KVM: SVM: Fallback to flush everything if FLUSHBYASID is not available

From: Jim Mattson

Date: Wed Oct 14 2026 - 18:46:31 EST


On Mon, Oct 12, 2026 at 4:36 PM Yosry Ahmed <yosry@xxxxxxxxxx> wrote:
>
> Currently, if FLUSHBYASID is not available when performing a TLB flush,
> the fallback is decrementing the ASID generation to trigger allocating a
> new ASID. In preparation for using a static ASID per vCPU (like VMX),
> just fallback to flushing everything if FLUSHBYASID is not available.
> This is probably worse from a performance perspective, but FLUSHBYASID
> has been around for ~15 years and it's not worth carrying the
> complexity.
>
> Move the fallback logic into vmcb_set_flush_asid(), as more callers will
> be added and will need the fallback as well. The only other current
> caller is from SEV code, and no CPUs support SEV but not FLUSHBYASID (at
> least according to AI).

A more compelling argument is that sev_hardware_setup() requires FLUSHBYASID.

> Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx>
> Signed-off-by: Yosry Ahmed <yosry@xxxxxxxxxx>
> ---
> arch/x86/kvm/svm/svm.c | 5 +----
> arch/x86/kvm/svm/svm.h | 5 ++++-
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index ad4f172f170d9..0c3befd9bc850 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -4326,10 +4326,7 @@ static void svm_flush_tlb_asid(struct kvm_vcpu *vcpu)
> * unconditionally does a TLB flush on both nested VM-Enter and nested
> * VM-Exit (via kvm_mmu_reset_context()).
> */
> - if (cpu_feature_enabled(X86_FEATURE_FLUSHBYASID))
> - vmcb_set_flush_asid(svm->vmcb);
> - else
> - svm->current_vmcb->asid_generation--;
> + vmcb_set_flush_asid(svm->vmcb);
> }
>
> static void svm_flush_tlb_current(struct kvm_vcpu *vcpu)
> diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> index ba5077b9838c0..3b59561d6cc2c 100644
> --- a/arch/x86/kvm/svm/svm.h
> +++ b/arch/x86/kvm/svm/svm.h
> @@ -482,7 +482,10 @@ static inline void vmcb_set_gpat(struct vmcb *vmcb, u64 data)
>
> static inline void vmcb_set_flush_asid(struct vmcb *vmcb)
> {
> - vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
> + if (cpu_feature_enabled(X86_FEATURE_FLUSHBYASID))
> + vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ASID;
> + else
> + vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;

This is unnecessary. Hardware that doesn't have FLUSHBYASID only looks
at tlb_ctl bit 0 to decide whether or not to flush the entire TLB.
The other bits are ignored.

> }
>
> static inline void vmcb_clr_flush_asid(struct vmcb *vmcb)
> --
> 2.56.0.385.gd3acb90ef8-goog
>