]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86/pmu: Bypass perf checks when emulating mediated PMU counter accesses
authorDapeng Mi <dapeng1.mi@linux.intel.com>
Sat, 6 Dec 2025 00:16:59 +0000 (16:16 -0800)
committerSean Christopherson <seanjc@google.com>
Thu, 8 Jan 2026 19:52:08 +0000 (11:52 -0800)
When emulating a PMC counter read or write for a mediated PMU, bypass the
perf checks and emulated_counter logic as the counters aren't proxied
through perf, i.e. pmc->counter always holds the guest's up-to-date value,
and thus there's no need to defer emulated overflow checks.

Suggested-by: Sean Christopherson <seanjc@google.com>
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 from event filtering change, write shortlog+changelog]
Reviewed-by: Sandipan Das <sandipan.das@amd.com>
Tested-by: Xudong Hao <xudong.hao@intel.com>
Tested-by: Manali Shukla <manali.shukla@amd.com>
Link: https://patch.msgid.link/20251206001720.468579-24-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/pmu.c
arch/x86/kvm/pmu.h

index 3e048c170b975210245e598d18613fe905fab5d5..3a901587ca6b0879a179eb2ddeec21db479ce008 100644 (file)
@@ -379,6 +379,11 @@ static void pmc_update_sample_period(struct kvm_pmc *pmc)
 
 void pmc_write_counter(struct kvm_pmc *pmc, u64 val)
 {
+       if (kvm_vcpu_has_mediated_pmu(pmc->vcpu)) {
+               pmc->counter = val & pmc_bitmask(pmc);
+               return;
+       }
+
        /*
         * Drop any unconsumed accumulated counts, the WRMSR is a write, not a
         * read-modify-write.  Adjust the counter value so that its value is
index 356b08e92bc952685b5bf040de9733d3b150ed48..9a199109d6729760564d012fdd737299ef029e3e 100644 (file)
@@ -111,6 +111,9 @@ static inline u64 pmc_read_counter(struct kvm_pmc *pmc)
 {
        u64 counter, enabled, running;
 
+       if (kvm_vcpu_has_mediated_pmu(pmc->vcpu))
+               return pmc->counter & pmc_bitmask(pmc);
+
        counter = pmc->counter + pmc->emulated_counter;
 
        if (pmc->perf_event && !pmc->is_paused)