KVM: nSVM: Use KVM-governed feature framework to track "TSC scaling enabled"
authorSean Christopherson <seanjc@google.com>
Tue, 15 Aug 2023 20:36:47 +0000 (13:36 -0700)
committerSean Christopherson <seanjc@google.com>
Thu, 17 Aug 2023 18:43:28 +0000 (11:43 -0700)
Track "TSC scaling exposed to L1" via a governed feature flag instead of
using a dedicated bit/flag in vcpu_svm.

Note, this fixes a benign bug where KVM would mark TSC scaling as exposed
to L1 even if overall nested SVM supported is disabled, i.e. KVM would let
L1 write MSR_AMD64_TSC_RATIO even when KVM didn't advertise TSCRATEMSR
support to userspace.

Reviewed-by: Yuan Yao <yuan.yao@intel.com>
Link: https://lore.kernel.org/r/20230815203653.519297-10-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/governed_features.h
arch/x86/kvm/svm/nested.c
arch/x86/kvm/svm/svm.c
arch/x86/kvm/svm/svm.h

index 722b66a..32c0469 100644 (file)
@@ -9,6 +9,7 @@ KVM_GOVERNED_X86_FEATURE(GBPAGES)
 KVM_GOVERNED_X86_FEATURE(XSAVES)
 KVM_GOVERNED_X86_FEATURE(VMX)
 KVM_GOVERNED_X86_FEATURE(NRIPS)
+KVM_GOVERNED_X86_FEATURE(TSCRATEMSR)
 
 #undef KVM_GOVERNED_X86_FEATURE
 #undef KVM_GOVERNED_FEATURE
index 9092f3f..da65948 100644 (file)
@@ -695,7 +695,7 @@ static void nested_vmcb02_prepare_control(struct vcpu_svm *svm,
 
        vmcb02->control.tsc_offset = vcpu->arch.tsc_offset;
 
-       if (svm->tsc_scaling_enabled &&
+       if (guest_can_use(vcpu, X86_FEATURE_TSCRATEMSR) &&
            svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio)
                nested_svm_update_tsc_ratio_msr(vcpu);
 
index de69e98..0d5cca0 100644 (file)
@@ -2795,7 +2795,8 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
        switch (msr_info->index) {
        case MSR_AMD64_TSC_RATIO:
-               if (!msr_info->host_initiated && !svm->tsc_scaling_enabled)
+               if (!msr_info->host_initiated &&
+                   !guest_can_use(vcpu, X86_FEATURE_TSCRATEMSR))
                        return 1;
                msr_info->data = svm->tsc_ratio_msr;
                break;
@@ -2937,7 +2938,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
        switch (ecx) {
        case MSR_AMD64_TSC_RATIO:
 
-               if (!svm->tsc_scaling_enabled) {
+               if (!guest_can_use(vcpu, X86_FEATURE_TSCRATEMSR)) {
 
                        if (!msr->host_initiated)
                                return 1;
@@ -2959,7 +2960,8 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
 
                svm->tsc_ratio_msr = data;
 
-               if (svm->tsc_scaling_enabled && is_guest_mode(vcpu))
+               if (guest_can_use(vcpu, X86_FEATURE_TSCRATEMSR) &&
+                   is_guest_mode(vcpu))
                        nested_svm_update_tsc_ratio_msr(vcpu);
 
                break;
@@ -4260,8 +4262,8 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
                kvm_governed_feature_set(vcpu, X86_FEATURE_XSAVES);
 
        kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_NRIPS);
+       kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_TSCRATEMSR);
 
-       svm->tsc_scaling_enabled = tsc_scaling && guest_cpuid_has(vcpu, X86_FEATURE_TSCRATEMSR);
        svm->lbrv_enabled = lbrv && guest_cpuid_has(vcpu, X86_FEATURE_LBRV);
 
        svm->v_vmload_vmsave_enabled = vls && guest_cpuid_has(vcpu, X86_FEATURE_V_VMSAVE_VMLOAD);
index c06de55..4e7332f 100644 (file)
@@ -259,7 +259,6 @@ struct vcpu_svm {
        bool soft_int_injected;
 
        /* optional nested SVM features that are enabled for this guest  */
-       bool tsc_scaling_enabled          : 1;
        bool v_vmload_vmsave_enabled      : 1;
        bool lbrv_enabled                 : 1;
        bool pause_filter_enabled         : 1;