[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 13/16] x86/kvmclock: Get CPU base frequency from CPUID when it's available
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/kvmclock.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index a7c4ae7f92e2..66e53b15dd1d 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -102,6 +102,20 @@ static inline void kvm_sched_clock_init(bool stable) sizeof(((struct pvclock_vcpu_time_info *)NULL)->system_time)); } +static unsigned long kvm_get_cpu_khz(void) +{ + unsigned int cpu_khz; + + /* + * Prefer CPUID over kvmclock when possible, as the base CPU frequency + * isn't necessary the same as the kvmlock "TSC" frequency. + */ + if (!cpuid_get_cpu_freq(&cpu_khz)) + return cpu_khz; + + return pvclock_tsc_khz(this_cpu_pvti()); +} + /* * If we don't do that, there is the possibility that the guest * will calibrate under heavy load - thus, getting a lower lpj - @@ -332,7 +346,7 @@ void __init kvmclock_init(void) flags = pvclock_read_flags(&hv_clock_boot[0].pvti); kvm_sched_clock_init(flags & PVCLOCK_TSC_STABLE_BIT); - tsc_register_calibration_routines(kvm_get_tsc_khz, kvm_get_tsc_khz, + tsc_register_calibration_routines(kvm_get_tsc_khz, kvm_get_cpu_khz, tsc_properties); x86_platform.get_wallclock = kvm_get_wallclock; -- 2.48.1.362.g079036d154-goog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |