Andrea Parri <parri.andrea@xxxxxxxxx> writes: > If the hardware supports TSC scaling, Hyper-V will set bit 15 of the > HV_PARTITION_PRIVILEGE_MASK in guest VMs with a compatible Hyper-V > configuration version. Bit 15 corresponds to the > AccessTscInvariantControls privilege. If this privilege bit is set, > guests can access the HvSyntheticInvariantTscControl MSR: guests can > set bit 0 of this synthetic MSR to enable the InvariantTSC feature. > After setting the synthetic MSR, CPUID will enumerate support for > InvariantTSC. I tried getting more information from TLFS but as of 5.0C this feature is not described there. I'm really interested in why this additional interface is needed, e.g. why can't Hyper-V just set InvariantTSC unconditionally when TSC scaling is supported? > > Signed-off-by: Andrea Parri <parri.andrea@xxxxxxxxx> > --- > arch/x86/include/asm/hyperv-tlfs.h | 5 +++++ > arch/x86/kernel/cpu/mshyperv.c | 7 ++++++- > 2 files changed, 11 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h > index 7741e211f7f51..5f10f7f2098db 100644 > --- a/arch/x86/include/asm/hyperv-tlfs.h > +++ b/arch/x86/include/asm/hyperv-tlfs.h > @@ -86,6 +86,8 @@ > #define HV_X64_ACCESS_FREQUENCY_MSRS BIT(11) > /* AccessReenlightenmentControls privilege */ > #define HV_X64_ACCESS_REENLIGHTENMENT BIT(13) > +/* AccessTscInvariantControls privilege */ > +#define HV_X64_ACCESS_TSC_INVARIANT BIT(15) > > /* > * Feature identification: indicates which flags were specified at partition > @@ -278,6 +280,9 @@ > #define HV_X64_MSR_TSC_EMULATION_CONTROL 0x40000107 > #define HV_X64_MSR_TSC_EMULATION_STATUS 0x40000108 > > +/* TSC invariant control */ > +#define HV_X64_MSR_TSC_INVARIANT_CONTROL 0x40000118 > + > /* > * Declare the MSR used to setup pages used to communicate with the hypervisor. > */ > diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c > index 267daad8c0360..105844d542e5c 100644 > --- a/arch/x86/kernel/cpu/mshyperv.c > +++ b/arch/x86/kernel/cpu/mshyperv.c > @@ -286,7 +286,12 @@ static void __init ms_hyperv_init_platform(void) > machine_ops.shutdown = hv_machine_shutdown; > machine_ops.crash_shutdown = hv_machine_crash_shutdown; > #endif > - mark_tsc_unstable("running on Hyper-V"); > + if (ms_hyperv.features & HV_X64_ACCESS_TSC_INVARIANT) { > + wrmsrl(HV_X64_MSR_TSC_INVARIANT_CONTROL, 0x1); > + setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE); > + } else { > + mark_tsc_unstable("running on Hyper-V"); > + } > > /* > * Generation 2 instances don't support reading the NMI status from -- Vitaly