KVM: x86: Reject userspace attempts to access PERF_CAPABILITIES w/o PDCM
authorSean Christopherson <seanjc@google.com>
Fri, 2 Aug 2024 18:55:06 +0000 (11:55 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 1 Nov 2024 16:22:32 +0000 (09:22 -0700)
Reject userspace accesses to PERF_CAPABILITIES if PDCM isn't set in guest
CPUID, i.e. if the vCPU doesn't actually have PERF_CAPABILITIES.  But!  Do
so via KVM_MSR_RET_UNSUPPORTED, so that reads get '0' and writes of '0'
are ignored if KVM advertised support PERF_CAPABILITIES.

KVM's ABI is that userspace must set guest CPUID prior to setting MSRs,
and that setting MSRs that aren't supposed exist is disallowed (modulo the
'0' exemption).

Link: https://lore.kernel.org/r/20240802185511.305849-5-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/x86.c

index 34a7359d2bf385882577633217314f1bbbae0f55..c2802272871db0e9f1c57c0e6ac5003551d7ce13 100644 (file)
@@ -3800,8 +3800,10 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                vcpu->arch.arch_capabilities = data;
                break;
        case MSR_IA32_PERF_CAPABILITIES:
-               if (!msr_info->host_initiated)
-                       return 1;
+               if (!msr_info->host_initiated ||
+                   !guest_cpuid_has(vcpu, X86_FEATURE_PDCM))
+                       return KVM_MSR_RET_UNSUPPORTED;
+
                if (data & ~kvm_caps.supported_perf_cap)
                        return 1;
 
@@ -4260,9 +4262,8 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                msr_info->data = vcpu->arch.arch_capabilities;
                break;
        case MSR_IA32_PERF_CAPABILITIES:
-               if (!msr_info->host_initiated &&
-                   !guest_cpuid_has(vcpu, X86_FEATURE_PDCM))
-                       return 1;
+               if (!guest_cpuid_has(vcpu, X86_FEATURE_PDCM))
+                       return KVM_MSR_RET_UNSUPPORTED;
                msr_info->data = vcpu->arch.perf_capabilities;
                break;
        case MSR_IA32_POWER_CTL: