[PATCH v7 019/120] x86/tsc: Use parsed CPUID(0x16)
"Ahmed S. Darwish" <[email protected]> Thu, 28 May 2026 17:37:41 +0200
| Newsgroups | dev.linux.lists.x86-cpuid,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
At the x86 timestamp counter code, use parsed CPUID(0x16) access instead of a direct CPUID query. Beside the CPUID parser centralization benefits, this allows using the auto-generated <asm/cpuid/leaf_types.h> data types, and their full C99 bitfields, instead of doing ugly bitwise operations on CPUID output. Remove the "max standard level >= CPUID_LEVEL_FREQ" check since the CPUID parser API's NULL check is equivalent. Remove the Intel vendor check since the CPUID parser does a similar check before caching CPUID(0x16) output. Thus the CPUID API's NULL check is also equivalent. Signed-off-by: Ahmed S. Darwish <[email protected]> --- arch/x86/kernel/tsc.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index c5110eb554bc..0043ed398578 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -664,6 +664,7 @@ static unsigned long quick_pit_calibrate(void) */ unsigned long native_calibrate_tsc(void) { + const struct leaf_0x16_0 *l16 = cpuid_leaf(&boot_cpu_data, 0x16); unsigned int eax_denominator, ebx_numerator, ecx_hz, edx; unsigned int crystal_khz; @@ -705,13 +706,8 @@ unsigned long native_calibrate_tsc(void) * clock, but we can easily calculate it to a high degree of accuracy * by considering the crystal ratio and the CPU speed. */ - if (crystal_khz == 0 && boot_cpu_data.cpuid_level >= CPUID_LEAF_FREQ) { - unsigned int eax_base_mhz, ebx, ecx, edx; - - cpuid(CPUID_LEAF_FREQ, &eax_base_mhz, &ebx, &ecx, &edx); - crystal_khz = eax_base_mhz * 1000 * - eax_denominator / ebx_numerator; - } + if (crystal_khz == 0 && l16) + crystal_khz = l16->cpu_base_mhz * 1000 * eax_denominator / ebx_numerator; if (crystal_khz == 0) return 0; @@ -738,19 +734,9 @@ unsigned long native_calibrate_tsc(void) static unsigned long cpu_khz_from_cpuid(void) { - unsigned int eax_base_mhz, ebx_max_mhz, ecx_bus_mhz, edx; - - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return 0; - - if (boot_cpu_data.cpuid_level < CPUID_LEAF_FREQ) - return 0; - - eax_base_mhz = ebx_max_mhz = ecx_bus_mhz = edx = 0; - - cpuid(CPUID_LEAF_FREQ, &eax_base_mhz, &ebx_max_mhz, &ecx_bus_mhz, &edx); + const struct leaf_0x16_0 *l16 = cpuid_leaf(&boot_cpu_data, 0x16); - return eax_base_mhz * 1000; + return l16 ? (l16->cpu_base_mhz * 1000) : 0; } /* -- 2.54.0