[PATCH v4 21/47] x86/xen: Obtain TSC frequency from CPUID if present

From: Sean Christopherson

Date: Fri May 29 2026 - 11:25:17 EST


From: David Woodhouse <dwmw@xxxxxxxxxxxx>

The Xen CPUID leaf 3, sub-leaf 0, ECX provides the guest TSC frequency
in kHz directly. Use it when available instead of reverse-calculating
the frequency from the pvclock tsc_to_system_mul and tsc_shift values,
which loses precision.

This mirrors the equivalent change for KVM guests using the generic
0x40000010 timing leaf.

Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
[sean: drop non-Xen changes]
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/xen/time.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 487ad838c441..36d66abf5379 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -42,6 +42,17 @@ static unsigned int __init xen_tsc_khz(void)
{
struct pvclock_vcpu_time_info *info =
&HYPERVISOR_shared_info->vcpu_info[0].time;
+ u32 base = xen_cpuid_base();
+ u32 eax, ebx, ecx, edx;
+
+ /*
+ * If Xen provides the guest TSC frequency directly in CPUID
+ * (leaf 3, sub-leaf 0, ECX), use that instead of reverse-
+ * calculating from the pvclock mul/shift.
+ */
+ cpuid_count(base + 3, 0, &eax, &ebx, &ecx, &edx);
+ if (ecx)
+ return ecx;

return pvclock_tsc_khz(info);
}
--
2.54.0.823.g6e5bcc1fc9-goog