Created attachment 207346 [details]
Patch (Revision 1)
Keep in mind that I am new to the kernel.
If frequency for CPUID 0x15 is zero, fall back to CPUID 0x16 for the TSC clock if available. This is needed on some Intel SOCs like Skylake and Kaby Lake whcih report 0 for the crystal clock..
Inspired by Linux commit 604dc9170f2435d27da5039a3efd757dceadc684.
Tested on the HP Spectre x360 13-ap0043dx running 13-CURRENT with an accurate clock using this patch (without the patch, the ticks are slower).
If frequency for CPUID 0x15 is zero, fall back to CPUID 0x16 for the TSC clock if available. This is needed on some Intel SOCs like Skylake and Kaby Lake which report 0 for the crystal clock.
(In reply to Neel Chauhan from comment #1)
It is wrong to use cpuid leaf 0x16 for frequency base, this is explicitly stated in Intel SDM. Also, I am even more curious about your machine config.
Please post verbose dmesg, as requested.
This patch is based upon an existing Linux commit: https://github.com/torvalds/linux/commit/604dc9170f2435d27da5039a3efd757dceadc684
In the commit message:
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
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.
This is also true on my system.
I will post two verbose dmesgs: one without any patches, and one with this patch (which also has drm-kmod and Vladimir Kondratyev's iichid loaded).
Created attachment 207426 [details]
dmesg log on the Spectre x360 without any patches (LiveUSB)
Created attachment 207427 [details]
dmesg log on the Spectre x360 with the Bug 240475 patch (Main System)
Your patch is still not equivalent to what Linux did. Note that they still apply the nom/denom coefficient reported from leaf 0x15, but take adjusted mhz from 0x16, instead of zero hz from 0x15. In other words, they do not hardcode 100000.
It's true that Linux does this (lines 660-661):
crystal_khz = eax_base_mhz * 1000 *
eax_denominator / ebx_numerator;
But in the same function, Linux returns this (line 674):
return crystal_khz * ebx_numerator / eax_denominator;
So the numerator and denominator in crystal_khz effectively cancels out on CPUID 0x16.
From what I understand, Linux expects the value in kilohertz, so a multiplier of 1000 works on Linux. I believe FreeBSD expects hertz, so a multiplier of 1000000 is needed.
For unit conversion of megahertz to hertz, 1000 Hz = 1 KHz and 1000 KHz = 1 MHz, so 1 MHz = 1000 KHz * 1000 Hz.
Also, using the numerator and denominator wouldn't work (I've tried that, I got a kernel panic).