[Patch v5 06/18] perf/x86/amd: Avoid re-enabling PMU and LBR for BPF when disabled
From: Dapeng Mi
Date: Thu Oct 29 2026 - 00:51:34 EST
amd_pmu_v2_snapshot_branch_stack() currently re-enables the PMU and LBR
unconditionally even when they were already disabled in PMI context
This can cause events such as cycles and instructions to be counted
while the PMI handler is running, which is not intended.
Only restore the PMU and LBR on the BPF path if they were originally
enabled.
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Closes: https://lore.kernel.org/all/sashiko-outbox-179823@xxxxxxxxxx/
Fixes: a4d18112e531 ("perf/x86/amd: Support capturing LBR from software events")
Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
---
arch/x86/events/amd/core.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
index bf631f60757c..851d8a938f52 100644
--- a/arch/x86/events/amd/core.c
+++ b/arch/x86/events/amd/core.c
@@ -932,22 +932,28 @@ static int amd_pmu_v2_snapshot_branch_stack(struct perf_branch_entry *entries, u
{
struct cpu_hw_events *cpuc;
unsigned long flags;
+ int pmu_enabled;
+ int lbr_enabled;
/*
* The sequence of steps to freeze LBR should be completely inlined
* and contain no branches to minimize contamination of LBR snapshot
*/
local_irq_save(flags);
+ cpuc = this_cpu_ptr(&cpu_hw_events);
+ pmu_enabled = cpuc->enabled;
+ lbr_enabled = cpuc->lbr_enabled;
amd_pmu_core_disable_all();
__amd_pmu_lbr_disable();
- cpuc = this_cpu_ptr(&cpu_hw_events);
-
amd_pmu_lbr_read();
cnt = min(cnt, cpuc->lbr_stack.nr);
memcpy(entries, cpuc->lbr_entries, sizeof(struct perf_branch_entry) * cnt);
- amd_pmu_v2_enable_all(0);
+ if (lbr_enabled)
+ amd_pmu_lbr_enable_all();
+ if (pmu_enabled)
+ amd_pmu_core_enable_all();
local_irq_restore(flags);
return cnt;
--
2.34.1