Linux Perf Users
 help / color / mirror / Atom feed
* [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes
@ 2026-06-12  9:01 Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Dapeng Mi
                   ` (7 more replies)
  0 siblings, 8 replies; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi

This series groups several independent PMU fixes to simplify review and
backporting.

Changes:
v2 -> v3:
- Patch 2/8: Directly update PERF_EVENT_FLAG_USER_READ_CNT according to
  rdpmc user disable state (Peter).
- Patch 3/8: Only keep x86_lbr_type check for the detection of hardware
  branch type decoding (Peter).
- Patch 4/8: Switch from_plm and to_plm variables order and refine
  comments (Peter).
- Patch 5/8: Move intel_pmu_arch_lbr_init() after model-specfic PMU
  initialization to avoid extra kmem cache destroy (Peter).
- Patch 6/8: Improve change log to add more details (Peter).

v1 -> v2:
- Fallback to software branch type decoding if hardware decoding is not
  suppprted (Sashiko patch 4/9).
- Drop kernel IP for PERF_SAMPLE_IP if exclude_kernel attribute is
  required (Sashiko, patch 8/9).
- Add kernel access check when kernel callchains are requested
  (Sashiko, patch 9/9)
- Address Zide and Thomas's comments.
- Collect Reviewed-bys.

Patch layout:
- Patch 1/8: Fix anythread_deprecated being overwritten issue. 
- Patch 2/8: Fix the issue that cap_user_rdpmc is not updated correctly.
- Patch 3/8: Fallback to software branch type decoding if no hardware
  decoding.
- Patch 4/8: Fix the kernel address leakage issue in LBR stack.
- Patch 5/8: Fix the issue that the return value of
  intel_pmu_init_hybrid() is not valiated correctly.
- Patch 6/8: Fix a "unchecked MSR access error" on PEBS_ENABLE MSR.
- Patch 7/8: Prevent a theoretical kernel register data leak in sampling.
- Patch 8/8: Add kernel access check when kernel callchains are
  requested. 

History:
v2: https://lore.kernel.org/all/20260609050222.2458129-1-dapeng1.mi@linux.intel.com/
v1: https://lore.kernel.org/all/20260605011136.2043393-1-dapeng1.mi@linux.intel.com/

Dapeng Mi (8):
  perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities
  perf/x86/intel: Keep cap_user_rdpmc in sync with RDPMC user-disable
    state
  perf/x86/intel: Fallback to sw branch type decoding if no hw decoding
  perf/x86/intel: Fix kernel address leakages in LBR stack
  perf/x86/intel: Validate the return value of intel_pmu_init_hybrid()
  perf/x86/intel: Drop fixed-counter PEBS constraints for baseline PEBS
  perf/core: Fix kernel register info leak via hardware skid
  perf/core: Check kernel access when kernel callchains are requested

 arch/x86/events/core.c       |  3 +-
 arch/x86/events/intel/core.c | 60 +++++++++++++++++++++---------------
 arch/x86/events/intel/ds.c   | 13 --------
 arch/x86/events/intel/lbr.c  | 14 ++++++---
 arch/x86/events/perf_event.h |  4 +--
 kernel/events/core.c         | 41 +++++++++++++++++++-----
 6 files changed, 83 insertions(+), 52 deletions(-)


base-commit: 67d27727854def4a7e2b386429941f5c4741ccc4
-- 
2.34.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:46   ` Peter Zijlstra
  2026-06-12  9:01 ` [Patch v3 2/8] perf/x86/intel: Keep cap_user_rdpmc in sync with RDPMC user-disable state Dapeng Mi
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi, stable

AnyThread mode deprecation is enumerated by CPUID.0AH:EDX[15] instead of
PERF_CAPABILITIES MSR. It's not a good practice to define a bit to
represent "anythread deprecation" in perf_capabilities. It leads to the
anythread_deprecated bit could be overwritten by the real value of
PERF_CAPABILITIES MSR, just like the below code in update_pmu_cap() does.

```
if (!intel_pmu_broken_perf_cap()) {
	/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
	rdmsrq(MSR_IA32_PERF_CAPABILITIES, hybrid(pmu, intel_cap).capabilities);
}
```

It leads to the anythread_deprecated bit is cleared to 0 and the "any"
attribute is incorrectly shown in the /sys/devices/cpu/format/ folder on
these support Perfmon v6 platforms, like Clearwater Forest.

```
$grep . /sys/devices/cpu/format/*
/sys/devices/cpu/format/acr_mask:config2:0-63
/sys/devices/cpu/format/any:config:21
/sys/devices/cpu/format/cmask:config:24-31
```

So remove the anythread_deprecated bit from perf_capabilities structure
and directly depends on CPUID.0AH:EDX[15] to judge if anythread is
deprecated.

Cc: stable@vger.kernel.org
Reported-by: Namhyung Kim <namhyung@kernel.org>
Fixes: cadbaa039b99 ("perf/x86/intel: Make anythread filter support conditional")
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Reviewed-by: Zide Chen <zide.chen@intel.com>
Reviewed-by: Thomas Falcon <thomas.falcon@intel.com>
---
 arch/x86/events/intel/core.c | 10 +++-------
 arch/x86/events/perf_event.h |  2 +-
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 0217e701aeeb..ea3ab3050a3b 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -7946,12 +7946,6 @@ __init int intel_pmu_init(void)
 
 	x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
 
-	if (version >= 5) {
-		x86_pmu.intel_cap.anythread_deprecated = edx.split.anythread_deprecated;
-		if (x86_pmu.intel_cap.anythread_deprecated)
-			pr_cont(" AnyThread deprecated, ");
-	}
-
 	/* The perf side of core PMU is ready to support the mediated vPMU. */
 	x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_MEDIATED_VPMU;
 
@@ -8828,8 +8822,10 @@ __init int intel_pmu_init(void)
 				      &x86_pmu.intel_ctrl);
 
 	/* AnyThread may be deprecated on arch perfmon v5 or later */
