Skip to content

Commit 197706f

Browse files
yakuizhaolijinxia
authored andcommitted
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 <yakui.zhao@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 7d83abb commit 197706f

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

hypervisor/arch/x86/timer.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,23 +278,31 @@ static uint64_t pit_calibrate_tsc(uint32_t cal_ms_arg)
278278
}
279279

280280
/*
281-
* Determine TSC frequency via CPUID 0x15
281+
* Determine TSC frequency via CPUID 0x15 and 0x16.
282282
*/
283283
static uint64_t native_calibrate_tsc(void)
284284
{
285+
uint64_t tsc_hz = 0;
286+
285287
if (boot_cpu_data.cpuid_level >= 0x15U) {
286288
uint32_t eax_denominator, ebx_numerator, ecx_hz, reserved;
287289

288290
cpuid(0x15U, &eax_denominator, &ebx_numerator,
289291
&ecx_hz, &reserved);
290292

291293
if ((eax_denominator != 0U) && (ebx_numerator != 0U)) {
292-
return ((uint64_t) ecx_hz *
294+
tsc_hz = ((uint64_t) ecx_hz *
293295
ebx_numerator) / eax_denominator;
294296
}
295297
}
296298

297-
return 0;
299+
if ((tsc_hz == 0) && (boot_cpu_data.cpuid_level >= 0x16U)) {
300+
uint32_t eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx;
301+
cpuid(0x16U, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx);
302+
tsc_hz = (uint64_t) eax_base_mhz * 1000000U;
303+
}
304+
305+
return tsc_hz;
298306
}
299307

300308
void calibrate_tsc(void)

0 commit comments

Comments
 (0)