When running as a KVM guest with PV timing info provided by the host, stuff the APIC timer period/frequency with the local APIC bus frequency reported in CPUID.0x40000010.EBX instead of trying to calibrate/guess the frequency.
Note, the unit of measurement for lapic_timer_period is "ticks per HZ", not Khz. See Documentation/virt/kvm/x86/cpuid.rst for details. Signed-off-by: Sean Christopherson <[email protected]> --- arch/x86/kernel/kvm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 4fe9c69bf40b..c1139182121d 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -977,6 +977,7 @@ static void __init kvm_init_platform(void) .mask_lo = (u32)(~(SZ_4G - tolud - 1)) | MTRR_PHYSMASK_V, .mask_hi = (BIT_ULL(boot_cpu_data.x86_phys_bits) - 1) >> 32, }; + u32 apic_khz __maybe_unused; u32 timing_info_leaf; bool tsc_is_reliable; @@ -1039,6 +1040,13 @@ static void __init kvm_init_platform(void) x86_init.hyper.get_tsc_khz = kvm_get_tsc_khz; x86_init.hyper.get_cpu_khz = kvm_get_tsc_khz; } + +#ifdef CONFIG_X86_LOCAL_APIC + /* The leaf also includes the local APIC bus/timer frequency.*/ + apic_khz = cpuid_ebx(timing_info_leaf); + if (apic_khz) + lapic_timer_period = apic_khz * 1000 / HZ; +#endif } /* -- 2.54.0.823.g6e5bcc1fc9-goog