-	if (x86_pmu.intel_cap.anythread_deprecated)
+	if (version >= 5 && edx.split.anythread_deprecated) {
 		x86_pmu.format_attrs = intel_arch_formats_attr;
+		pr_cont("AnyThread deprecated, ");
+	}
 
 	intel_pmu_check_event_constraints_all(NULL);
 
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index eae24bb35dc1..5902a297daa1 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -668,7 +668,7 @@ union perf_capabilities {
 		u64	perf_metrics:1;
 		u64	pebs_output_pt_available:1;
 		u64	pebs_timing_info:1;
-		u64	anythread_deprecated:1;
+		u64	__reserved:1;
 		u64	rdpmc_metrics_clear:1;
 	};
 	u64	capabilities;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 2/8] perf/x86/intel: Keep cap_user_rdpmc in sync with RDPMC user-disable state
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 3/8] perf/x86/intel: Fallback to sw branch type decoding if no hw decoding Dapeng Mi
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi

After introducing the RDPMC user disable feature, user-space RDPMC may
return 0 instead of the actual event count. This creates an inconsistency
with cap_user_rdpmc, where cap_user_rdpmc is set, but user-space RDPMC
only returns 0.

To accurately represent the user-space RDPMC capability, update
cap_user_rdpmc (depending on PERF_EVENT_FLAG_USER_READ_CNT) according to
the RDPMC user disable state. If RDPMC user disable is enabled,
cap_user_rdpmc is updated to false eventually, allowing user-space
programs to fall back to the read() syscall to obtain the real event
count.

Because PERF_EVENT_FLAG_USER_READ_CNT is evaluated in
x86_pmu_event_init(), move intel_pmu_update_rdpmc_user_disable()
earlier into intel_pmu_hw_config(). This ensures that the user-disable
state is updated before updating PERF_EVENT_FLAG_USER_READ_CNT. Note that
since event->ctx is not yet assigned at this stage, use the
PERF_ATTACH_TASK flag to detect whether the event is task-attached.

While at it, fix the indentation of x86_pmu_has_rdpmc_user_disable()
to adhere to the kernel coding style.

Fixes: 59af95e028d4 ("perf/x86/intel: Add support for rdpmc user disable feature")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 arch/x86/events/core.c       | 3 ++-
 arch/x86/events/intel/core.c | 6 +++---
 arch/x86/events/perf_event.h | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 4b9e105309c6..a76a2afae2fb 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -2539,7 +2539,8 @@ static int x86_pmu_event_init(struct perf_event *event)
 	}
 
 	if (READ_ONCE(x86_pmu.attr_rdpmc) &&
-	    !(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS))
+	    !(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS) &&
+	    !(event->hw.config & ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE))
 		event->hw.flags |= PERF_EVENT_FLAG_USER_READ_CNT;
 
 	return err;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index ea3ab3050a3b..db52e7e53a6c 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3532,7 +3532,7 @@ static void intel_pmu_update_rdpmc_user_disable(struct perf_event *event)
 	 */
 	if (x86_pmu.attr_rdpmc == X86_USER_RDPMC_ALWAYS_ENABLE ||
 	    (x86_pmu.attr_rdpmc == X86_USER_RDPMC_CONDITIONAL_ENABLE &&
-	     event->ctx->task))
+	     (event->attach_state & PERF_ATTACH_TASK)))
 		event->hw.config &= ~ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE;
 	else
 		event->hw.config |= ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE;
@@ -3546,8 +3546,6 @@ static void intel_pmu_enable_event(struct perf_event *event)
 	struct hw_perf_event *hwc = &event->hw;
 	int idx = hwc->idx;
 
-	intel_pmu_update_rdpmc_user_disable(event);
-
 	if (unlikely(event->attr.precise_ip))
 		static_call(x86_pmu_pebs_enable)(event);
 
@@ -5146,6 +5144,8 @@ static int intel_pmu_hw_config(struct perf_event *event)
 		leader->hw.flags |= PERF_X86_EVENT_ACR;
 	}
 
+	intel_pmu_update_rdpmc_user_disable(event);
+
 	if ((event->attr.type == PERF_TYPE_HARDWARE) ||
 	    (event->attr.type == PERF_TYPE_HW_CACHE))
 		return 0;
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 5902a297daa1..a8afea8d38f0 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1344,7 +1344,7 @@ static inline u64 x86_pmu_get_event_config(struct perf_event *event)
 static inline bool x86_pmu_has_rdpmc_user_disable(struct pmu *pmu)
 {
 	return !!(hybrid(pmu, config_mask) &
-		 ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE);
+		  ARCH_PERFMON_EVENTSEL_RDPMC_USER_DISABLE);
 }
 
 extern struct event_constraint emptyconstraint;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 3/8] perf/x86/intel: Fallback to sw branch type decoding if no hw decoding
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 2/8] perf/x86/intel: Keep cap_user_rdpmc in sync with RDPMC user-disable state Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:21   ` sashiko-bot
  2026-06-12  9:01 ` [Patch v3 4/8] perf/x86/intel: Fix kernel address leakages in LBR stack Dapeng Mi
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi

