On Tue, May 19, 2026, Michael Kelley wrote: > From: Sean Christopherson <[email protected]> Sent: Monday, May 18, 2026 3:18 > PM > > > > diff --git a/arch/x86/kernel/cpu/mshyperv.c > > > > b/arch/x86/kernel/cpu/mshyperv.c > > > > --- a/arch/x86/kernel/cpu/mshyperv.c > > > > +++ b/arch/x86/kernel/cpu/mshyperv.c > > > > @@ -516,8 +516,13 @@ static void __init ms_hyperv_init_platform(void) > > > > > > > > if (ms_hyperv.features & HV_ACCESS_FREQUENCY_MSRS && > > > > ms_hyperv.misc_features & > > > > HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) { > > > > - tsc_register_calibration_routines(hv_get_tsc_khz, > > > > hv_get_tsc_khz); > > > > - setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ); > > > > + enum tsc_properties tsc_properties = > > > > TSC_FREQUENCY_KNOWN; > > > > + > > > > + if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) > > > > + tsc_properties = TSC_FREQ_KNOWN_AND_RELIABLE; > > > > + > > > > + tsc_register_calibration_routines(hv_get_tsc_khz, > > > > hv_get_tsc_khz, > > > > + tsc_properties); > > > > } > > > > > > [ ... ] > > > > > > > @@ -629,7 +634,6 @@ static void __init ms_hyperv_init_platform(void) > > > > * is called. > > > > */ > > > > wrmsrq(HV_X64_MSR_TSC_INVARIANT_CONTROL, > > > > HV_EXPOSE_INVARIANT_TSC); > > > > - setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); > > > > } > > > > > > If a Hyper-V VM exposes an invariant TSC but lacks the frequency MSRs, > > > does it bypass the tsc_register_calibration_routines() block entirely? > > > > Yes. > > > > > Without the standalone setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE) call > > > here, it looks like these VMs will lose the reliable flag. > > > > > > Will this inadvertently enable the TSC watchdog, potentially causing a > > > performance regression if the system falsely marks the TSC as unstable due > > > to virtualization scheduling delays? > > > > Hmm, I was going to say that the change was intentional and desriable, but > > looking > > at this yet again, I don't think that's true. Enabling > > HV_EXPOSE_INVARIANT_TSC > > just means the kernel will (probably) set X86_FEATURE_CONSTANT_TSC and > > X86_FEATURE_NONSTOP_TSC during early_init_intel(), AFAICT it doesn't lead to > > X86_FEATURE_TSC_RELIABLE being set. And I think in this case, marking the > > TSC > > as reliable makes sense; even if the kernel doesn't user Hyper-V's > > calibration > > info, the host is still clearly telling the guest that the TSC is reliable. > > Yes, I agree. But I'm doubtful that such a combination ever occurs in > practice. > I've never seen an occurrence of a Hyper-V (even really old versions) guest > where the frequency MSRs are not available or are not accessible. The > Hyper-V spec allows for either condition, so we have the code to test the > flags. I've thought of the flags as always set, though I suppose one never > knows what the future holds. > > > > > Michael, does keeping the > > > > setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); > > > > but also passing TSC_FREQ_KNOWN_AND_RELIABLE to the calibration routine make > > sense? > > I don't see that it would break anything. But it seems a bit disjointed in > that HV_ACCESS_TSC_INVARIANT is tested in two places in > ms_hyperv_init_platform(). Does TSC_RELIABLE *need* to be passed to > tsc_register_calibration_routines() if later code in ms_hyperv_init_platform() > does setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE)?
Sort of? It's not strictly necessary, but passing in TSC_RELIABLE allows tsc_register_calibration_routines() to ensure it doesn't clobber a more robust calibration routine with a "lesser" routine. I.e. not passing TSC_RELIABLE in this case would trigger a false positive (and break Hyper-V). In other words, invoking setup_force_cpu_cap() is a (happy, desirable) side effect, not the primary goal. > In other words, I'm suggesting let tsc_register_calibration_routines() handle > the TSC_FREQ_KNOWN case since that's what the calibration routines are all > about. Leave the setting of X86_FEATURE_TSC_RELIABLE to the later code that > tests HV_ACCESS_TSC_INVARIANT, instead of duplicating the > setup_force_cpu_cap() operation. > > While combining FREQUENCY_KNOWN and RELIABLE into > tsc_register_calibration_routines() is convenient, the two > concepts turn out to be independent when looking strictly at > the Hyper-V spec and code written to follow that spec. > Combining them into the same function ends up being clumsy Yeah, it's a bit awkward for Hyper-V, but Hyper-V is definitely the odd one out here, in that it has an "out-of-band" feature that marks the TSC as reliable. All other PV features that trigger overrides of the calibration routines bundle the RELIABLE aspect with the feature itself.
