From: Sean Christopherson <[email protected]> Sent: Wednesday, May 20, 2026 
9:41 AM
> 
> 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.

Indeed, Hyper-V is definitely the odd one here. Keeping the
"setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE)" in the later code
block where HV_ACCESS_TSC_INVARIANT is tested works well enough.
In the real world, the frequency MSRs are available and accessible,
so the additional "setup_force_cpu_cap()" is duplicative, but doesn't
hurt anything.

Michael

Reply via email to