On Tue, Aug 12, 2025 at 07:48:45PM +0000, Wei Liu wrote: > The HV_ACCESS_TSC_INVARIANT bit is always zero when Linux runs as the > root partition. The root partition will see directly what the hardware > provides. > > The old logic in ms_hyperv_init_platform caused the native TSC clock > source to be incorrectly marked as unstable on x86. Fix it. > > Skip the unnecessary checks in code for the root partition. Add one > extra comment in code to clarify the behavior. > > Signed-off-by: Wei Liu <wei....@kernel.org> > --- > v2: update the commit message and comments > --- > arch/x86/kernel/cpu/mshyperv.c | 11 ++++++++++- > drivers/clocksource/hyperv_timer.c | 10 +++++++++- > 2 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c > index c78f860419d6..25773af116bc 100644 > --- a/arch/x86/kernel/cpu/mshyperv.c > +++ b/arch/x86/kernel/cpu/mshyperv.c > @@ -565,6 +565,11 @@ static void __init ms_hyperv_init_platform(void) > machine_ops.crash_shutdown = hv_machine_crash_shutdown; > #endif > #endif > + /* > + * HV_ACCESS_TSC_INVARIANT is always zero for the root partition. Root > + * partition doesn't need to write to synthetic MSR to enable invariant > + * TSC feature. It sees what the hardware provides. > + */ > if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { > /* > * Writing to synthetic MSR 0x40000118 updates/changes the > @@ -636,8 +641,12 @@ static void __init ms_hyperv_init_platform(void) > * TSC should be marked as unstable only after Hyper-V > * clocksource has been initialized. This ensures that the > * stability of the sched_clock is not altered. > + * > + * HV_ACCESS_TSC_INVARIANT is always zero for the root partition. No > + * need to check for it. > */ > - if (!(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)) > + if (!hv_root_partition() && > + !(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT)) > mark_tsc_unstable("running on Hyper-V"); > > hardlockup_detector_disable(); > diff --git a/drivers/clocksource/hyperv_timer.c > b/drivers/clocksource/hyperv_timer.c > index 2edc13ca184e..ca39044a4a60 100644 > --- a/drivers/clocksource/hyperv_timer.c > +++ b/drivers/clocksource/hyperv_timer.c > @@ -549,14 +549,22 @@ static void __init hv_init_tsc_clocksource(void) > union hv_reference_tsc_msr tsc_msr; > > /* > + * When running as a guest partition: > + * > * If Hyper-V offers TSC_INVARIANT, then the virtualized TSC correctly > * handles frequency and offset changes due to live migration, > * pause/resume, and other VM management operations. So lower the > * Hyper-V Reference TSC rating, causing the generic TSC to be used. > * TSC_INVARIANT is not offered on ARM64, so the Hyper-V Reference > * TSC will be preferred over the virtualized ARM64 arch counter. > + * > + * When running as the root partition: > + * > + * There is no HV_ACCESS_TSC_INVARIANT feature. Skip the unnecessary > + * check.
This comment needs to be changed. * There is no HV_ACCESS_TSC_INVARIANT feature. Always lower the * rating of the Hyper-V Reference TSC. > */ > - if (ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) { > + if ((ms_hyperv.features & HV_ACCESS_TSC_INVARIANT) || > + hv_root_partition()) { > hyperv_cs_tsc.rating = 250; > hyperv_cs_msr.rating = 245; > } > -- > 2.43.0 >