intel_pmu_lbr_filter() currently assumes arch-LBR provides hardware
branch-type decoding and skips software decoding on that path.

However, arch-LBR may not always expose branch-type information. In
that case, treating entries as hardware-decoded can misclassify sampled
branches (for example, defaulting to JCC), which breaks branch-type
filtering results.

Fix this by using software branch-type decoding when hardware
branch-type decoding is unavailable (that is, when x86_lbr_type is not
enabled). This keeps branch classification and filtering behavior
correct across arch-LBR configurations.

Since x86_lbr_type is only set to true when arch-LBR is supported,
it's unnecessary to check if the CPU has the arch-LBR feature.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 arch/x86/events/intel/lbr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 72f2adcda7c6..e2657f791e50 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1231,7 +1231,7 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
 		 * Doesn't support OTHER_BRANCH decoding for now.
 		 * OTHER_BRANCH branch type still rely on software decoding.
 		 */
-		if (static_cpu_has(X86_FEATURE_ARCH_LBR) &&
+		if (static_branch_likely(&x86_lbr_type) &&
 		    type <= ARCH_LBR_BR_TYPE_KNOWN_MAX) {
 			to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
 			type = arch_lbr_br_type_map[type] | to_plm;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 4/8] perf/x86/intel: Fix kernel address leakages in LBR stack
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
                   ` (2 preceding siblings ...)
  2026-06-12  9:01 ` [Patch v3 3/8] perf/x86/intel: Fallback to sw branch type decoding if no hw decoding Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:18   ` sashiko-bot
  2026-06-12  9:01 ` [Patch v3 5/8] perf/x86/intel: Validate the return value of intel_pmu_init_hybrid() Dapeng Mi
                   ` (3 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi, stable

Before Arch LBR gained CPL filtering support, a user-only branch stack
could still contain kernel addresses. As a result, kernel branch records
may be exposed to user space even when PERF_SAMPLE_BRANCH_USER is
requested.

For example, on Intel Tiger Lake, the following command can still report
SYSRET/ERET entries with kernel-space from addresses:

```
$./perf record -e cycles:p -o - --branch-filter any,save_type,u -- \
 	./perf bench syscall basic --loop 1000 | \
	./perf script -i - --fields brstack|tr ' ' '\n'| \
	grep -E '0x[89a-f][0-9a-f]{15}'

    Total time: 0.000 [sec]

      0.219000 usecs/op
     4,566,210 ops/sec
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.551 MB - ]
0xffffffff93c001c8/0x7f12a2b1d647/P/-/-/16959/SYSRET/-
0xffffffff93c001c8/0x7f12a2b1d5c2/P/-/-/17535/SYSRET/-
0xffffffff93c01928/0x7f12a2861000/P/-/-/6719/ERET/-
0xffffffff93c01928/0x7f12a297a000/P/-/-/8575/ERET/-
```

The problem is that intel_pmu_lbr_filter() does not fully validate the
privilege level of sampled entries. It filters some mismatches based on
the branch type and the to address, but it does not reject entries whose
from address violates the requested branch privilege filter.

Fix this by extending software filtering to validate both from and to
addresses against br_sel. Any LBR entry contains kernel address does not
match the requested user filter is dropped. This prevents kernel
addresses from appearing in user-only branch stacks.

Cc: stable@vger.kernel.org
Reported-by: Ian Rogers <irogers@google.com>
Fixes: 47125db27e47 ("perf/x86/intel/lbr: Support Architectural LBR")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 arch/x86/events/intel/lbr.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index e2657f791e50..16eef1537816 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1212,7 +1212,7 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
 {
 	u64 from, to;
 	int br_sel = cpuc->br_sel;
-	int i, j, type, to_plm;
+	int i, j, type, from_plm, to_plm;
 	bool compress = false;
 
 	/* if sampling all branches, then nothing to filter */
@@ -1244,8 +1244,14 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
 				type |= X86_BR_NO_TX;
 		}
 
-		/* if type does not correspond, then discard */
-		if (type == X86_BR_NONE || (br_sel & type) != type) {
+		from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
+		/*
+		 * If type does not correspond, then discard.
+		 * Specifically reject entries whose from address is in
+		 * kernel space when only X86_BR_USER is requested.
+		 */
+		if (type == X86_BR_NONE || (br_sel & type) != type ||
+		    (!(br_sel & X86_BR_KERNEL) && (from_plm & X86_BR_KERNEL))) {
 			cpuc->lbr_entries[i].from = 0;
 			compress = true;
 		}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 5/8] perf/x86/intel: Validate the return value of intel_pmu_init_hybrid()
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
                   ` (3 preceding siblings ...)
  2026-06-12  9:01 ` [Patch v3 4/8] perf/x86/intel: Fix kernel address leakages in LBR stack Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:31   ` sashiko-bot
  2026-06-12  9:01 ` [Patch v3 6/8] perf/x86/intel: Drop fixed-counter PEBS constraints for baseline PEBS Dapeng Mi
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi

The intel_pmu_init_hybrid() function allocates memory for the
x86_pmu.hybrid_pmu[] array. If this allocation fails under memory
pressure, hybrid PMU initialization will fail.

Currently, the caller does not check the return value of
intel_pmu_init_hybrid(). This can lead to a null-pointer dereference or
invalid memory access when attempting to use the uninitialized array,
potentially triggering a system panic.

Fix this by validating the return value of intel_pmu_init_hybrid().
Additionally, reset x86_pmu.num_hybrid_pmus to 0 on failure, and defer
intel_pmu_arch_lbr_init() until after hybrid PMU initialization
succeeds. This reordering avoids the need to explicitly destroy the
kmem cache if the memory allocation fails.

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 arch/x86/events/intel/core.c | 44 ++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index db52e7e53a6c..74dbf24b0ab6 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -7678,8 +7678,10 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus)
 	x86_pmu.num_hybrid_pmus = hweight_long(pmus_mask);
 	x86_pmu.hybrid_pmu = kzalloc_objs(struct x86_hybrid_pmu,
 					  x86_pmu.num_hybrid_pmus);
-	if (!x86_pmu.hybrid_pmu)
+	if (!x86_pmu.hybrid_pmu) {
+		x86_pmu.num_hybrid_pmus = 0;
 		return -ENOMEM;
+	}
 
 	static_branch_enable(&perf_is_hybrid);
 	x86_pmu.filter = intel_pmu_filter;
@@ -7862,14 +7864,14 @@ __init int intel_pmu_init(void)
 	struct attribute **td_attr    = &empty_attrs;
 	struct attribute **mem_attr   = &empty_attrs;
 	struct attribute **tsx_attr   = &empty_attrs;
+	struct x86_hybrid_pmu *pmu;
+	unsigned int fixed_mask;
 	union cpuid10_edx edx;
 	union cpuid10_eax eax;
 	union cpuid10_ebx ebx;
-	unsigned int fixed_mask;
+	int version, i, ret;
 	bool pmem = false;
-	int version, i;
 	char *name;
-	struct x86_hybrid_pmu *pmu;
 
 	/* Architectural Perfmon was introduced starting with Core "Yonah" */
 	if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
@@ -7939,9 +7941,6 @@ __init int intel_pmu_init(void)
 		x86_pmu.lbr_read = intel_pmu_lbr_read_32;
 	}
 
-	if (boot_cpu_has(X86_FEATURE_ARCH_LBR))
-		intel_pmu_arch_lbr_init();
-
 	intel_pebs_init();
 
 	x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
@@ -8539,7 +8538,9 @@ __init int intel_pmu_init(void)
 		 *
 		 * Initialize the common PerfMon capabilities here.
 		 */
-		intel_pmu_init_hybrid(hybrid_big_small);
+		ret = intel_pmu_init_hybrid(hybrid_big_small);
+		if (ret)
+			return ret;
 
 		x86_pmu.pebs_latency_data = grt_latency_data;
 		x86_pmu.get_event_constraints = adl_get_event_constraints;
@@ -8597,7 +8598,9 @@ __init int intel_pmu_init(void)
 	case INTEL_METEORLAKE:
 	case INTEL_METEORLAKE_L:
 	case INTEL_ARROWLAKE_U:
-		intel_pmu_init_hybrid(hybrid_big_small);
+		ret = intel_pmu_init_hybrid(hybrid_big_small);
+		if (ret)
+			return ret;
 
 		x86_pmu.pebs_latency_data = cmt_latency_data;
 		x86_pmu.get_event_constraints = mtl_get_event_constraints;
@@ -8628,7 +8631,9 @@ __init int intel_pmu_init(void)
 		pr_cont("Pantherlake Hybrid events, ");
 		name = "pantherlake_hybrid";
 
-		intel_pmu_init_hybrid(hybrid_big_small);
+		ret = intel_pmu_init_hybrid(hybrid_big_small);
+		if (ret)
+			return ret;
 
 		/* Initialize big core specific PerfMon capabilities.*/
 		pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
@@ -8643,7 +8648,9 @@ __init int intel_pmu_init(void)
 		pr_cont("Arrowlake Hybrid events, ");
 		name = "arrowlake_hybrid";
 
-		intel_pmu_init_hybrid(hybrid_big_small);
+		ret = intel_pmu_init_hybrid(hybrid_big_small);
+		if (ret)
+			return ret;
 
 		/* Initialize big core specific PerfMon capabilities.*/
 		pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
@@ -8660,7 +8667,9 @@ __init int intel_pmu_init(void)
 		pr_cont("Lunarlake Hybrid events, ");
 		name = "lunarlake_hybrid";
 
-		intel_pmu_init_hybrid(hybrid_big_small);
+		ret = intel_pmu_init_hybrid(hybrid_big_small);
+		if (ret)
+			return ret;
 
 		/* Initialize big core specific PerfMon capabilities.*/
 		pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
@@ -8685,7 +8694,9 @@ __init int intel_pmu_init(void)
 		break;
 
 	case INTEL_ARROWLAKE_H:
-		intel_pmu_init_hybrid(hybrid_big_small_tiny);
+		ret = intel_pmu_init_hybrid(hybrid_big_small_tiny);
+		if (ret)
+			return ret;
 
 		x86_pmu.pebs_latency_data = arl_h_latency_data;
 		x86_pmu.get_event_constraints = arl_h_get_event_constraints;
@@ -8720,7 +8731,9 @@ __init int intel_pmu_init(void)
 	case INTEL_NOVALAKE_L:
 		pr_cont("Novalake Hybrid events, ");
 		name = "novalake_hybrid";
-		intel_pmu_init_hybrid(hybrid_big_small);
+		ret = intel_pmu_init_hybrid(hybrid_big_small);
+		if (ret)
+			return ret;
 
 		x86_pmu.pebs_latency_data = nvl_latency_data;
 		x86_pmu.get_event_constraints = mtl_get_event_constraints;
@@ -8829,6 +8842,9 @@ __init int intel_pmu_init(void)
 
 	intel_pmu_check_event_constraints_all(NULL);
 
+	if (boot_cpu_has(X86_FEATURE_ARCH_LBR))
+		intel_pmu_arch_lbr_init();
+
 	/*
 	 * Access LBR MSR may cause #GP under certain circumstances.
 	 * Check all LBR MSR here.
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 6/8] perf/x86/intel: Drop fixed-counter PEBS constraints for baseline PEBS
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
                   ` (4 preceding siblings ...)
  2026-06-12  9:01 ` [Patch v3 5/8] perf/x86/intel: Validate the return value of intel_pmu_init_hybrid() Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 7/8] perf/core: Fix kernel register info leak via hardware skid Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 8/8] perf/core: Check kernel access when kernel callchains are requested Dapeng Mi
  7 siblings, 0 replies; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi, Yi Lai

On Sapphire Rapids (SPR) guests where pebs_baseline is not advertised,
running command

$ ./perf record -e cpu/event=0x00,umask=0x01,i\
	 name=INST_RETIRED.PREC_DIST/p -c 10000 sleep 1

can trigger:

unchecked MSR access error: WRMSR to 0x3f1 ... in\
	 intel_pmu_pebs_enable_all()

This occurs because SPR-specific PEBS constraints allow fixed-counter
scheduling (for example, INST_RETIRED.PREC_DIST on fixed counter 0).
In guests lacking pebs_baseline, KVM does not support PEBS sampling on
fixed counters, so enabling such events reaches an invalid MSR
programming path.

Starting with Icelake, regardless of whether Extended PEBS or
Architectural PEBS is in use, all counters (including fixed counters)
support PEBS sampling, and the PMU_FL_PEBS_ALL flag is set by default.
As long as PMU_FL_PEBS_ALL is set, constraint lookup automatically falls
back to the corresponding non-PEBS constraints if no matching entry is
found in the PEBS constraints table. Since non-PEBS event constraints
already contain the same fixed-counter constraints, it is safe to remove
these fixed-counter entries from the PEBS constraints table. The fallback
mechanism will ensure that fixed PEBS events are scheduled onto the
correct fixed counters.

So, directly drop the fixed-counter entries from the PEBS constraint
table. Without pebs_baseline, these fixed-counter PEBS events will now
resolve to empty constraints and will not be scheduled or enabled,
thereby avoiding the warning and bypassing the broken guest PEBS path.

Reported-by: Yi Lai <yi1.lai@intel.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 arch/x86/events/intel/ds.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index cb72af9b61ce..5db15a92017a 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1447,10 +1447,6 @@ struct event_constraint intel_skl_pebs_event_constraints[] = {
 };
 
 struct event_constraint intel_icl_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x01c0, 0x100000000ULL),	/* old INST_RETIRED.PREC_DIST */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0100, 0x100000000ULL),	/* INST_RETIRED.PREC_DIST */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),	/* SLOTS */
-
 	INTEL_PLD_CONSTRAINT(0x1cd, 0xff),			/* MEM_TRANS_RETIRED.LOAD_LATENCY */
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_LOADS */
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_STORES */
@@ -1473,9 +1469,6 @@ struct event_constraint intel_icl_pebs_event_constraints[] = {
 };
 
 struct event_constraint intel_glc_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL),	/* INST_RETIRED.PREC_DIST */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),
-
 	INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe),
 	INTEL_PLD_CONSTRAINT(0x1cd, 0xfe),
 	INTEL_PSD_CONSTRAINT(0x2cd, 0x1),
@@ -1500,9 +1493,6 @@ struct event_constraint intel_glc_pebs_event_constraints[] = {
 };
 
 struct event_constraint intel_lnc_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL),	/* INST_RETIRED.PREC_DIST */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),
-
 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x012a, 0x1),		/* OCR.* events */
 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x012b, 0x1),		/* OCR.* events */
 
@@ -1534,9 +1524,6 @@ struct event_constraint intel_lnc_pebs_event_constraints[] = {
 };
 
 struct event_constraint intel_pnc_pebs_event_constraints[] = {
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL),	/* INST_RETIRED.PREC_DIST */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),
-
 	INTEL_HYBRID_LDLAT_CONSTRAINT(0x1cd, 0xfc),
 	INTEL_HYBRID_STLAT_CONSTRAINT(0x2cd, 0x3),
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_LOADS */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 7/8] perf/core: Fix kernel register info leak via hardware skid
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
                   ` (5 preceding siblings ...)
  2026-06-12  9:01 ` [Patch v3 6/8] perf/x86/intel: Drop fixed-counter PEBS constraints for baseline PEBS Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  2026-06-12  9:01 ` [Patch v3 8/8] perf/core: Check kernel access when kernel callchains are requested Dapeng Mi
  7 siblings, 0 replies; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi, Mark Rutland

