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.

Reply via email to