Skip to content

Commit 604dc91

Browse files
dsdIngo Molnar
authored and
Ingo Molnar
committed
x86/tsc: Use CPUID.0x16 to calculate missing crystal frequency
native_calibrate_tsc() had a data mapping Intel CPU families and crystal clock speed, but hardcoded tables are not ideal, and this approach was already problematic at least in the Skylake X case, as seen in commit: b511203 ("x86/tsc: Fix erroneous TSC rate on Skylake Xeon") By examining CPUID data from http://instlatx64.atw.hu/ and units in the lab, we have found that 3 different scenarios need to be dealt with, and we can eliminate most of the hardcoded data using an approach a little more advanced than before: 1. ApolloLake, GeminiLake, CannonLake (and presumably all new chipsets from this point) report the crystal frequency directly via CPUID.0x15. That's definitive data that we can rely upon. 2. Skylake, Kabylake and all variants of those two chipsets report a crystal frequency of zero, however we can calculate the crystal clock speed by condidering data from CPUID.0x16. This method correctly distinguishes between the two crystal clock frequencies present on different Skylake X variants that caused headaches before. As the calculations do not quite match the previously-hardcoded values in some cases (e.g. 23913043Hz instead of 24MHz), TSC refinement is enabled on all platforms where we had to calculate the crystal frequency in this way. 3. Denverton (GOLDMONT_X) reports a crystal frequency of zero and does not support CPUID.0x16, so we leave this entry hardcoded. Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Daniel Drake <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent ffa6f55 commit 604dc91

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

arch/x86/kernel/tsc.c

+27-20
Original file line numberDiff line numberDiff line change
@@ -631,31 +631,38 @@ unsigned long native_calibrate_tsc(void)
631631

632632
crystal_khz = ecx_hz / 1000;
633633

634-
if (crystal_khz == 0) {
635-
switch (boot_cpu_data.x86_model) {
636-
case INTEL_FAM6_SKYLAKE_MOBILE:
637-
case INTEL_FAM6_SKYLAKE_DESKTOP:
638-
case INTEL_FAM6_KABYLAKE_MOBILE:
639-
case INTEL_FAM6_KABYLAKE_DESKTOP:
640-
crystal_khz = 24000; /* 24.0 MHz */
641-
break;
642-
case INTEL_FAM6_ATOM_GOLDMONT_X:
643-
crystal_khz = 25000; /* 25.0 MHz */
644-
break;
645-
case INTEL_FAM6_ATOM_GOLDMONT:
646-
crystal_khz = 19200; /* 19.2 MHz */
647-
break;
648-
}
649-
}
634+
/*
635+
* Denverton SoCs don't report crystal clock, and also don't support
636+
* CPUID.0x16 for the calculation below, so hardcode the 25MHz crystal
637+
* clock.
638+
*/
639+
if (crystal_khz == 0 &&
640+
boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT_X)
641+
crystal_khz = 25000;
650642

651-
if (crystal_khz == 0)
652-
return 0;
653643
/*
654-
* TSC frequency determined by CPUID is a "hardware reported"
644+
* TSC frequency reported directly by CPUID is a "hardware reported"
655645
* frequency and is the most accurate one so far we have. This
656646
* is considered a known frequency.
657647
*/
658-
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
648+
if (crystal_khz != 0)
649+
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
650+
651+
/*
652+
* Some Intel SoCs like Skylake and Kabylake don't report the crystal
653+
* clock, but we can easily calculate it to a high degree of accuracy
654+
* by considering the crystal ratio and the CPU speed.
655+
*/
656+
if (crystal_khz == 0 && boot_cpu_data.cpuid_level >= 0x16) {
657+
unsigned int eax_base_mhz, ebx, ecx, edx;
658+
659+
cpuid(0x16, &eax_base_mhz, &ebx, &ecx, &edx);
660+
crystal_khz = eax_base_mhz * 1000 *
661+
eax_denominator / ebx_numerator;
662+
}
663+
664+
if (crystal_khz == 0)
665+
return 0;
659666

660667
/*
661668
* For Atom SoCs TSC is the only reliable clocksource.

0 commit comments

Comments
 (0)