An unprivileged hardware perf event using exclude_kernel=1 can leak kernel
register data to user space via PERF_SAMPLE_REGS_INTR or PERF_SAMPLE_IP.
Due to hardware skid, a PMI may trigger after the CPU has already entered
kernel space (Ring 0), bypassing the perf_allow_kernel() privilege
barrier.

This security vulnerability is severely exacerbated by upcoming support
for SIMD register sampling via XSAVES, which could expose sensitive kernel
FPU states (such as active cryptographic keys).

Fix this by ensuring that sampled register data is dropped if the event's
exclude_kernel attribute is set but the PMI catches the CPU in kernel mode.

Link: https://lore.kernel.org/all/20260529085613.CCAFB1F00893@smtp.kernel.org/
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 kernel/events/core.c | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 95d806bba654..89f6c9ffb964 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7792,10 +7792,20 @@ unsigned long perf_misc_flags(struct perf_event *event,
 unsigned long perf_instruction_pointer(struct perf_event *event,
 				       struct pt_regs *regs)
 {
-	if (should_sample_guest(event))
-		return perf_guest_get_ip();
+	/*
+	 * Hardware skid can lead to a scenario where a PMI is
+	 * delivered after the CPU has already entered kernel mode.
+	 * In that case, user-space sampling must not expose kernel
+	 * register state.
+	 */
+	if (should_sample_guest(event)) {
+		return event->attr.exclude_kernel &&
+		       !(perf_guest_state() & PERF_GUEST_USER) ?
+			0 : perf_guest_get_ip();
+	}
 
-	return perf_arch_instruction_pointer(regs);
+	return event->attr.exclude_kernel && !user_mode(regs) ?
+		0 : perf_arch_instruction_pointer(regs);
 }
 
 static void
@@ -7829,10 +7839,22 @@ static void perf_sample_regs_user(struct perf_regs *regs_user,
 }
 
 static void perf_sample_regs_intr(struct perf_regs *regs_intr,
-				  struct pt_regs *regs)
+				  struct pt_regs *regs,
+				  bool exclude_kernel)
 {
-	regs_intr->regs = regs;
-	regs_intr->abi  = perf_reg_abi(current);
+	/*
+	 * Hardware skid can lead to a scenario where a PMI is
+	 * delivered after the CPU has already entered kernel mode.
+	 * In that case, user-space sampling must not expose kernel
+	 * register state.
+	 */
+	if (exclude_kernel && !user_mode(regs)) {
+		regs_intr->abi = PERF_SAMPLE_REGS_ABI_NONE;
+		regs_intr->regs = NULL;
+	} else {
+		regs_intr->regs = regs;
+		regs_intr->abi = perf_reg_abi(current);
+	}
 }
 
 
