On Fri, Sep 16, 2022, Vitaly Kuznetsov wrote: > Normally, genuine Hyper-V doesn't expose architectural invariant TSC > (CPUID.80000007H:EDX[8]) to its guests by default. A special PV MSR > (HV_X64_MSR_TSC_INVARIANT_CONTROL, 0x40000118) and corresponding CPUID > feature bit (CPUID.0x40000003.EAX[15]) were introduced. When bit 0 of the > PV MSR is set, invariant TSC bit starts to show up in CPUID. When the > feature is exposed to Hyper-V guests, reenlightenment becomes unneeded. > > Add the feature to KVM. Keep CPUID output intact when the feature > wasn't exposed to L1 and implement the required logic for hiding > invariant TSC when the feature was exposed and invariant TSC control > MSR wasn't written to. Copy genuine Hyper-V behavior and forbid to > disable the feature once it was enabled. ... > diff --git a/arch/x86/kvm/hyperv.h b/arch/x86/kvm/hyperv.h > index da2737f2a956..8be6dc3d76af 100644 > --- a/arch/x86/kvm/hyperv.h > +++ b/arch/x86/kvm/hyperv.h > @@ -133,6 +133,21 @@ static inline bool kvm_hv_has_stimer_pending(struct kvm_vcpu *vcpu) > HV_SYNIC_STIMER_COUNT); > } > > +/* > + * With HV_ACCESS_TSC_INVARIANT feature, invariant TSC (CPUID.80000007H:EDX[8]) > + * is only observed after HV_X64_MSR_TSC_INVARIANT_CONTROL was written to. > + */ > +static inline bool kvm_hv_invtsc_suppressed(struct kvm_vcpu *vcpu) > +{ > + struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); > + > + if (!hv_vcpu) > + return false; > + > + return (hv_vcpu->cpuid_cache.features_eax & HV_ACCESS_TSC_INVARIANT) && > + !(to_kvm_hv(vcpu->kvm)->hv_invtsc_control & HV_INVARIANT_TSC_EXPOSED); It's still not obvious to me why KVM shouldn't do: if (!hv_vcpu) return false; return !(hv_vcpu->cpuid_cache.features_eax & HV_ACCESS_TSC_INVARIANT) || !(to_kvm_hv(vcpu->kvm)->hv_invtsc_control & HV_INVARIANT_TSC_EXPOSED); I.e. why is invariant TSC _not_ suppressed on Hyper-V by default?