]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: VMX: Extract checking of guest's DEBUGCTL into helper
authorSean Christopherson <seanjc@google.com>
Tue, 10 Jun 2025 23:20:07 +0000 (16:20 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:05:22 +0000 (13:05 -0700)
Move VMX's logic to check DEBUGCTL values into a standalone helper so that
the code can be used by nested VM-Enter to apply the same logic to the
value being loaded from vmcs12.

KVM needs to explicitly check vmcs12->guest_ia32_debugctl on nested
VM-Enter, as hardware may support features that KVM does not, i.e. relying
on hardware to detect invalid guest state will result in false negatives.
Unfortunately, that means applying KVM's funky suppression of BTF and LBR
to vmcs12 so as not to break existing guests.

No functional change intended.

Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://lore.kernel.org/r/20250610232010.162191-6-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/vmx/vmx.c

index 311f6fa53b679f5d7e2be4b0c2e5288fc9902844..4f827a75d9805c208ce1c3ecbf2139e929717bc6 100644 (file)
@@ -2193,6 +2193,19 @@ static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated
        return debugctl;
 }
 
+static bool vmx_is_valid_debugctl(struct kvm_vcpu *vcpu, u64 data,
+                                 bool host_initiated)
+{
+       u64 invalid;
+
+       invalid = data & ~vmx_get_supported_debugctl(vcpu, host_initiated);
+       if (invalid & (DEBUGCTLMSR_BTF | DEBUGCTLMSR_LBR)) {
+               kvm_pr_unimpl_wrmsr(vcpu, MSR_IA32_DEBUGCTLMSR, data);
+               invalid &= ~(DEBUGCTLMSR_BTF | DEBUGCTLMSR_LBR);
+       }
+       return !invalid;
+}
+
 /*
  * Writes msr value into the appropriate "register".
  * Returns 0 on success, non-0 otherwise.
@@ -2261,19 +2274,12 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                }
                vmcs_writel(GUEST_SYSENTER_ESP, data);
                break;
-       case MSR_IA32_DEBUGCTLMSR: {
-               u64 invalid;
-
-               invalid = data & ~vmx_get_supported_debugctl(vcpu, msr_info->host_initiated);
-               if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) {
-                       kvm_pr_unimpl_wrmsr(vcpu, msr_index, data);
-                       data &= ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR);
-                       invalid &= ~(DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR);
-               }
-
-               if (invalid)
+       case MSR_IA32_DEBUGCTLMSR:
+               if (!vmx_is_valid_debugctl(vcpu, data, msr_info->host_initiated))
                        return 1;
 
+               data &= vmx_get_supported_debugctl(vcpu, msr_info->host_initiated);
+
                if (is_guest_mode(vcpu) && get_vmcs12(vcpu)->vm_exit_controls &
                                                VM_EXIT_SAVE_DEBUG_CONTROLS)
                        get_vmcs12(vcpu)->guest_ia32_debugctl = data;
@@ -2283,7 +2289,6 @@ int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                    (data & DEBUGCTLMSR_LBR))
                        intel_pmu_create_guest_lbr_event(vcpu);
                return 0;
-       }
        case MSR_IA32_BNDCFGS:
                if (!kvm_mpx_supported() ||
                    (!msr_info->host_initiated &&