@@ -8723,7 +8745,8 @@ void perf_prepare_sample(struct perf_sample_data *data,
 		/* regs dump ABI info */
 		int size = sizeof(u64);
 
-		perf_sample_regs_intr(&data->regs_intr, regs);
+		perf_sample_regs_intr(&data->regs_intr, regs,
+				      event->attr.exclude_kernel);
 
 		if (data->regs_intr.regs) {
 			u64 mask = event->attr.sample_regs_intr;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Patch v3 8/8] perf/core: Check kernel access when kernel callchains are requested
  2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
                   ` (6 preceding siblings ...)
  2026-06-12  9:01 ` [Patch v3 7/8] perf/core: Fix kernel register info leak via hardware skid Dapeng Mi
@ 2026-06-12  9:01 ` Dapeng Mi
  7 siblings, 0 replies; 13+ messages in thread
From: Dapeng Mi @ 2026-06-12  9:01 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Ian Rogers, Adrian Hunter, Alexander Shishkin,
	Andi Kleen, Eranian Stephane
  Cc: linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, Dapeng Mi, Mark Rutland

perf_event_open() currently gates perf_allow_kernel() only on
!attr.exclude_kernel.

However, users can still request kernel callchain collection with
attr.exclude_callchain_kernel == 0 even when attr.exclude_kernel == 1.
That still requires kernel profiling privilege, but the existing check
does not enforce it.

Update the permission check to call perf_allow_kernel() when either
kernel sampling is requested or kernel callchains are requested.

This keeps permission checks aligned with requested data and prevents
unprivileged use of kernel callchain capture.

Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
 kernel/events/core.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 89f6c9ffb964..bbd260d9d5b5 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -13924,7 +13924,9 @@ SYSCALL_DEFINE5(perf_event_open,
 	if (err)
 		return err;
 
-	if (!attr.exclude_kernel) {
+	if (!attr.exclude_kernel ||
+	    ((attr.sample_type & PERF_SAMPLE_CALLCHAIN) &&
+	     !attr.exclude_callchain_kernel)) {
 		err = perf_allow_kernel();
 		if (err)
 			return err;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Patch v3 4/8] perf/x86/intel: Fix kernel address leakages in LBR stack
  2026-06-12  9:01 ` [Patch v3 4/8] perf/x86/intel: Fix kernel address leakages in LBR stack Dapeng Mi
@ 2026-06-12  9:18   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  9:18 UTC (permalink / raw)
  To: Dapeng Mi; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Missing Privilege Escalation/Leakage Fix in AMD LBR
--

commit c04d9132d61b165193dd28c5a358e42d3c52a350
Author: Dapeng Mi <dapeng1.mi@linux.intel.com>

perf/x86/intel: Fix kernel address leakages in LBR stack

This commit fixes a kernel address leakage in the Intel LBR stack when
PERF_SAMPLE_BRANCH_USER is requested. The intel_pmu_lbr_filter function
previously only validated the privilege level of the "to" address, leaving
kernel "from" addresses exposed on SYSRET/ERET branches. The fix extends
software filtering to validate both addresses against the requested filter.

Cc: stable@vger.kernel.org
Reported-by: Ian Rogers <irogers@google.com>
Fixes: 47125db27e47 ("perf/x86/intel/lbr: Support Architectural LBR")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>

> diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
> index e2657f791e507..16eef15378166 100644
> --- a/arch/x86/events/intel/lbr.c
> +++ b/arch/x86/events/intel/lbr.c

[ ... ]

> @@ -1244,8 +1244,14 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
>  				type |= X86_BR_NO_TX;
>  		}
>  
> -		/* if type does not correspond, then discard */
> -		if (type == X86_BR_NONE || (br_sel & type) != type) {
> +		from_plm = kernel_ip(from) ? X86_BR_KERNEL : X86_BR_USER;
> +		/*
> +		 * If type does not correspond, then discard.
> +		 * Specifically reject entries whose from address is in
> +		 * kernel space when only X86_BR_USER is requested.
> +		 */
> +		if (type == X86_BR_NONE || (br_sel & type) != type ||
> +		    (!(br_sel & X86_BR_KERNEL) && (from_plm & X86_BR_KERNEL))) {

[Severity: High]
This isn't a bug introduced by this patch, but does the exact same kernel
address leakage vulnerability exist in AMD's LBR implementation and remain
unpatched?

Looking at amd_pmu_lbr_filter() in arch/x86/events/amd/lbr.c, it relies on
branch_type_fused() to determine the branch type. For kernel-to-user branches
(like SYSRET), it evaluates the privilege purely based on the target (to)
address and returns X86_BR_SYSRET | X86_BR_USER.

When user-only branches are requested, br_sel includes X86_BR_USER and
X86_BR_ANY. Because AMD hardware will record kernel-to-user branches when
filtering by "ending in CPL > 0", the check in amd_pmu_lbr_filter():

    if (type == X86_BR_NONE || (br_sel & type) != type) {
        cpuc->lbr_entries[i].from = 0;
        compress = true;
    }

evaluates to false since type is fully satisfied by br_sel. This allows the
branch to bypass the software filter and leaks the kernel from addresses to
unprivileged users.

Should a similar from_plm validation check be added to amd_pmu_lbr_filter()
to prevent KASLR bypass on AMD systems?

>  			cpuc->lbr_entries[i].from = 0;
>  			compress = true;
>  		}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612090114.3188886-1-dapeng1.mi@linux.intel.com?part=4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch v3 3/8] perf/x86/intel: Fallback to sw branch type decoding if no hw decoding
  2026-06-12  9:01 ` [Patch v3 3/8] perf/x86/intel: Fallback to sw branch type decoding if no hw decoding Dapeng Mi
@ 2026-06-12  9:21   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  9:21 UTC (permalink / raw)
  To: Dapeng Mi; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] The patch introduces a severe performance regression in NMI context on Arch LBR CPUs that lack hardware branch-type decoding by unintentionally forcing software disassembly on all recorded branches.
--

commit 4686077e19d211c998cc542c03a674a17408e8d7
Author: Dapeng Mi <dapeng1.mi@linux.intel.com>

perf/x86/intel: Fallback to sw branch type decoding if no hw decoding

This commit updates the arch-LBR filtering logic to fallback to software
branch-type decoding if hardware decoding is not supported. It replaces
the X86_FEATURE_ARCH_LBR CPU feature check with the x86_lbr_type static
branch to properly handle arch-LBR configurations that lack branch-type
information.

> diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
> index 72f2adcda7c68..e2657f791e507 100644
> --- a/arch/x86/events/intel/lbr.c
> +++ b/arch/x86/events/intel/lbr.c
> @@ -1231,7 +1231,7 @@ intel_pmu_lbr_filter(struct cpu_hw_events *cpuc)
>  		 * Doesn't support OTHER_BRANCH decoding for now.
>  		 * OTHER_BRANCH branch type still rely on software decoding.
>  		 */
> -		if (static_cpu_has(X86_FEATURE_ARCH_LBR) &&
> +		if (static_branch_likely(&x86_lbr_type) &&
>  		    type <= ARCH_LBR_BR_TYPE_KNOWN_MAX) {
>  			to_plm = kernel_ip(to) ? X86_BR_KERNEL : X86_BR_USER;
>  			type = arch_lbr_br_type_map[type] | to_plm;

[Severity: High]
Does this introduce a performance regression in NMI context on arch-LBR CPUs
that lack hardware branch-type decoding?

Currently, intel_pmu_setup_hw_lbr_filter() unconditionally sets
X86_BR_TYPE_SAVE for arch-LBR CPUs:

arch/x86/events/intel/lbr.c:intel_pmu_setup_hw_lbr_filter() {
    ...
    reg->reg |= X86_BR_TYPE_SAVE;
    ...
}

Because X86_BR_TYPE_SAVE is forcibly set in br_sel, the fast-path early
return at the start of intel_pmu_lbr_filter() is bypassed even if the user
only requested basic branch recording without branch types.

With this patch, if x86_lbr_type is false, the loop falls through to the
else block and calls branch_type() for every LBR entry. This causes
expensive software instruction decoding to unconditionally execute for all
LBR records on every PMU interrupt.

Should intel_pmu_setup_hw_lbr_filter() be updated to only force-enable
X86_BR_TYPE_SAVE if static_branch_likely(&x86_lbr_type) is true?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612090114.3188886-1-dapeng1.mi@linux.intel.com?part=3

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch v3 5/8] perf/x86/intel: Validate the return value of intel_pmu_init_hybrid()
  2026-06-12  9:01 ` [Patch v3 5/8] perf/x86/intel: Validate the return value of intel_pmu_init_hybrid() Dapeng Mi
