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 | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index e02a38da5296..c46a34aeb3df 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -5557,7 +5557,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 b9103de01428..54e92d94155e 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -2792,6 +2792,16 @@ static int setup_vmcs_config(struct vmcs_config 
*vmcs_conf,
        if (!cpu_has_sgx())
                _cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_ENCLS_EXITING;
 
+       /*
+        * KVM doesn't re-derive the TSC scaling ratio when the host TSC
+        * frequency changes, so TSC scaling is only usable with a constant
+        * TSC.  Clear the control here rather than in vmx_hardware_setup() so
+        * that the per-CPU configs recomputed by vmx_check_processor_compat()
+        * stay consistent with the golden vmcs_config.
+        */
+       if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
+               _cpu_based_2nd_exec_control &= ~SECONDARY_EXEC_TSC_SCALING;
+
        if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_TERTIARY_CONTROLS)
                _cpu_based_3rd_exec_control =
                        
adjust_vmx_controls64(KVM_OPTIONAL_VMX_TERTIARY_VM_EXEC_CONTROL,
-- 
2.54.0


Reply via email to