[PATCH v6 24/51] x86/kvm: Get CPU base frequency from CPUID when it's available
From: Sean Christopherson
Date: Thu Aug 06 2026 - 19:42:36 EST
If CPUID.0x16 is present and valid, use the CPU frequency provided by
CPUID instead of assuming that the virtual CPU runs at the same
frequency as TSC and/or kvmclock. Back before constant TSCs were a
thing, treating the TSC and CPU frequencies as one and the same was
somewhat reasonable, but now it's nonsensical, especially if the
hypervisor explicitly enumerates the CPU frequency.
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kernel/kvm.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 255a24a99f28..83b9351f2810 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -50,6 +50,7 @@
#include <asm/e820/api.h>
static unsigned int kvm_tsc_khz_cpuid __initdata;
+static unsigned int kvm_cpu_khz_cpuid __initdata;
DEFINE_STATIC_KEY_FALSE_RO(kvm_async_pf_enabled);
@@ -930,6 +931,11 @@ static unsigned int __init kvm_get_tsc_khz(void)
return kvm_tsc_khz_cpuid;
}
+static unsigned int __init kvm_get_cpu_khz(void)
+{
+ return kvm_cpu_khz_cpuid;
+}
+
unsigned int kvm_arch_para_features(void)
{
return cpuid_eax(kvm_cpuid_base() | KVM_CPUID_FEATURES);
@@ -1043,6 +1049,14 @@ static void __init kvm_init_platform(void)
}
}
+ /*
+ * Prefer CPUID.0x16 over KVM's PV CPUID when possible, as the base CPU
+ * frequency isn't necessarily the same as the TSC frequency.
+ */
+ kvm_cpu_khz_cpuid = __cpu_khz_from_cpuid();
+ if (kvm_cpu_khz_cpuid)
+ x86_init.hyper.get_cpu_khz = kvm_get_cpu_khz;
+
/*
* If the TSC counts at a constant frequency across P/T states and in
* deep C-states, treat the TSC reliable, as guaranteed by KVM.
--
2.55.0.679.g6767b8d81c-goog