[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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



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>
---
 arch/x86/kvm/x86.c  |  3 +--
 arch/x86/xen/time.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c15303963686..ac982652e5e0 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3469,7 +3469,6 @@ static void kvm_setup_guest_pvclock(struct 
pvclock_vcpu_time_info *ref_hv_clock,
 int kvm_guest_time_update(struct kvm_vcpu *v)
 {
        struct pvclock_vcpu_time_info hv_clock = {};
-       unsigned long flags;
        u64 tgt_tsc_hz;
        unsigned seq;
        struct kvm_vcpu_arch *vcpu = &v->arch;
@@ -10162,7 +10161,7 @@ static void kvm_hyperv_tsc_notifier(void)
        kvm_caps.max_guest_tsc_khz = tsc_khz;
 
        list_for_each_entry(kvm, &vm_list, vm_list) {
-               __kvm_start_pvclock_update(kvm);
+               __kvm_start_pvclock_update(kvm, NULL);
                pvclock_update_vm_gtod_copy(kvm);
                kvm_end_pvclock_update(kvm);
        }
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 6f9f665bb7ae..862b8e9e8405 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -41,8 +41,20 @@ static unsigned long xen_tsc_khz(void)
 {
        struct pvclock_vcpu_time_info *info =
                &HYPERVISOR_shared_info->vcpu_info[0].time;
+       u32 eax, ebx, ecx, edx;
+       u32 base = xen_cpuid_base();
 
        setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+       /*
+        * 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.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.