]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86/pmu: Introduce eventsel_hw to prepare for pmu event filtering
authorMingwei Zhang <mizhang@google.com>
Sat, 6 Dec 2025 00:17:00 +0000 (16:17 -0800)
committerSean Christopherson <seanjc@google.com>
Thu, 8 Jan 2026 19:52:09 +0000 (11:52 -0800)
Introduce eventsel_hw and fixed_ctr_ctrl_hw to store the actual HW value in
PMU event selector MSRs. In mediated PMU checks events before allowing the
event values written to the PMU MSRs. However, to match the HW behavior,
when PMU event checks fails, KVM should allow guest to read the value back.

This essentially requires an extra variable to separate the guest requested
value from actual PMU MSR value. Note this only applies to event selectors.

Signed-off-by: Mingwei Zhang <mizhang@google.com>
Co-developed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Tested-by: Xudong Hao <xudong.hao@intel.com>
Tested-by: Manali Shukla <manali.shukla@amd.com>
Link: https://patch.msgid.link/20251206001720.468579-25-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/pmu.c
arch/x86/kvm/svm/pmu.c
arch/x86/kvm/vmx/pmu_intel.c

index defd979003beb5a2dc13ddb907276e44a0dbfc18..e72357f64b19b3f8f3eb475c7b9fe86f3a16b3b0 100644 (file)
@@ -529,6 +529,7 @@ struct kvm_pmc {
         */
        u64 emulated_counter;
        u64 eventsel;
+       u64 eventsel_hw;
        struct perf_event *perf_event;
        struct kvm_vcpu *vcpu;
        /*
@@ -557,6 +558,7 @@ struct kvm_pmu {
        unsigned nr_arch_fixed_counters;
        unsigned available_event_types;
        u64 fixed_ctr_ctrl;
+       u64 fixed_ctr_ctrl_hw;
        u64 fixed_ctr_ctrl_rsvd;
        u64 global_ctrl;
        u64 global_status;
index 3a901587ca6b0879a179eb2ddeec21db479ce008..a05366e4eef2dab1acb0e6ee165e29271985050c 100644 (file)
@@ -900,11 +900,14 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
                pmc->counter = 0;
                pmc->emulated_counter = 0;
 
-               if (pmc_is_gp(pmc))
+               if (pmc_is_gp(pmc)) {
                        pmc->eventsel = 0;
+                       pmc->eventsel_hw = 0;
+               }
        }
 
-       pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0;
+       pmu->fixed_ctr_ctrl = pmu->fixed_ctr_ctrl_hw = 0;
+       pmu->global_ctrl = pmu->global_status = 0;
 
        kvm_pmu_call(reset)(vcpu);
 }
index 16c88b2a2eb8809ff181ddd9f1a48aa7c30e6236..c1ec1962314ec2406eea767bb5a76cd8f29bf6f7 100644 (file)
@@ -166,6 +166,7 @@ static int amd_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                data &= ~pmu->reserved_bits;
                if (data != pmc->eventsel) {
                        pmc->eventsel = data;
+                       pmc->eventsel_hw = data;
                        kvm_pmu_request_counter_reprogram(pmc);
                }
                return 0;
index 820da47454d79116936c4a0d8e8a9f98a0457511..855240678300e26fbd15d9246c9be2229c42ca26 100644 (file)
@@ -61,6 +61,7 @@ static void reprogram_fixed_counters(struct kvm_pmu *pmu, u64 data)
        int i;
 
        pmu->fixed_ctr_ctrl = data;
+       pmu->fixed_ctr_ctrl_hw = data;
        for (i = 0; i < pmu->nr_arch_fixed_counters; i++) {
                u8 new_ctrl = fixed_ctrl_field(data, i);
                u8 old_ctrl = fixed_ctrl_field(old_fixed_ctr_ctrl, i);
@@ -430,6 +431,7 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 
                        if (data != pmc->eventsel) {
                                pmc->eventsel = data;
+                               pmc->eventsel_hw = data;
                                kvm_pmu_request_counter_reprogram(pmc);
                        }
                        break;