On Mon, Jun 08, 2026, David Woodhouse wrote:
> From: David Woodhouse <[email protected]>
>
> KVM does make an attempt to cope with non-constant TSC, and has
> notifiers to handle host TSC frequency changes. However, it *only*
> adjusts the KVM clock, and doesn't adjust TSC frequency scaling when
> the host changes.
>
> This is presumably because non-constant TSCs were fixed in hardware
> long before TSC scaling was implemented, so there should never be real
> CPUs which have TSC scaling but *not* CONSTANT_TSC.
>
> Such a combination could potentially happen in some odd L1 nesting
> environment, but it isn't worth trying to support it. Just make the
> dependency explicit.
>
> Signed-off-by: David Woodhouse <[email protected]>
> Reviewed-by: Paul Durrant <[email protected]>
> ---
> arch/x86/kvm/svm/svm.c | 3 ++-
> arch/x86/kvm/vmx/vmx.c | 2 +-
> 2 files changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index e7fdd7a9c280..7817752533fe 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -5546,7 +5546,8 @@ static __init int svm_hardware_setup(void)
> XFEATURE_MASK_BNDCSR);
>
> if (tsc_scaling) {
> - if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
> + if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR) ||
> + !boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) {
> tsc_scaling = false;
> } else {
> pr_info("TSC scaling supported\n");
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index a29896a9ef14..ed207cc7692d 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -8672,7 +8672,7 @@ __init int vmx_hardware_setup(void)
> if (!enable_apicv || !cpu_has_vmx_ipiv())
> enable_ipiv = false;
>
> - if (cpu_has_vmx_tsc_scaling())
> + if (cpu_has_vmx_tsc_scaling() && boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
We should clear SECONDARY_EXEC_TSC_SCALING in setup_vmcs_config(). Failure to
clear the vmcs_config bit will advertise the feature to L2 and allow it to be
enabled in vmcs12, but KVM will ultimately not honor the scaling in vmcs02:
if (kvm_caps.has_tsc_control)
vmcs_write64(TSC_MULTIPLIER, vcpu->arch.tsc_scaling_ratio);
This series kinda sorta gets there with "KVM: x86: Remove pvclock_gtod_data and
private timekeeping code", but that change looks misplaced? And I think
clearing
the bit this late will lead to false failures in vmx_check_processor_compat()
due
to the golden config clearing the bit, but the local config having it set.
> kvm_caps.has_tsc_control = true;
>
> kvm_caps.max_tsc_scaling_ratio = KVM_VMX_TSC_MULTIPLIER_MAX;
> --
> 2.54.0
>