@ 2026-06-12  9:31   ` sashiko-bot
  0 siblings, 0 replies; 13+ messages in thread
From: sashiko-bot @ 2026-06-12  9:31 UTC (permalink / raw)
  To: Dapeng Mi; +Cc: linux-perf-users

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Relocating `intel_pmu_arch_lbr_init()` below `intel_pmu_check_event_constraints_all()` bypasses the dynamic constraint validation for branch counters.
--

commit 4ceb25a65fdf63fe8fa33e932139cf0a5d28e924
Author: Dapeng Mi <dapeng1.mi@linux.intel.com>

perf/x86/intel: Validate the return value of intel_pmu_init_hybrid()

This patch validates the return value of intel_pmu_init_hybrid() to avoid a
null-pointer dereference. It also defers intel_pmu_arch_lbr_init() until after
hybrid PMU initialization succeeds to avoid destroying the kmem cache on
failure.

> diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
> index db52e7e53a6cd..74dbf24b0ab63 100644
> --- a/arch/x86/events/intel/core.c
> +++ b/arch/x86/events/intel/core.c
[ ... ]
> @@ -8829,6 +8842,9 @@ __init int intel_pmu_init(void)
>  
>  	intel_pmu_check_event_constraints_all(NULL);
>  
> +	if (boot_cpu_has(X86_FEATURE_ARCH_LBR))
> +		intel_pmu_arch_lbr_init();
> +
[Severity: Medium]
Does moving intel_pmu_arch_lbr_init() below
intel_pmu_check_event_constraints_all() bypass the dynamic constraint
validation for branch counters?

When intel_pmu_check_event_constraints_all() runs, it eventually calls
intel_pmu_check_dyn_constr(). This check relies on the PMU_FL_BR_CNTR flag
and the x86_pmu.lbr_counters mask:

arch/x86/events/intel/core.c:intel_pmu_check_dyn_constr() {
    ...
		case DYN_CONSTR_BR_CNTR:
			if (x86_pmu.flags & PMU_FL_BR_CNTR)
				mask = x86_pmu.lbr_counters;
			break;
    ...
}

Because intel_pmu_arch_lbr_init() is now deferred until after this validation,
the PMU_FL_BR_CNTR flag hasn't been set yet. Will this cause the dynamic
constraint check for branch counters to evaluate to false and be skipped?

>  	/*
>  	 * Access LBR MSR may cause #GP under certain circumstances.
>  	 * Check all LBR MSR here.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260612090114.3188886-1-dapeng1.mi@linux.intel.com?part=5

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities
  2026-06-12  9:01 ` [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Dapeng Mi
@ 2026-06-12  9:46   ` Peter Zijlstra
  0 siblings, 0 replies; 13+ messages in thread
From: Peter Zijlstra @ 2026-06-12  9:46 UTC (permalink / raw)
  To: Dapeng Mi
  Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Namhyung Kim, Ian Rogers,
	Adrian Hunter, Alexander Shishkin, Andi Kleen, Eranian Stephane,
	linux-kernel, linux-perf-users, Dapeng Mi, Zide Chen,
	Falcon Thomas, Xudong Hao, stable

On Fri, Jun 12, 2026 at 05:01:07PM +0800, Dapeng Mi wrote:
> AnyThread mode deprecation is enumerated by CPUID.0AH:EDX[15] instead of
> PERF_CAPABILITIES MSR. It's not a good practice to define a bit to
> represent "anythread deprecation" in perf_capabilities. It leads to the
> anythread_deprecated bit could be overwritten by the real value of
> PERF_CAPABILITIES MSR, just like the below code in update_pmu_cap() does.
> 
> ```
> if (!intel_pmu_broken_perf_cap()) {
> 	/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
> 	rdmsrq(MSR_IA32_PERF_CAPABILITIES, hybrid(pmu, intel_cap).capabilities);
> }
> ```
> 
> It leads to the anythread_deprecated bit is cleared to 0 and the "any"
> attribute is incorrectly shown in the /sys/devices/cpu/format/ folder on
> these support Perfmon v6 platforms, like Clearwater Forest.
> 
> ```
> $grep . /sys/devices/cpu/format/*
> /sys/devices/cpu/format/acr_mask:config2:0-63
> /sys/devices/cpu/format/any:config:21
> /sys/devices/cpu/format/cmask:config:24-31
> ```
> 
> So remove the anythread_deprecated bit from perf_capabilities structure
> and directly depends on CPUID.0AH:EDX[15] to judge if anythread is
> deprecated.

Again, no markdown please. I've stripped it from these patches.

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-06-12  9:46 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12  9:01 [Patch v3 0/8] perf/x86: Miscellaneous PMU bug fixes Dapeng Mi
2026-06-12  9:01 ` [Patch v3 1/8] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Dapeng Mi
2026-06-12  9:46   ` Peter Zijlstra
2026-06-12  9:01 ` [Patch v3 2/8] perf/x86/intel: Keep cap_user_rdpmc in sync with RDPMC user-disable state Dapeng Mi
2026-06-12  9:01 ` [Patch v3 3/8] perf/x86/intel: Fallback to sw branch type decoding if no hw decoding Dapeng Mi
2026-06-12  9:21   ` sashiko-bot
2026-06-12  9:01 ` [Patch v3 4/8] perf/x86/intel: Fix kernel address leakages in LBR stack Dapeng Mi
2026-06-12  9:18   ` sashiko-bot
2026-06-12  9:01 ` [Patch v3 5/8] perf/x86/intel: Validate the return value of intel_pmu_init_hybrid() Dapeng Mi
2026-06-12  9:31   ` sashiko-bot
2026-06-12  9:01 ` [Patch v3 6/8] perf/x86/intel: Drop fixed-counter PEBS constraints for baseline PEBS Dapeng Mi
2026-06-12  9:01 ` [Patch v3 7/8] perf/core: Fix kernel register info leak via hardware skid Dapeng Mi
2026-06-12  9:01 ` [Patch v3 8/8] perf/core: Check kernel access when kernel callchains are requested Dapeng Mi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox