Extract the guts of cpu_khz_from_cpuid() to a standalone helper that doesn't restrict the usage to Intel CPUs. This will allow sharing the core logic with KVM-as-a-guest, as KVM generally doesn't restrict CPUID based on vendor. No functional change intended. Reviewed-by: David Woodhouse Signed-off-by: Sean Christopherson --- arch/x86/include/asm/tsc.h | 1 + arch/x86/kernel/tsc.c | 32 +++++++++++++++----------------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/tsc.h b/arch/x86/include/asm/tsc.h index 4a224f99c3b9..7ff2bfdcdf38 100644 --- a/arch/x86/include/asm/tsc.h +++ b/arch/x86/include/asm/tsc.h @@ -90,6 +90,7 @@ struct cpuid_tsc_info { unsigned int tsc_khz; }; extern int __init cpuid_get_tsc_freq(struct cpuid_tsc_info *info); +extern unsigned int __cpu_khz_from_cpuid(void); extern void tsc_early_init(void); extern void tsc_init(void); diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index 3e911f0f7364..bdff8c988866 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -692,6 +692,18 @@ int __init cpuid_get_tsc_freq(struct cpuid_tsc_info *info) return 0; } +unsigned int __cpu_khz_from_cpuid(void) +{ + unsigned int eax_base_mhz, ebx, ecx, edx; + + if (boot_cpu_data.cpuid_level < CPUID_LEAF_FREQ) + return 0; + + cpuid(CPUID_LEAF_FREQ, &eax_base_mhz, &ebx, &ecx, &edx); + + return eax_base_mhz * 1000; +} + /** * native_calibrate_tsc - determine TSC frequency * Determine TSC frequency via CPUID, else return 0. @@ -727,13 +739,8 @@ static 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 (!info.crystal_khz && 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); - info.crystal_khz = eax_base_mhz * 1000 * - info.denominator / info.numerator; - } + if (!info.crystal_khz) + info.crystal_khz = __cpu_khz_from_cpuid() * info.denominator / info.numerator; if (!info.crystal_khz) return 0; @@ -760,19 +767,10 @@ static 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); - - return eax_base_mhz * 1000; + return __cpu_khz_from_cpuid(); } /* -- 2.54.0.823.g6e5bcc1fc9-goog