[Patch v6 17/20] perf/x86/intel: Clear raw LBR counters in the LBR stack
From: Dapeng Mi
Date: Thu Nov 05 2026 - 23:47:44 EST
Raw LBR counters are currently stored in the reserved fields of the LBR
stack even when no LBR event needs them.
If an LBR counter event is present, it clears the raw LBR counters while
processing the stack, but those counters can be leaked to userspace when
no LBR event requires them. Clear the raw LBR counters when no LBR event
uses them.
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Fixes: 33744916196b ("perf/x86/intel: Support branch counters logging")
Signed-off-by: Dapeng Mi <dapeng1.mi@xxxxxxxxxxxxxxx>
---
arch/x86/events/intel/core.c | 1 +
arch/x86/events/intel/lbr.c | 13 +++++++++++++
arch/x86/events/perf_event.h | 2 ++
3 files changed, 16 insertions(+)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index b267c68f9467..707bff285ed7 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2835,6 +2835,7 @@ __intel_pmu_snapshot_branch_stack(struct perf_branch_entry *entries,
(struct perf_branch_stack *)bpf->__lbr_stack;
intel_pmu_lbr_read(lbr_stack, bpf->counters);
+ intel_pmu_lbr_clear_counters(lbr_stack);
cnt = min_t(unsigned int, cnt, lbr_stack->nr);
memcpy(entries, lbr_stack->entries,
diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 3500cf3518f4..fbc053ebbeaf 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -987,6 +987,18 @@ static void intel_pmu_lbr_counters_reorder(struct cpu_hw_events *cpuc,
}
}
+void intel_pmu_lbr_clear_counters(struct perf_branch_stack *lbr_stack)
+{
+ int i;
+
+ if (!(x86_pmu.flags & PMU_FL_BR_CNTR))
+ return;
+
+ /* reserved field stores raw branch counters, clear it. */
+ for (i = 0; i < lbr_stack->nr; i++)
+ lbr_stack->entries[i].reserved = 0;
+}
+
void intel_pmu_lbr_save_brstack(struct perf_sample_data *data,
struct cpu_hw_events *cpuc,
struct perf_event *event)
@@ -997,6 +1009,7 @@ void intel_pmu_lbr_save_brstack(struct perf_sample_data *data,
return;
}
+ intel_pmu_lbr_clear_counters(cpu_lbr_stack(cpuc));
perf_sample_save_brstack(data, event, cpu_lbr_stack(cpuc), NULL);
}
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 0213e2a8efff..a4e53c99eaf5 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1984,6 +1984,8 @@ void intel_pmu_store_pebs_lbrs(struct lbr_entry *lbr);
void intel_pebs_init(void);
+void intel_pmu_lbr_clear_counters(struct perf_branch_stack *lbr_stack);
+
void intel_pmu_lbr_save_brstack(struct perf_sample_data *data,
struct cpu_hw_events *cpuc,
struct perf_event *event);
--
2.34.1