]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86/pmu: Implement Intel mediated PMU requirements and constraints
authorDapeng Mi <dapeng1.mi@linux.intel.com>
Sat, 6 Dec 2025 00:16:53 +0000 (16:16 -0800)
committerSean Christopherson <seanjc@google.com>
Thu, 8 Jan 2026 19:52:04 +0000 (11:52 -0800)
Implement Intel PMU requirements and constraints for mediated PMU support.
Require host PMU version 4+ so that PERF_GLOBAL_STATUS_SET can be used to
precisely load the guest's status value into hardware, and require full-
width writes so that KVM can precisely load guest counter values.

Disable PEBS and LBRs if mediated PMU support is enabled, as they won't be
supported in the initial implementation.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Co-developed-by: Mingwei Zhang <mizhang@google.com>
Signed-off-by: Mingwei Zhang <mizhang@google.com>
[sean: split to separate patch, add full-width writes dependency]
Tested-by: Xudong Hao <xudong.hao@intel.com>
Tested-by: Manali Shukla <manali.shukla@amd.com>
Link: https://patch.msgid.link/20251206001720.468579-18-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/vmx/capabilities.h
arch/x86/kvm/vmx/pmu_intel.c
arch/x86/kvm/vmx/vmx.c

index 02aadb9d730e79cfc5eb6fc79e4d00acfe49a3de..26302fd6dd9c91d2f605b52d8a62e85e317d07a3 100644 (file)
@@ -395,7 +395,8 @@ static inline bool vmx_pt_mode_is_host_guest(void)
 
 static inline bool vmx_pebs_supported(void)
 {
-       return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept;
+       return boot_cpu_has(X86_FEATURE_PEBS) && kvm_pmu_cap.pebs_ept &&
+              !enable_mediated_pmu;
 }
 
 static inline bool cpu_has_notify_vmexit(void)
index de1d9785c01ff9359b36b9f83b624e21e98f75c0..050c21298213013f509ac396fd5329dfe8f628fb 100644 (file)
@@ -767,6 +767,20 @@ void intel_pmu_cross_mapped_check(struct kvm_pmu *pmu)
        }
 }
 
+static bool intel_pmu_is_mediated_pmu_supported(struct x86_pmu_capability *host_pmu)
+{
+       u64 host_perf_cap = 0;
+
+       if (boot_cpu_has(X86_FEATURE_PDCM))
+               rdmsrq(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
+
+       /*
+        * Require v4+ for MSR_CORE_PERF_GLOBAL_STATUS_SET, and full-width
+        * writes so that KVM can precisely load guest counter values.
+        */
+       return host_pmu->version >= 4 && host_perf_cap & PERF_CAP_FW_WRITES;
+}
+
 struct kvm_pmu_ops intel_pmu_ops __initdata = {
        .rdpmc_ecx_to_pmc = intel_rdpmc_ecx_to_pmc,
        .msr_idx_to_pmc = intel_msr_idx_to_pmc,
@@ -778,6 +792,9 @@ struct kvm_pmu_ops intel_pmu_ops __initdata = {
        .reset = intel_pmu_reset,
        .deliver_pmi = intel_pmu_deliver_pmi,
        .cleanup = intel_pmu_cleanup,
+
+       .is_mediated_pmu_supported = intel_pmu_is_mediated_pmu_supported,
+
        .EVENTSEL_EVENT = ARCH_PERFMON_EVENTSEL_EVENT,
        .MAX_NR_GP_COUNTERS = KVM_MAX_NR_INTEL_GP_COUNTERS,
        .MIN_NR_GP_COUNTERS = 1,
index 4cbe8c84b6366092be1bc3b2692204c988620a73..fdd18ad1ede3759742659ccff472102bd52ae7f4 100644 (file)
@@ -7958,7 +7958,8 @@ static __init u64 vmx_get_perf_capabilities(void)
        if (boot_cpu_has(X86_FEATURE_PDCM))
                rdmsrq(MSR_IA32_PERF_CAPABILITIES, host_perf_cap);
 
-       if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR)) {
+       if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR) &&
+           !enable_mediated_pmu) {
                x86_perf_get_lbr(&vmx_lbr_caps);
 
                /*