[RFC PATCH v2 02/25] KVM: SVM: Passthrough the number of supported ASIDs
From: Yosry Ahmed
Date: Mon Jun 15 2026 - 20:46:22 EST
KVM currently hardcodes the number of supported ASIDs in CPUID to 8. A
KVM guest (L1) would then do a full TLB flush (i.e.
TLB_CONTROL_FLUSH_ALL_ASID) every time it runs out of ASIDs on a vCPU
and updates the generation (see new_asid()).
This is currently harmless, as KVM (L0) uses the same ASID for both L1
and L2, and flushes that ASID on nested transitions. However, following
changes will add proper ASID emulation and a separate ASID for L2,
minimizing the TLB flushes on nested transitions. At that point, a full
TLB flush from a KVM guest (L1) would flush both L1 and L2 ASIDs, so
should be avoided as much as possible.
Passthrough the number of ASIDs in hardware instead of hardcoding 8, to
reduce the chances of an L1 guest flushing its own TLB entries
unnecessarily on a nested VMRUN.
In practice, there is no harm in exposing a large number of ASIDs to the
guest, even larger than what hardware supports, as KVM never actually
uses the value of ASID from vmcb12. Even with a separate L2 ASID, KVM
would allocate a (supported) ASID for L2, and just flush that same ASID
every time L1 changes the ASID in vmcb12.
That being said, avoid the temptation of just advertising the maximum
possible number of ASIDs (i.e. 0xFFFFFFFF), in case any peculiar guest
OS does not handle that properly.
Note: QEMU currently hardcodes the number of ASIDs to 16, so this change
doesn't help QEMU VMs (without making a similar change in QEMU).
Signed-off-by: Yosry Ahmed <yosry@xxxxxxxxxx>
---
arch/x86/kvm/cpuid.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 591d2294acd75..4486fc8d22b04 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -1824,8 +1824,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
break;
}
entry->eax = 1; /* SVM revision 1 */
- entry->ebx = 8; /* Lets support 8 ASIDs in case we add proper
- ASID emulation to nested SVM */
entry->ecx = 0; /* Reserved */
cpuid_entry_override(entry, CPUID_8000_000A_EDX);
break;
--
2.54.0.1136.gdb2ca164c4-goog