From 197706ff16b86806689ea1580383e73efdf83cb2 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Tue, 14 Aug 2018 10:41:25 +0800 Subject: [PATCH] HV: Use the CPUID(0x16) to obtain tsc_hz when zero tsc_hz is returned by 0x15 cpuid Sometimes the CPUID(0x15) still returns the zero tsc frequency. In such case the base frequency of cpuid(0x16) is used as tsc frequency. Signed-off-by: Zhao Yakui Acked-by: Eddie Dong --- hypervisor/arch/x86/timer.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/hypervisor/arch/x86/timer.c b/hypervisor/arch/x86/timer.c index fe15d7300..f1b6275a8 100644 --- a/hypervisor/arch/x86/timer.c +++ b/hypervisor/arch/x86/timer.c @@ -278,10 +278,12 @@ static uint64_t pit_calibrate_tsc(uint32_t cal_ms_arg) } /* - * Determine TSC frequency via CPUID 0x15 + * Determine TSC frequency via CPUID 0x15 and 0x16. */ static uint64_t native_calibrate_tsc(void) { + uint64_t tsc_hz = 0; + if (boot_cpu_data.cpuid_level >= 0x15U) { uint32_t eax_denominator, ebx_numerator, ecx_hz, reserved; @@ -289,12 +291,18 @@ static uint64_t native_calibrate_tsc(void) &ecx_hz, &reserved); if ((eax_denominator != 0U) && (ebx_numerator != 0U)) { - return ((uint64_t) ecx_hz * + tsc_hz = ((uint64_t) ecx_hz * ebx_numerator) / eax_denominator; } } - return 0; + if ((tsc_hz == 0) && (boot_cpu_data.cpuid_level >= 0x16U)) { + uint32_t eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx; + cpuid(0x16U, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx); + tsc_hz = (uint64_t) eax_base_mhz * 1000000U; + } + + return tsc_hz; } void calibrate_tsc(void)