* [PATCH v2 0/7] perf/amd/ibs: Future enhancements
@ 2026-02-16 4:25 Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 1/7] perf/amd/ibs: Define macro for ldlat mask and shift Ravi Bangoria
` (6 more replies)
0 siblings, 7 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
Add support for new capabilities that will appear in future AMD
CPUs:
- Alternate disable bit with control only MSRs to eliminate the
RMW race in existing IBS_{FETCH|OP}_CTL MSRs
- RIP bit 63 filtering, which can be used as hardware assisted
privilege filtering, enabling IBS for unprivileged users without
software based privilege filtering
- Fetch latency threshold filter to capture only high-latency fetch
events
- Streaming-store filter to sample only instructions that perform
streaming stores
- Remote socket indicator for load/store instructions
Patches are prepared on tip/perf/core (7db06e329af3) + IBS fixes series
IBS fixes series:
https://lore.kernel.org/r/20260216042216.1440-1-ravi.bangoria@amd.com
Perf tools patches:
https://lore.kernel.org/r/20260119024328.897-1-ravi.bangoria@amd.com
v1: https://lore.kernel.org/r/20260116033450.965-1-ravi.bangoria@amd.com
v1->v2:
- Split fixes series from future enhancements
- Replace magic numbers with macros
Ravi Bangoria (7):
perf/amd/ibs: Define macro for ldlat mask and shift
perf/amd/ibs: Add new MSRs and CPUID bits definitions
perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race
perf/amd/ibs: Enable fetch latency filtering
perf/amd/ibs: Enable RIP bit63 hardware filtering
perf/amd/ibs: Enable streaming store filter
perf/amd/ibs: Advertise remote socket capability
arch/x86/events/amd/ibs.c | 238 ++++++++++++++++++++++++++++--
arch/x86/include/asm/amd/ibs.h | 4 +-
arch/x86/include/asm/msr-index.h | 2 +
arch/x86/include/asm/perf_event.h | 55 ++++---
4 files changed, 266 insertions(+), 33 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 1/7] perf/amd/ibs: Define macro for ldlat mask and shift
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 2/7] perf/amd/ibs: Add new MSRs and CPUID bits definitions Ravi Bangoria
` (5 subsequent siblings)
6 siblings, 1 reply; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
Load latency filter threshold is encoded in config1[11:0]. Define a mask
for it instead of hardcoded 0xFFF. Unlike "config" fields whose layout
maps to PERF_{FETCH|OP}_CTL MSR, layout of "config1" is custom defined
so a new set of macros are needed for "config1" fields.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/events/amd/ibs.c | 11 +++++++----
arch/x86/include/asm/perf_event.h | 1 +
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 32e6456cb5e5..2e8fb0615226 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -32,6 +32,9 @@ static u32 ibs_caps;
/* attr.config2 */
#define IBS_SW_FILTER_MASK 1
+/* attr.config1 */
+#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+
/*
* IBS states:
*
@@ -274,7 +277,7 @@ static bool perf_ibs_ldlat_event(struct perf_ibs *perf_ibs,
{
return perf_ibs == &perf_ibs_op &&
(ibs_caps & IBS_CAPS_OPLDLAT) &&
- (event->attr.config1 & 0xFFF);
+ (event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK);
}
static int perf_ibs_init(struct perf_event *event)
@@ -352,13 +355,13 @@ static int perf_ibs_init(struct perf_event *event)
}
if (perf_ibs_ldlat_event(perf_ibs, event)) {
- u64 ldlat = event->attr.config1 & 0xFFF;
+ u64 ldlat = event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK;
if (ldlat < 128 || ldlat > 2048)
return -EINVAL;
ldlat >>= 7;
- config |= (ldlat - 1) << 59;
+ config |= (ldlat - 1) << IBS_OP_LDLAT_THRSH_SHIFT;
config |= IBS_OP_LDLAT_EN;
if (cpu_feature_enabled(X86_FEATURE_ZEN5))
@@ -1305,7 +1308,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
* within [128, 2048] range.
*/
if (!op_data3.ld_op || !op_data3.dc_miss ||
- op_data3.dc_miss_lat <= (event->attr.config1 & 0xFFF)) {
+ op_data3.dc_miss_lat <= (event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK)) {
throttle = perf_event_account_interrupt(event);
goto out;
}
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index ff5acb8b199b..67ecb989408e 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -671,6 +671,7 @@ struct arch_pebs_cntr_header {
*/
#define IBS_OP_LDLAT_EN (1ULL<<63)
#define IBS_OP_LDLAT_THRSH (0xFULL<<59)
+#define IBS_OP_LDLAT_THRSH_SHIFT (59)
#define IBS_OP_CUR_CNT (0xFFF80ULL<<32)
#define IBS_OP_CUR_CNT_RAND (0x0007FULL<<32)
#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL<<52)
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 2/7] perf/amd/ibs: Add new MSRs and CPUID bits definitions
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 1/7] perf/amd/ibs: Define macro for ldlat mask and shift Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 3/7] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race Ravi Bangoria
` (4 subsequent siblings)
6 siblings, 1 reply; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
IBS on upcoming microarch introduced two new control MSRs and couple of
new features. Define macros for them.
New capabilities:
o IBS_CAPS_DIS: Alternate Fetch and Op IBS disable bits
o IBS_CAPS_FETCHLAT: Fetch Latency filter
o IBS_CAPS_BIT63_FILTER: Virtual address bit 63 based filters for Fetch
and Op
o IBS_CAPS_STRMST_RMTSOCKET: Streaming store filter and indicator,
remote socket indicator
New control MSRs for above features:
o MSR_AMD64_IBSFETCHCTL2
o MSR_AMD64_IBSOPCTL2
Also do cosmetic alignment changes.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
---
arch/x86/include/asm/msr-index.h | 2 ++
arch/x86/include/asm/perf_event.h | 56 ++++++++++++++++++++-----------
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 6d1b69ea01c2..2313623eb0d0 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -698,6 +698,8 @@
#define MSR_AMD64_IBSBRTARGET 0xc001103b
#define MSR_AMD64_ICIBSEXTDCTL 0xc001103c
#define MSR_AMD64_IBSOPDATA4 0xc001103d
+#define MSR_AMD64_IBSOPCTL2 0xc001103e
+#define MSR_AMD64_IBSFETCHCTL2 0xc001103f
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
#define MSR_AMD64_SVM_AVIC_DOORBELL 0xc001011b
#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 67ecb989408e..752cb319d5ea 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -643,6 +643,10 @@ struct arch_pebs_cntr_header {
#define IBS_CAPS_OPDATA4 (1U<<10)
#define IBS_CAPS_ZEN4 (1U<<11)
#define IBS_CAPS_OPLDLAT (1U<<12)
+#define IBS_CAPS_DIS (1U<<13)
+#define IBS_CAPS_FETCHLAT (1U<<14)
+#define IBS_CAPS_BIT63_FILTER (1U<<15)
+#define IBS_CAPS_STRMST_RMTSOCKET (1U<<16)
#define IBS_CAPS_OPDTLBPGSIZE (1U<<19)
#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
@@ -657,32 +661,44 @@ struct arch_pebs_cntr_header {
#define IBSCTL_LVT_OFFSET_MASK 0x0F
/* IBS fetch bits/masks */
-#define IBS_FETCH_L3MISSONLY (1ULL<<59)
-#define IBS_FETCH_RAND_EN (1ULL<<57)
-#define IBS_FETCH_VAL (1ULL<<49)
-#define IBS_FETCH_ENABLE (1ULL<<48)
-#define IBS_FETCH_CNT 0xFFFF0000ULL
-#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+#define IBS_FETCH_L3MISSONLY (1ULL << 59)
+#define IBS_FETCH_RAND_EN (1ULL << 57)
+#define IBS_FETCH_VAL (1ULL << 49)
+#define IBS_FETCH_ENABLE (1ULL << 48)
+#define IBS_FETCH_CNT 0xFFFF0000ULL
+#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+
+#define IBS_FETCH_2_DIS (1ULL << 0)
+#define IBS_FETCH_2_FETCHLAT_FILTER (0xFULL << 1)
+#define IBS_FETCH_2_FETCHLAT_FILTER_SHIFT (1)
+#define IBS_FETCH_2_EXCL_RIP_63_EQ_1 (1ULL << 5)
+#define IBS_FETCH_2_EXCL_RIP_63_EQ_0 (1ULL << 6)
/*
* IBS op bits/masks
* The lower 7 bits of the current count are random bits
* preloaded by hardware and ignored in software
*/
-#define IBS_OP_LDLAT_EN (1ULL<<63)
-#define IBS_OP_LDLAT_THRSH (0xFULL<<59)
-#define IBS_OP_LDLAT_THRSH_SHIFT (59)
-#define IBS_OP_CUR_CNT (0xFFF80ULL<<32)
-#define IBS_OP_CUR_CNT_RAND (0x0007FULL<<32)
-#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL<<52)
-#define IBS_OP_CNT_CTL (1ULL<<19)
-#define IBS_OP_VAL (1ULL<<18)
-#define IBS_OP_ENABLE (1ULL<<17)
-#define IBS_OP_L3MISSONLY (1ULL<<16)
-#define IBS_OP_MAX_CNT 0x0000FFFFULL
-#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
-#define IBS_OP_MAX_CNT_EXT_MASK (0x7FULL<<20) /* separate upper 7 bits */
-#define IBS_RIP_INVALID (1ULL<<38)
+#define IBS_OP_LDLAT_EN (1ULL << 63)
+#define IBS_OP_LDLAT_THRSH (0xFULL << 59)
+#define IBS_OP_LDLAT_THRSH_SHIFT (59)
+#define IBS_OP_CUR_CNT (0xFFF80ULL << 32)
+#define IBS_OP_CUR_CNT_RAND (0x0007FULL << 32)
+#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL << 52)
+#define IBS_OP_CNT_CTL (1ULL << 19)
+#define IBS_OP_VAL (1ULL << 18)
+#define IBS_OP_ENABLE (1ULL << 17)
+#define IBS_OP_L3MISSONLY (1ULL << 16)
+#define IBS_OP_MAX_CNT 0x0000FFFFULL
+#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
+#define IBS_OP_MAX_CNT_EXT_MASK (0x7FULL << 20) /* separate upper 7 bits */
+#define IBS_RIP_INVALID (1ULL << 38)
+
+#define IBS_OP_2_DIS (1ULL << 0)
+#define IBS_OP_2_EXCL_RIP_63_EQ_0 (1ULL << 1)
+#define IBS_OP_2_EXCL_RIP_63_EQ_1 (1ULL << 2)
+#define IBS_OP_2_STRM_ST_FILTER (1ULL << 3)
+#define IBS_OP_2_STRM_ST_FILTER_SHIFT (3)
#ifdef CONFIG_X86_LOCAL_APIC
extern u32 get_ibs_caps(void);
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 3/7] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 1/7] perf/amd/ibs: Define macro for ldlat mask and shift Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 2/7] perf/amd/ibs: Add new MSRs and CPUID bits definitions Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` [tip: perf/core] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] " tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 4/7] perf/amd/ibs: Enable fetch latency filtering Ravi Bangoria
` (3 subsequent siblings)
6 siblings, 2 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
The existing IBS_{FETCH|OP}_CTL MSRs combine control and status bits
which leads to RMW race between HW and SW:
HW SW
------------------------ ------------------------------
config = rdmsr(IBS_OP_CTL);
config &= ~EN;
Set IBS_OP_CTL[Val] to 1
trigger NMI
wrmsr(IBS_OP_CTL, config);
// Val is accidentally cleared
Future hardware adds a control-only MSR, IBS_{FETCH|OP}_CTL2, which
provides a second-level "disable" bit (Dis). IBS is now:
Enabled: IBS_{FETCH|OP}_CTL[En] = 1 && IBS_{FETCH|OP}_CTL2[Dis] = 0
Disabled: IBS_{FETCH|OP}_CTL[En] = 0 || IBS_{FETCH|OP}_CTL2[Dis] = 1
The separate "Dis" bit lets software disable IBS without touching any
status fields, eliminating the hardware/software race.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
---
arch/x86/events/amd/ibs.c | 45 +++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 2e8fb0615226..b7f0aad9356c 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -86,9 +86,11 @@ struct cpu_perf_ibs {
struct perf_ibs {
struct pmu pmu;
unsigned int msr;
+ unsigned int msr2;
u64 config_mask;
u64 cnt_mask;
u64 enable_mask;
+ u64 disable_mask;
u64 valid_mask;
u16 min_period;
u64 max_period;
@@ -292,6 +294,8 @@ static int perf_ibs_init(struct perf_event *event)
return -ENOENT;
config = event->attr.config;
+ hwc->extra_reg.config = 0;
+ hwc->extra_reg.reg = 0;
if (event->pmu != &perf_ibs->pmu)
return -ENOENT;
@@ -319,6 +323,11 @@ static int perf_ibs_init(struct perf_event *event)
if (perf_allow_kernel())
hwc->flags |= PERF_X86_EVENT_UNPRIVILEGED;
+ if (ibs_caps & IBS_CAPS_DIS) {
+ hwc->extra_reg.config &= ~perf_ibs->disable_mask;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+
if (hwc->sample_period) {
if (config & perf_ibs->cnt_mask)
/* raw max_cnt may not be set */
@@ -448,6 +457,9 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
wrmsrq(hwc->config_base, tmp & ~perf_ibs->enable_mask);
wrmsrq(hwc->config_base, tmp | perf_ibs->enable_mask);
+
+ if (hwc->extra_reg.reg)
+ wrmsrq(hwc->extra_reg.reg, hwc->extra_reg.config);
}
/*
@@ -460,6 +472,11 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
struct hw_perf_event *hwc, u64 config)
{
+ if (ibs_caps & IBS_CAPS_DIS) {
+ wrmsrq(hwc->extra_reg.reg, perf_ibs->disable_mask);
+ return;
+ }
+
config &= ~perf_ibs->cnt_mask;
if (boot_cpu_data.x86 == 0x10)
wrmsrq(hwc->config_base, config);
@@ -812,6 +829,7 @@ static struct perf_ibs perf_ibs_fetch = {
.check_period = perf_ibs_check_period,
},
.msr = MSR_AMD64_IBSFETCHCTL,
+ .msr2 = MSR_AMD64_IBSFETCHCTL2,
.config_mask = IBS_FETCH_MAX_CNT | IBS_FETCH_RAND_EN,
.cnt_mask = IBS_FETCH_MAX_CNT,
.enable_mask = IBS_FETCH_ENABLE,
@@ -837,6 +855,7 @@ static struct perf_ibs perf_ibs_op = {
.check_period = perf_ibs_check_period,
},
.msr = MSR_AMD64_IBSOPCTL,
+ .msr2 = MSR_AMD64_IBSOPCTL2,
.config_mask = IBS_OP_MAX_CNT,
.cnt_mask = IBS_OP_MAX_CNT | IBS_OP_CUR_CNT |
IBS_OP_CUR_CNT_RAND,
@@ -1394,6 +1413,9 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
out:
if (!throttle) {
+ if (ibs_caps & IBS_CAPS_DIS)
+ wrmsrq(hwc->extra_reg.reg, perf_ibs->disable_mask);
+
if (perf_ibs == &perf_ibs_op) {
if (ibs_caps & IBS_CAPS_OPCNTEXT) {
new_config = period & IBS_OP_MAX_CNT_EXT_MASK;
@@ -1465,6 +1487,9 @@ static __init int perf_ibs_fetch_init(void)
if (ibs_caps & IBS_CAPS_ZEN4)
perf_ibs_fetch.config_mask |= IBS_FETCH_L3MISSONLY;
+ if (ibs_caps & IBS_CAPS_DIS)
+ perf_ibs_fetch.disable_mask = IBS_FETCH_2_DIS;
+
perf_ibs_fetch.pmu.attr_groups = fetch_attr_groups;
perf_ibs_fetch.pmu.attr_update = fetch_attr_update;
@@ -1486,6 +1511,9 @@ static __init int perf_ibs_op_init(void)
if (ibs_caps & IBS_CAPS_ZEN4)
perf_ibs_op.config_mask |= IBS_OP_L3MISSONLY;
+ if (ibs_caps & IBS_CAPS_DIS)
+ perf_ibs_op.disable_mask = IBS_OP_2_DIS;
+
perf_ibs_op.pmu.attr_groups = op_attr_groups;
perf_ibs_op.pmu.attr_update = op_attr_update;
@@ -1732,6 +1760,23 @@ static void clear_APIC_ibs(void)
static int x86_pmu_amd_ibs_starting_cpu(unsigned int cpu)
{
setup_APIC_ibs();
+
+ if (ibs_caps & IBS_CAPS_DIS) {
+ /*
+ * IBS enable sequence:
+ * CTL[En] = 1;
+ * CTL2[Dis] = 0;
+ *
+ * IBS disable sequence:
+ * CTL2[Dis] = 1;
+ *
+ * Set CTL2[Dis] when CPU comes up. This is needed to make
+ * enable sequence effective.
+ */
+ wrmsrq(MSR_AMD64_IBSFETCHCTL2, IBS_FETCH_2_DIS);
+ wrmsrq(MSR_AMD64_IBSOPCTL2, IBS_OP_2_DIS);
+ }
+
return 0;
}
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 4/7] perf/amd/ibs: Enable fetch latency filtering
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
` (2 preceding siblings ...)
2026-02-16 4:25 ` [PATCH v2 3/7] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering Ravi Bangoria
` (2 subsequent siblings)
6 siblings, 2 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
IBS Fetch on future hardware adds fetch latency filtering which
generates interrupt only when FetchLat value exceeds a programmable
threshold.
Hardware allows threshold in 128-cycle increment (i.e. 128, 256, 384
etc.) from 128 to 1920 cycles. Like the existing IBS filters, samples
that fail the latency test are dropped and IBS restarts internally.
Since hardware supports threshold in multiple of 128, add a software
filter on top to support latency threshold with the granularity of 1
cycle in between [128-1920].
Example:
# perf record -e ibs_fetch/fetchlat=128/ -c 10000 -a -- sleep 5
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
---
arch/x86/events/amd/ibs.c | 66 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index b7f0aad9356c..cb3ae4e4744c 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -35,6 +35,8 @@ static u32 ibs_caps;
/* attr.config1 */
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
+
/*
* IBS states:
*
@@ -282,6 +284,14 @@ static bool perf_ibs_ldlat_event(struct perf_ibs *perf_ibs,
(event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK);
}
+static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
+ struct perf_event *event)
+{
+ return perf_ibs == &perf_ibs_fetch &&
+ (ibs_caps & IBS_CAPS_FETCHLAT) &&
+ (event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
+}
+
static int perf_ibs_init(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -377,6 +387,17 @@ static int perf_ibs_init(struct perf_event *event)
config |= IBS_OP_L3MISSONLY;
}
+ if (perf_ibs_fetch_lat_event(perf_ibs, event)) {
+ u64 fetchlat = event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK;
+
+ if (fetchlat < 128 || fetchlat > 1920)
+ return -EINVAL;
+ fetchlat >>= 7;
+
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
+ }
+
/*
* If we modify hwc->sample_period, we also need to update
* hwc->last_period and hwc->period_left.
@@ -665,6 +686,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_format, "config1:0-11");
PMU_EVENT_ATTR_STRING(zen4_ibs_extensions, zen4_ibs_extensions, "1");
PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
+PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
+PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -672,6 +695,12 @@ zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int
return ibs_caps & IBS_CAPS_ZEN4 ? attr->mode : 0;
}
+static umode_t
+ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_FETCHLAT ? attr->mode : 0;
+}
+
static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
@@ -700,6 +729,16 @@ static struct attribute *zen4_ibs_extensions_attrs[] = {
NULL,
};
+static struct attribute *ibs_fetch_lat_format_attrs[] = {
+ &ibs_fetch_lat_format.attr.attr,
+ NULL,
+};
+
+static struct attribute *ibs_fetch_lat_cap_attrs[] = {
+ &ibs_fetch_lat_cap.attr.attr,
+ NULL,
+};
+
static struct attribute *ibs_op_ldlat_cap_attrs[] = {
&ibs_op_ldlat_cap.attr.attr,
NULL,
@@ -727,6 +766,18 @@ static struct attribute_group group_zen4_ibs_extensions = {
.is_visible = zen4_ibs_extensions_is_visible,
};
+static struct attribute_group group_ibs_fetch_lat_cap = {
+ .name = "caps",
+ .attrs = ibs_fetch_lat_cap_attrs,
+ .is_visible = ibs_fetch_lat_is_visible,
+};
+
+static struct attribute_group group_ibs_fetch_lat_format = {
+ .name = "format",
+ .attrs = ibs_fetch_lat_format_attrs,
+ .is_visible = ibs_fetch_lat_is_visible,
+};
+
static struct attribute_group group_ibs_op_ldlat_cap = {
.name = "caps",
.attrs = ibs_op_ldlat_cap_attrs,
@@ -748,6 +799,8 @@ static const struct attribute_group *fetch_attr_groups[] = {
static const struct attribute_group *fetch_attr_update[] = {
&group_fetch_l3missonly,
&group_zen4_ibs_extensions,
+ &group_ibs_fetch_lat_cap,
+ &group_ibs_fetch_lat_format,
NULL,
};
@@ -1191,7 +1244,8 @@ static int perf_ibs_get_offset_max(struct perf_ibs *perf_ibs,
{
if (event->attr.sample_type & PERF_SAMPLE_RAW ||
perf_ibs_is_mem_sample_type(perf_ibs, event) ||
- perf_ibs_ldlat_event(perf_ibs, event))
+ perf_ibs_ldlat_event(perf_ibs, event) ||
+ perf_ibs_fetch_lat_event(perf_ibs, event))
return perf_ibs->offset_max;
else if (check_rip)
return 3;
@@ -1333,6 +1387,16 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
}
}
+ if (perf_ibs_fetch_lat_event(perf_ibs, event)) {
+ union ibs_fetch_ctl fetch_ctl;
+
+ fetch_ctl.val = ibs_data.regs[ibs_fetch_msr_idx(MSR_AMD64_IBSFETCHCTL)];
+ if (fetch_ctl.fetch_lat < (event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK)) {
+ throttle = perf_event_account_interrupt(event);
+ goto out;
+ }
+ }
+
/*
* Read IbsBrTarget, IbsOpData4, and IbsExtdCtl separately
* depending on their availability.
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
` (3 preceding siblings ...)
2026-02-16 4:25 ` [PATCH v2 4/7] perf/amd/ibs: Enable fetch latency filtering Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-24 17:47 ` Ian Rogers
` (2 more replies)
2026-02-16 4:25 ` [PATCH v2 6/7] perf/amd/ibs: Enable streaming store filter Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 7/7] perf/amd/ibs: Advertise remote socket capability Ravi Bangoria
6 siblings, 3 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
IBS on future hardware adds the ability to filter IBS events by examining
RIP bit 63. Because Linux kernel addresses always have bit 63 set while
user-space addresses never do, this capability can be used as a privilege
filter.
So far, IBS supports privilege filtering in software (swfilt=1), where
samples are dropped in the NMI handler. The RIP bit63 hardware filter
enables IBS to be usable by unprivileged users without passing swfilt
flag. So, swfilt flag will silently be ignored when the hardware
filtering capability is present.
Example (non-root user):
$ perf record -e ibs_op//u -- <workload>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
---
arch/x86/events/amd/ibs.c | 46 ++++++++++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index cb3ae4e4744c..13ecc8d92b23 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -321,11 +321,6 @@ static int perf_ibs_init(struct perf_event *event)
event->attr.exclude_idle)
return -EINVAL;
- if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
- (event->attr.exclude_kernel || event->attr.exclude_user ||
- event->attr.exclude_hv))
- return -EINVAL;
-
ret = validate_group(event);
if (ret)
return ret;
@@ -338,6 +333,32 @@ static int perf_ibs_init(struct perf_event *event)
hwc->extra_reg.reg = perf_ibs->msr2;
}
+ if (ibs_caps & IBS_CAPS_BIT63_FILTER) {
+ if (perf_ibs == &perf_ibs_fetch) {
+ if (event->attr.exclude_kernel) {
+ hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_1;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ if (event->attr.exclude_user) {
+ hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_0;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ } else {
+ if (event->attr.exclude_kernel) {
+ hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_1;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ if (event->attr.exclude_user) {
+ hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_0;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ }
+ } else if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
+ (event->attr.exclude_kernel || event->attr.exclude_user ||
+ event->attr.exclude_hv)) {
+ return -EINVAL;
+ }
+
if (hwc->sample_period) {
if (config & perf_ibs->cnt_mask)
/* raw max_cnt may not be set */
@@ -1280,7 +1301,7 @@ static bool perf_ibs_is_kernel_br_target(struct perf_event *event,
op_data.op_brn_ret && kernel_ip(br_target));
}
-static bool perf_ibs_swfilt_discard(struct perf_ibs *perf_ibs, struct perf_event *event,
+static bool perf_ibs_discard_sample(struct perf_ibs *perf_ibs, struct perf_event *event,
struct pt_regs *regs, struct perf_ibs_data *ibs_data,
int br_target_idx)
{
@@ -1435,8 +1456,9 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
regs.flags |= PERF_EFLAGS_EXACT;
}
- if ((event->attr.config2 & IBS_SW_FILTER_MASK) &&
- perf_ibs_swfilt_discard(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
+ if (((ibs_caps & IBS_CAPS_BIT63_FILTER) ||
+ (event->attr.config2 & IBS_SW_FILTER_MASK)) &&
+ perf_ibs_discard_sample(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
throttle = perf_event_account_interrupt(event);
goto out;
}
@@ -1899,6 +1921,14 @@ static __init int amd_ibs_init(void)
perf_ibs_pm_init();
+#ifdef CONFIG_X86_32
+ /*
+ * IBS_CAPS_BIT63_FILTER is used for exclude_kernel/user filtering,
+ * which obviously won't work for 32 bit kernel.
+ */
+ caps &= ~IBS_CAPS_BIT63_FILTER;
+#endif
+
ibs_caps = caps;
/* make ibs_caps visible to other cpus: */
smp_mb();
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 6/7] perf/amd/ibs: Enable streaming store filter
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
` (4 preceding siblings ...)
2026-02-16 4:25 ` [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 7/7] perf/amd/ibs: Advertise remote socket capability Ravi Bangoria
6 siblings, 2 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
IBS OP on future hardware supports recording samples only for instructions
that does streaming store. Like the existing IBS filters, samples pointing
to instruction which does not cause streaming store are discarded and IBS
restarts internally.
Example:
$ perf record -e ibs_op/strmst=1/ -- <workload>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
---
arch/x86/events/amd/ibs.c | 51 ++++++++++++++++++++++++++++++++++
arch/x86/include/asm/amd/ibs.h | 3 +-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 13ecc8d92b23..0a8313ea6331 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -34,6 +34,8 @@ static u32 ibs_caps;
/* attr.config1 */
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+#define IBS_OP_CONFIG1_STRMST_MASK (1ULL << 12)
+#define IBS_OP_CONFIG1_STRMST_SHIFT (12)
#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
@@ -292,6 +294,14 @@ static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
(event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
}
+static bool perf_ibs_strmst_event(struct perf_ibs *perf_ibs,
+ struct perf_event *event)
+{
+ return perf_ibs == &perf_ibs_op &&
+ (ibs_caps & IBS_CAPS_STRMST_RMTSOCKET) &&
+ (event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK);
+}
+
static int perf_ibs_init(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -419,6 +429,15 @@ static int perf_ibs_init(struct perf_event *event)
hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
}
+ if (perf_ibs_strmst_event(perf_ibs, event)) {
+ u64 strmst = event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK;
+
+ strmst >>= IBS_OP_CONFIG1_STRMST_SHIFT;
+
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ hwc->extra_reg.config |= strmst << IBS_OP_2_STRM_ST_FILTER_SHIFT;
+ }
+
/*
* If we modify hwc->sample_period, we also need to update
* hwc->last_period and hwc->period_left.
@@ -709,6 +728,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
+PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
+PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -722,6 +743,12 @@ ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
return ibs_caps & IBS_CAPS_FETCHLAT ? attr->mode : 0;
}
+static umode_t
+ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
+}
+
static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
@@ -770,6 +797,11 @@ static struct attribute *ibs_op_dtlb_pgsize_cap_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_strmst_cap_attrs[] = {
+ &ibs_op_strmst_cap.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_fetch_formats = {
.name = "format",
.attrs = fetch_attrs,
@@ -811,6 +843,12 @@ static struct attribute_group group_ibs_op_dtlb_pgsize_cap = {
.is_visible = ibs_op_dtlb_pgsize_is_visible,
};
+static struct attribute_group group_ibs_op_strmst_cap = {
+ .name = "caps",
+ .attrs = ibs_op_strmst_cap_attrs,
+ .is_visible = ibs_op_strmst_is_visible,
+};
+
static const struct attribute_group *fetch_attr_groups[] = {
&group_fetch_formats,
&empty_caps_group,
@@ -856,6 +894,11 @@ static struct attribute *ibs_op_ldlat_format_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_strmst_format_attrs[] = {
+ &ibs_op_strmst_format.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_cnt_ctl = {
.name = "format",
.attrs = cnt_ctl_attrs,
@@ -880,6 +923,12 @@ static struct attribute_group group_ibs_op_ldlat_format = {
.is_visible = ibs_op_ldlat_is_visible,
};
+static struct attribute_group group_ibs_op_strmst_format = {
+ .name = "format",
+ .attrs = ibs_op_strmst_format_attrs,
+ .is_visible = ibs_op_strmst_is_visible,
+};
+
static const struct attribute_group *op_attr_update[] = {
&group_cnt_ctl,
&group_op_l3missonly,
@@ -887,6 +936,8 @@ static const struct attribute_group *op_attr_update[] = {
&group_ibs_op_ldlat_cap,
&group_ibs_op_ldlat_format,
&group_ibs_op_dtlb_pgsize_cap,
+ &group_ibs_op_strmst_cap,
+ &group_ibs_op_strmst_format,
NULL,
};
diff --git a/arch/x86/include/asm/amd/ibs.h b/arch/x86/include/asm/amd/ibs.h
index fcc8a5abe54e..020916eb7b4e 100644
--- a/arch/x86/include/asm/amd/ibs.h
+++ b/arch/x86/include/asm/amd/ibs.h
@@ -99,7 +99,8 @@ union ibs_op_data2 {
rmt_node:1, /* 4: destination node */
cache_hit_st:1, /* 5: cache hit state */
data_src_hi:2, /* 6-7: data source high */
- reserved1:56; /* 8-63: reserved */
+ strm_st:1, /* 8: streaming store */
+ reserved1:55; /* 9-63: reserved */
};
};
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v2 7/7] perf/amd/ibs: Advertise remote socket capability
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
` (5 preceding siblings ...)
2026-02-16 4:25 ` [PATCH v2 6/7] perf/amd/ibs: Enable streaming store filter Ravi Bangoria
@ 2026-02-16 4:25 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
6 siblings, 2 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-16 4:25 UTC (permalink / raw)
To: Peter Zijlstra, Ingo Molnar
Cc: Ravi Bangoria, Arnaldo Carvalho de Melo, Namhyung Kim,
Ian Rogers, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das
IBS OP on future hardware can indicate data source from remote socket
as well. Advertise this capability to userspace so that userspace tools
can decode IBS data accordingly.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
---
arch/x86/events/amd/ibs.c | 19 +++++++++++++++++++
arch/x86/include/asm/amd/ibs.h | 3 ++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 0a8313ea6331..eeb607b84dda 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -730,6 +730,7 @@ PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
+PMU_EVENT_ATTR_STRING(rmtsocket, ibs_op_rmtsocket_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -749,6 +750,12 @@ ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
}
+static umode_t
+ibs_op_rmtsocket_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
+}
+
static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
@@ -802,6 +809,11 @@ static struct attribute *ibs_op_strmst_cap_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_rmtsocket_cap_attrs[] = {
+ &ibs_op_rmtsocket_cap.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_fetch_formats = {
.name = "format",
.attrs = fetch_attrs,
@@ -849,6 +861,12 @@ static struct attribute_group group_ibs_op_strmst_cap = {
.is_visible = ibs_op_strmst_is_visible,
};
+static struct attribute_group group_ibs_op_rmtsocket_cap = {
+ .name = "caps",
+ .attrs = ibs_op_rmtsocket_cap_attrs,
+ .is_visible = ibs_op_rmtsocket_is_visible,
+};
+
static const struct attribute_group *fetch_attr_groups[] = {
&group_fetch_formats,
&empty_caps_group,
@@ -938,6 +956,7 @@ static const struct attribute_group *op_attr_update[] = {
&group_ibs_op_dtlb_pgsize_cap,
&group_ibs_op_strmst_cap,
&group_ibs_op_strmst_format,
+ &group_ibs_op_rmtsocket_cap,
NULL,
};
diff --git a/arch/x86/include/asm/amd/ibs.h b/arch/x86/include/asm/amd/ibs.h
index 020916eb7b4e..4eac36c42db6 100644
--- a/arch/x86/include/asm/amd/ibs.h
+++ b/arch/x86/include/asm/amd/ibs.h
@@ -100,7 +100,8 @@ union ibs_op_data2 {
cache_hit_st:1, /* 5: cache hit state */
data_src_hi:2, /* 6-7: data source high */
strm_st:1, /* 8: streaming store */
- reserved1:55; /* 9-63: reserved */
+ rmt_socket:1, /* 9: remote socket */
+ reserved1:54; /* 10-63: reserved */
};
};
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-16 4:25 ` [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering Ravi Bangoria
@ 2026-02-24 17:47 ` Ian Rogers
2026-02-26 9:20 ` Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2 siblings, 1 reply; 26+ messages in thread
From: Ian Rogers @ 2026-02-24 17:47 UTC (permalink / raw)
To: Ravi Bangoria
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das, Stephane Eranian
On Sun, Feb 15, 2026 at 8:26 PM Ravi Bangoria <ravi.bangoria@amd.com> wrote:
>
> IBS on future hardware adds the ability to filter IBS events by examining
> RIP bit 63. Because Linux kernel addresses always have bit 63 set while
> user-space addresses never do, this capability can be used as a privilege
> filter.
Since x86's top-byte-ignore/linear-address-masking leaves bit 63 could
this break in the future if the kernel later ignores all bits,
including bit 63, and user space wants to use bit 63 of the pointer
for metadata? Does the bit 63 assumption hold for guest operating
systems?
Thanks,
Ian
> So far, IBS supports privilege filtering in software (swfilt=1), where
> samples are dropped in the NMI handler. The RIP bit63 hardware filter
> enables IBS to be usable by unprivileged users without passing swfilt
> flag. So, swfilt flag will silently be ignored when the hardware
> filtering capability is present.
>
> Example (non-root user):
> $ perf record -e ibs_op//u -- <workload>
>
> Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
> ---
> arch/x86/events/amd/ibs.c | 46 ++++++++++++++++++++++++++++++++-------
> 1 file changed, 38 insertions(+), 8 deletions(-)
>
> diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
> index cb3ae4e4744c..13ecc8d92b23 100644
> --- a/arch/x86/events/amd/ibs.c
> +++ b/arch/x86/events/amd/ibs.c
> @@ -321,11 +321,6 @@ static int perf_ibs_init(struct perf_event *event)
> event->attr.exclude_idle)
> return -EINVAL;
>
> - if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
> - (event->attr.exclude_kernel || event->attr.exclude_user ||
> - event->attr.exclude_hv))
> - return -EINVAL;
> -
> ret = validate_group(event);
> if (ret)
> return ret;
> @@ -338,6 +333,32 @@ static int perf_ibs_init(struct perf_event *event)
> hwc->extra_reg.reg = perf_ibs->msr2;
> }
>
> + if (ibs_caps & IBS_CAPS_BIT63_FILTER) {
> + if (perf_ibs == &perf_ibs_fetch) {
> + if (event->attr.exclude_kernel) {
> + hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_1;
> + hwc->extra_reg.reg = perf_ibs->msr2;
> + }
> + if (event->attr.exclude_user) {
> + hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_0;
> + hwc->extra_reg.reg = perf_ibs->msr2;
> + }
> + } else {
> + if (event->attr.exclude_kernel) {
> + hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_1;
> + hwc->extra_reg.reg = perf_ibs->msr2;
> + }
> + if (event->attr.exclude_user) {
> + hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_0;
> + hwc->extra_reg.reg = perf_ibs->msr2;
> + }
> + }
> + } else if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
> + (event->attr.exclude_kernel || event->attr.exclude_user ||
> + event->attr.exclude_hv)) {
> + return -EINVAL;
> + }
> +
> if (hwc->sample_period) {
> if (config & perf_ibs->cnt_mask)
> /* raw max_cnt may not be set */
> @@ -1280,7 +1301,7 @@ static bool perf_ibs_is_kernel_br_target(struct perf_event *event,
> op_data.op_brn_ret && kernel_ip(br_target));
> }
>
> -static bool perf_ibs_swfilt_discard(struct perf_ibs *perf_ibs, struct perf_event *event,
> +static bool perf_ibs_discard_sample(struct perf_ibs *perf_ibs, struct perf_event *event,
> struct pt_regs *regs, struct perf_ibs_data *ibs_data,
> int br_target_idx)
> {
> @@ -1435,8 +1456,9 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
> regs.flags |= PERF_EFLAGS_EXACT;
> }
>
> - if ((event->attr.config2 & IBS_SW_FILTER_MASK) &&
> - perf_ibs_swfilt_discard(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
> + if (((ibs_caps & IBS_CAPS_BIT63_FILTER) ||
> + (event->attr.config2 & IBS_SW_FILTER_MASK)) &&
> + perf_ibs_discard_sample(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
> throttle = perf_event_account_interrupt(event);
> goto out;
> }
> @@ -1899,6 +1921,14 @@ static __init int amd_ibs_init(void)
>
> perf_ibs_pm_init();
>
> +#ifdef CONFIG_X86_32
> + /*
> + * IBS_CAPS_BIT63_FILTER is used for exclude_kernel/user filtering,
> + * which obviously won't work for 32 bit kernel.
> + */
> + caps &= ~IBS_CAPS_BIT63_FILTER;
> +#endif
> +
> ibs_caps = caps;
> /* make ibs_caps visible to other cpus: */
> smp_mb();
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-24 17:47 ` Ian Rogers
@ 2026-02-26 9:20 ` Ravi Bangoria
2026-02-26 16:53 ` Ian Rogers
2026-03-09 2:58 ` Ravi Bangoria
0 siblings, 2 replies; 26+ messages in thread
From: Ravi Bangoria @ 2026-02-26 9:20 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das, Stephane Eranian, Ravi Bangoria
Hi Ian,
>> IBS on future hardware adds the ability to filter IBS events by examining
>> RIP bit 63. Because Linux kernel addresses always have bit 63 set while
>> user-space addresses never do, this capability can be used as a privilege
>> filter.
>
> Since x86's top-byte-ignore/linear-address-masking leaves bit 63 could
> this break in the future if the kernel later ignores all bits,
> including bit 63, and user space wants to use bit 63 of the pointer
> for metadata?
The AMD equivalent feature is called Upper Address Ignore (UAI).
o Identifying whether an address is in kernel or user space by examining
bit 63 is so fundamental in Linux that the UAI design was revisited in
UAIv2 to restore bit 63 as canonical:
https://lore.kernel.org/lkml/6a5076ad-405e-4e5e-af55-fe2a6b01467d@www.fastmail.com
o UAI applies only to data addresses; instruction addresses must remain
canonical.
So I assume this should not be an issue, at least for now.
> Does the bit 63 assumption hold for guest operating systems?
Yes, this seems to be an issue, even with current swfilt approach. Let
me inspect the code and get back.
Thanks for the review,
Ravi
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-26 9:20 ` Ravi Bangoria
@ 2026-02-26 16:53 ` Ian Rogers
2026-03-09 2:58 ` Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2026-02-26 16:53 UTC (permalink / raw)
To: Ravi Bangoria
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das, Stephane Eranian
On Thu, Feb 26, 2026 at 1:20 AM Ravi Bangoria <ravi.bangoria@amd.com> wrote:
>
> Hi Ian,
>
> >> IBS on future hardware adds the ability to filter IBS events by examining
> >> RIP bit 63. Because Linux kernel addresses always have bit 63 set while
> >> user-space addresses never do, this capability can be used as a privilege
> >> filter.
> >
> > Since x86's top-byte-ignore/linear-address-masking leaves bit 63 could
> > this break in the future if the kernel later ignores all bits,
> > including bit 63, and user space wants to use bit 63 of the pointer
> > for metadata?
>
> The AMD equivalent feature is called Upper Address Ignore (UAI).
>
> o Identifying whether an address is in kernel or user space by examining
> bit 63 is so fundamental in Linux that the UAI design was revisited in
> UAIv2 to restore bit 63 as canonical:
> https://lore.kernel.org/lkml/6a5076ad-405e-4e5e-af55-fe2a6b01467d@www.fastmail.com
Fwiw, throwing in my 2 cents. IIRC bit 63 wasn't canonical in the
original ARM64 top byte ignore work, it seemed like a legacy thing
added to keep older x86 drivers working. Imo, this feels crufty like
passing the number of float registers used for varargs in '%al' and
the lack of non-GPR callee saves on x86. Given APX means we'll be
recompiling all x86 binaries for the extra registers, it would be nice
to have made these issues history, given runtimes an extra bit (2x the
encoding space for metadata), etc.
Thanks,
Ian
> o UAI applies only to data addresses; instruction addresses must remain
> canonical.
>
> So I assume this should not be an issue, at least for now.
>
> > Does the bit 63 assumption hold for guest operating systems?
>
> Yes, this seems to be an issue, even with current swfilt approach. Let
> me inspect the code and get back.
>
> Thanks for the review,
> Ravi
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Advertise remote socket capability
2026-02-16 4:25 ` [PATCH v2 7/7] perf/amd/ibs: Advertise remote socket capability Ravi Bangoria
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 65772b382a9865a5480ee527f3fa6e606fafc0e7
Gitweb: https://git.kernel.org/tip/65772b382a9865a5480ee527f3fa6e606fafc0e7
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:30
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:25 +01:00
perf/amd/ibs: Advertise remote socket capability
IBS OP on future hardware can indicate data source from remote socket
as well. Advertise this capability to userspace so that userspace tools
can decode IBS data accordingly.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-8-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 19 +++++++++++++++++++
arch/x86/include/asm/amd/ibs.h | 3 ++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 0a8313e..eeb607b 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -730,6 +730,7 @@ PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
+PMU_EVENT_ATTR_STRING(rmtsocket, ibs_op_rmtsocket_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -750,6 +751,12 @@ ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
}
static umode_t
+ibs_op_rmtsocket_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
+}
+
+static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return ibs_caps & IBS_CAPS_OPLDLAT ? attr->mode : 0;
@@ -802,6 +809,11 @@ static struct attribute *ibs_op_strmst_cap_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_rmtsocket_cap_attrs[] = {
+ &ibs_op_rmtsocket_cap.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_fetch_formats = {
.name = "format",
.attrs = fetch_attrs,
@@ -849,6 +861,12 @@ static struct attribute_group group_ibs_op_strmst_cap = {
.is_visible = ibs_op_strmst_is_visible,
};
+static struct attribute_group group_ibs_op_rmtsocket_cap = {
+ .name = "caps",
+ .attrs = ibs_op_rmtsocket_cap_attrs,
+ .is_visible = ibs_op_rmtsocket_is_visible,
+};
+
static const struct attribute_group *fetch_attr_groups[] = {
&group_fetch_formats,
&empty_caps_group,
@@ -938,6 +956,7 @@ static const struct attribute_group *op_attr_update[] = {
&group_ibs_op_dtlb_pgsize_cap,
&group_ibs_op_strmst_cap,
&group_ibs_op_strmst_format,
+ &group_ibs_op_rmtsocket_cap,
NULL,
};
diff --git a/arch/x86/include/asm/amd/ibs.h b/arch/x86/include/asm/amd/ibs.h
index 020916e..4eac36c 100644
--- a/arch/x86/include/asm/amd/ibs.h
+++ b/arch/x86/include/asm/amd/ibs.h
@@ -100,7 +100,8 @@ union ibs_op_data2 {
cache_hit_st:1, /* 5: cache hit state */
data_src_hi:2, /* 6-7: data source high */
strm_st:1, /* 8: streaming store */
- reserved1:55; /* 9-63: reserved */
+ rmt_socket:1, /* 9: remote socket */
+ reserved1:54; /* 10-63: reserved */
};
};
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Enable streaming store filter
2026-02-16 4:25 ` [PATCH v2 6/7] perf/amd/ibs: Enable streaming store filter Ravi Bangoria
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 57218e4794f8b6ddefe2c762020e49bd871c349c
Gitweb: https://git.kernel.org/tip/57218e4794f8b6ddefe2c762020e49bd871c349c
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:29
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:25 +01:00
perf/amd/ibs: Enable streaming store filter
IBS OP on future hardware supports recording samples only for instructions
that does streaming store. Like the existing IBS filters, samples pointing
to instruction which does not cause streaming store are discarded and IBS
restarts internally.
Example:
$ perf record -e ibs_op/strmst=1/ -- <workload>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-7-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 51 +++++++++++++++++++++++++++++++++-
arch/x86/include/asm/amd/ibs.h | 3 +-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 13ecc8d..0a8313e 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -34,6 +34,8 @@ static u32 ibs_caps;
/* attr.config1 */
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+#define IBS_OP_CONFIG1_STRMST_MASK (1ULL << 12)
+#define IBS_OP_CONFIG1_STRMST_SHIFT (12)
#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
@@ -292,6 +294,14 @@ static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
(event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
}
+static bool perf_ibs_strmst_event(struct perf_ibs *perf_ibs,
+ struct perf_event *event)
+{
+ return perf_ibs == &perf_ibs_op &&
+ (ibs_caps & IBS_CAPS_STRMST_RMTSOCKET) &&
+ (event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK);
+}
+
static int perf_ibs_init(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -419,6 +429,15 @@ static int perf_ibs_init(struct perf_event *event)
hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
}
+ if (perf_ibs_strmst_event(perf_ibs, event)) {
+ u64 strmst = event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK;
+
+ strmst >>= IBS_OP_CONFIG1_STRMST_SHIFT;
+
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ hwc->extra_reg.config |= strmst << IBS_OP_2_STRM_ST_FILTER_SHIFT;
+ }
+
/*
* If we modify hwc->sample_period, we also need to update
* hwc->last_period and hwc->period_left.
@@ -709,6 +728,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
+PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
+PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -723,6 +744,12 @@ ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
}
static umode_t
+ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
+}
+
+static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return ibs_caps & IBS_CAPS_OPLDLAT ? attr->mode : 0;
@@ -770,6 +797,11 @@ static struct attribute *ibs_op_dtlb_pgsize_cap_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_strmst_cap_attrs[] = {
+ &ibs_op_strmst_cap.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_fetch_formats = {
.name = "format",
.attrs = fetch_attrs,
@@ -811,6 +843,12 @@ static struct attribute_group group_ibs_op_dtlb_pgsize_cap = {
.is_visible = ibs_op_dtlb_pgsize_is_visible,
};
+static struct attribute_group group_ibs_op_strmst_cap = {
+ .name = "caps",
+ .attrs = ibs_op_strmst_cap_attrs,
+ .is_visible = ibs_op_strmst_is_visible,
+};
+
static const struct attribute_group *fetch_attr_groups[] = {
&group_fetch_formats,
&empty_caps_group,
@@ -856,6 +894,11 @@ static struct attribute *ibs_op_ldlat_format_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_strmst_format_attrs[] = {
+ &ibs_op_strmst_format.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_cnt_ctl = {
.name = "format",
.attrs = cnt_ctl_attrs,
@@ -880,6 +923,12 @@ static struct attribute_group group_ibs_op_ldlat_format = {
.is_visible = ibs_op_ldlat_is_visible,
};
+static struct attribute_group group_ibs_op_strmst_format = {
+ .name = "format",
+ .attrs = ibs_op_strmst_format_attrs,
+ .is_visible = ibs_op_strmst_is_visible,
+};
+
static const struct attribute_group *op_attr_update[] = {
&group_cnt_ctl,
&group_op_l3missonly,
@@ -887,6 +936,8 @@ static const struct attribute_group *op_attr_update[] = {
&group_ibs_op_ldlat_cap,
&group_ibs_op_ldlat_format,
&group_ibs_op_dtlb_pgsize_cap,
+ &group_ibs_op_strmst_cap,
+ &group_ibs_op_strmst_format,
NULL,
};
diff --git a/arch/x86/include/asm/amd/ibs.h b/arch/x86/include/asm/amd/ibs.h
index fcc8a5a..020916e 100644
--- a/arch/x86/include/asm/amd/ibs.h
+++ b/arch/x86/include/asm/amd/ibs.h
@@ -99,7 +99,8 @@ union ibs_op_data2 {
rmt_node:1, /* 4: destination node */
cache_hit_st:1, /* 5: cache hit state */
data_src_hi:2, /* 6-7: data source high */
- reserved1:56; /* 8-63: reserved */
+ strm_st:1, /* 8: streaming store */
+ reserved1:55; /* 9-63: reserved */
};
};
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-16 4:25 ` [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering Ravi Bangoria
2026-02-24 17:47 ` Ian Rogers
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2 siblings, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 62ed6df2c8078725ba5bfb6ca2d06acc8d15bd36
Gitweb: https://git.kernel.org/tip/62ed6df2c8078725ba5bfb6ca2d06acc8d15bd36
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:28
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:25 +01:00
perf/amd/ibs: Enable RIP bit63 hardware filtering
IBS on future hardware adds the ability to filter IBS events by examining
RIP bit 63. Because Linux kernel addresses always have bit 63 set while
user-space addresses never do, this capability can be used as a privilege
filter.
So far, IBS supports privilege filtering in software (swfilt=1), where
samples are dropped in the NMI handler. The RIP bit63 hardware filter
enables IBS to be usable by unprivileged users without passing swfilt
flag. So, swfilt flag will silently be ignored when the hardware
filtering capability is present.
Example (non-root user):
$ perf record -e ibs_op//u -- <workload>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-6-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 46 +++++++++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index cb3ae4e..13ecc8d 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -321,11 +321,6 @@ static int perf_ibs_init(struct perf_event *event)
event->attr.exclude_idle)
return -EINVAL;
- if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
- (event->attr.exclude_kernel || event->attr.exclude_user ||
- event->attr.exclude_hv))
- return -EINVAL;
-
ret = validate_group(event);
if (ret)
return ret;
@@ -338,6 +333,32 @@ static int perf_ibs_init(struct perf_event *event)
hwc->extra_reg.reg = perf_ibs->msr2;
}
+ if (ibs_caps & IBS_CAPS_BIT63_FILTER) {
+ if (perf_ibs == &perf_ibs_fetch) {
+ if (event->attr.exclude_kernel) {
+ hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_1;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ if (event->attr.exclude_user) {
+ hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_0;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ } else {
+ if (event->attr.exclude_kernel) {
+ hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_1;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ if (event->attr.exclude_user) {
+ hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_0;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ }
+ } else if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
+ (event->attr.exclude_kernel || event->attr.exclude_user ||
+ event->attr.exclude_hv)) {
+ return -EINVAL;
+ }
+
if (hwc->sample_period) {
if (config & perf_ibs->cnt_mask)
/* raw max_cnt may not be set */
@@ -1280,7 +1301,7 @@ static bool perf_ibs_is_kernel_br_target(struct perf_event *event,
op_data.op_brn_ret && kernel_ip(br_target));
}
-static bool perf_ibs_swfilt_discard(struct perf_ibs *perf_ibs, struct perf_event *event,
+static bool perf_ibs_discard_sample(struct perf_ibs *perf_ibs, struct perf_event *event,
struct pt_regs *regs, struct perf_ibs_data *ibs_data,
int br_target_idx)
{
@@ -1435,8 +1456,9 @@ fail:
regs.flags |= PERF_EFLAGS_EXACT;
}
- if ((event->attr.config2 & IBS_SW_FILTER_MASK) &&
- perf_ibs_swfilt_discard(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
+ if (((ibs_caps & IBS_CAPS_BIT63_FILTER) ||
+ (event->attr.config2 & IBS_SW_FILTER_MASK)) &&
+ perf_ibs_discard_sample(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
throttle = perf_event_account_interrupt(event);
goto out;
}
@@ -1899,6 +1921,14 @@ static __init int amd_ibs_init(void)
perf_ibs_pm_init();
+#ifdef CONFIG_X86_32
+ /*
+ * IBS_CAPS_BIT63_FILTER is used for exclude_kernel/user filtering,
+ * which obviously won't work for 32 bit kernel.
+ */
+ caps &= ~IBS_CAPS_BIT63_FILTER;
+#endif
+
ibs_caps = caps;
/* make ibs_caps visible to other cpus: */
smp_mb();
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Enable fetch latency filtering
2026-02-16 4:25 ` [PATCH v2 4/7] perf/amd/ibs: Enable fetch latency filtering Ravi Bangoria
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: ba6056cabd0fa2c98d016a4ed01731ba009a340b
Gitweb: https://git.kernel.org/tip/ba6056cabd0fa2c98d016a4ed01731ba009a340b
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:27
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:24 +01:00
perf/amd/ibs: Enable fetch latency filtering
IBS Fetch on future hardware adds fetch latency filtering which
generates interrupt only when FetchLat value exceeds a programmable
threshold.
Hardware allows threshold in 128-cycle increment (i.e. 128, 256, 384
etc.) from 128 to 1920 cycles. Like the existing IBS filters, samples
that fail the latency test are dropped and IBS restarts internally.
Since hardware supports threshold in multiple of 128, add a software
filter on top to support latency threshold with the granularity of 1
cycle in between [128-1920].
Example:
# perf record -e ibs_fetch/fetchlat=128/ -c 10000 -a -- sleep 5
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-5-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 66 +++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index b7f0aad..cb3ae4e 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -35,6 +35,8 @@ static u32 ibs_caps;
/* attr.config1 */
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
+
/*
* IBS states:
*
@@ -282,6 +284,14 @@ static bool perf_ibs_ldlat_event(struct perf_ibs *perf_ibs,
(event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK);
}
+static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
+ struct perf_event *event)
+{
+ return perf_ibs == &perf_ibs_fetch &&
+ (ibs_caps & IBS_CAPS_FETCHLAT) &&
+ (event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
+}
+
static int perf_ibs_init(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -377,6 +387,17 @@ static int perf_ibs_init(struct perf_event *event)
config |= IBS_OP_L3MISSONLY;
}
+ if (perf_ibs_fetch_lat_event(perf_ibs, event)) {
+ u64 fetchlat = event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK;
+
+ if (fetchlat < 128 || fetchlat > 1920)
+ return -EINVAL;
+ fetchlat >>= 7;
+
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
+ }
+
/*
* If we modify hwc->sample_period, we also need to update
* hwc->last_period and hwc->period_left.
@@ -665,6 +686,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_format, "config1:0-11");
PMU_EVENT_ATTR_STRING(zen4_ibs_extensions, zen4_ibs_extensions, "1");
PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
+PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
+PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -673,6 +696,12 @@ zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int
}
static umode_t
+ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_FETCHLAT ? attr->mode : 0;
+}
+
+static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return ibs_caps & IBS_CAPS_OPLDLAT ? attr->mode : 0;
@@ -700,6 +729,16 @@ static struct attribute *zen4_ibs_extensions_attrs[] = {
NULL,
};
+static struct attribute *ibs_fetch_lat_format_attrs[] = {
+ &ibs_fetch_lat_format.attr.attr,
+ NULL,
+};
+
+static struct attribute *ibs_fetch_lat_cap_attrs[] = {
+ &ibs_fetch_lat_cap.attr.attr,
+ NULL,
+};
+
static struct attribute *ibs_op_ldlat_cap_attrs[] = {
&ibs_op_ldlat_cap.attr.attr,
NULL,
@@ -727,6 +766,18 @@ static struct attribute_group group_zen4_ibs_extensions = {
.is_visible = zen4_ibs_extensions_is_visible,
};
+static struct attribute_group group_ibs_fetch_lat_cap = {
+ .name = "caps",
+ .attrs = ibs_fetch_lat_cap_attrs,
+ .is_visible = ibs_fetch_lat_is_visible,
+};
+
+static struct attribute_group group_ibs_fetch_lat_format = {
+ .name = "format",
+ .attrs = ibs_fetch_lat_format_attrs,
+ .is_visible = ibs_fetch_lat_is_visible,
+};
+
static struct attribute_group group_ibs_op_ldlat_cap = {
.name = "caps",
.attrs = ibs_op_ldlat_cap_attrs,
@@ -748,6 +799,8 @@ static const struct attribute_group *fetch_attr_groups[] = {
static const struct attribute_group *fetch_attr_update[] = {
&group_fetch_l3missonly,
&group_zen4_ibs_extensions,
+ &group_ibs_fetch_lat_cap,
+ &group_ibs_fetch_lat_format,
NULL,
};
@@ -1191,7 +1244,8 @@ static int perf_ibs_get_offset_max(struct perf_ibs *perf_ibs,
{
if (event->attr.sample_type & PERF_SAMPLE_RAW ||
perf_ibs_is_mem_sample_type(perf_ibs, event) ||
- perf_ibs_ldlat_event(perf_ibs, event))
+ perf_ibs_ldlat_event(perf_ibs, event) ||
+ perf_ibs_fetch_lat_event(perf_ibs, event))
return perf_ibs->offset_max;
else if (check_rip)
return 3;
@@ -1333,6 +1387,16 @@ fail:
}
}
+ if (perf_ibs_fetch_lat_event(perf_ibs, event)) {
+ union ibs_fetch_ctl fetch_ctl;
+
+ fetch_ctl.val = ibs_data.regs[ibs_fetch_msr_idx(MSR_AMD64_IBSFETCHCTL)];
+ if (fetch_ctl.fetch_lat < (event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK)) {
+ throttle = perf_event_account_interrupt(event);
+ goto out;
+ }
+ }
+
/*
* Read IbsBrTarget, IbsOpData4, and IbsExtdCtl separately
* depending on their availability.
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] to eliminate RMW race
2026-02-16 4:25 ` [PATCH v2 3/7] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race Ravi Bangoria
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
2026-02-28 11:01 ` Peter Zijlstra
2026-02-28 11:07 ` [tip: perf/core] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] " tip-bot2 for Ravi Bangoria
1 sibling, 1 reply; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 28063f05f38b5c114b0c8d2b0200604196b085ef
Gitweb: https://git.kernel.org/tip/28063f05f38b5c114b0c8d2b0200604196b085ef
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:26
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:24 +01:00
to eliminate RMW race
The existing IBS_{FETCH|OP}_CTL MSRs combine control and status bits
which leads to RMW race between HW and SW:
HW SW
------------------------ ------------------------------
config = rdmsr(IBS_OP_CTL);
config &= ~EN;
Set IBS_OP_CTL[Val] to 1
trigger NMI
wrmsr(IBS_OP_CTL, config);
// Val is accidentally cleared
Future hardware adds a control-only MSR, IBS_{FETCH|OP}_CTL2, which
provides a second-level "disable" bit (Dis). IBS is now:
Enabled: IBS_{FETCH|OP}_CTL[En] = 1 && IBS_{FETCH|OP}_CTL2[Dis] = 0
Disabled: IBS_{FETCH|OP}_CTL[En] = 0 || IBS_{FETCH|OP}_CTL2[Dis] = 1
The separate "Dis" bit lets software disable IBS without touching any
status fields, eliminating the hardware/software race.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-4-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 45 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 2e8fb06..b7f0aad 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -86,9 +86,11 @@ struct cpu_perf_ibs {
struct perf_ibs {
struct pmu pmu;
unsigned int msr;
+ unsigned int msr2;
u64 config_mask;
u64 cnt_mask;
u64 enable_mask;
+ u64 disable_mask;
u64 valid_mask;
u16 min_period;
u64 max_period;
@@ -292,6 +294,8 @@ static int perf_ibs_init(struct perf_event *event)
return -ENOENT;
config = event->attr.config;
+ hwc->extra_reg.config = 0;
+ hwc->extra_reg.reg = 0;
if (event->pmu != &perf_ibs->pmu)
return -ENOENT;
@@ -319,6 +323,11 @@ static int perf_ibs_init(struct perf_event *event)
if (perf_allow_kernel())
hwc->flags |= PERF_X86_EVENT_UNPRIVILEGED;
+ if (ibs_caps & IBS_CAPS_DIS) {
+ hwc->extra_reg.config &= ~perf_ibs->disable_mask;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+
if (hwc->sample_period) {
if (config & perf_ibs->cnt_mask)
/* raw max_cnt may not be set */
@@ -448,6 +457,9 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
wrmsrq(hwc->config_base, tmp & ~perf_ibs->enable_mask);
wrmsrq(hwc->config_base, tmp | perf_ibs->enable_mask);
+
+ if (hwc->extra_reg.reg)
+ wrmsrq(hwc->extra_reg.reg, hwc->extra_reg.config);
}
/*
@@ -460,6 +472,11 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
struct hw_perf_event *hwc, u64 config)
{
+ if (ibs_caps & IBS_CAPS_DIS) {
+ wrmsrq(hwc->extra_reg.reg, perf_ibs->disable_mask);
+ return;
+ }
+
config &= ~perf_ibs->cnt_mask;
if (boot_cpu_data.x86 == 0x10)
wrmsrq(hwc->config_base, config);
@@ -812,6 +829,7 @@ static struct perf_ibs perf_ibs_fetch = {
.check_period = perf_ibs_check_period,
},
.msr = MSR_AMD64_IBSFETCHCTL,
+ .msr2 = MSR_AMD64_IBSFETCHCTL2,
.config_mask = IBS_FETCH_MAX_CNT | IBS_FETCH_RAND_EN,
.cnt_mask = IBS_FETCH_MAX_CNT,
.enable_mask = IBS_FETCH_ENABLE,
@@ -837,6 +855,7 @@ static struct perf_ibs perf_ibs_op = {
.check_period = perf_ibs_check_period,
},
.msr = MSR_AMD64_IBSOPCTL,
+ .msr2 = MSR_AMD64_IBSOPCTL2,
.config_mask = IBS_OP_MAX_CNT,
.cnt_mask = IBS_OP_MAX_CNT | IBS_OP_CUR_CNT |
IBS_OP_CUR_CNT_RAND,
@@ -1394,6 +1413,9 @@ fail:
out:
if (!throttle) {
+ if (ibs_caps & IBS_CAPS_DIS)
+ wrmsrq(hwc->extra_reg.reg, perf_ibs->disable_mask);
+
if (perf_ibs == &perf_ibs_op) {
if (ibs_caps & IBS_CAPS_OPCNTEXT) {
new_config = period & IBS_OP_MAX_CNT_EXT_MASK;
@@ -1465,6 +1487,9 @@ static __init int perf_ibs_fetch_init(void)
if (ibs_caps & IBS_CAPS_ZEN4)
perf_ibs_fetch.config_mask |= IBS_FETCH_L3MISSONLY;
+ if (ibs_caps & IBS_CAPS_DIS)
+ perf_ibs_fetch.disable_mask = IBS_FETCH_2_DIS;
+
perf_ibs_fetch.pmu.attr_groups = fetch_attr_groups;
perf_ibs_fetch.pmu.attr_update = fetch_attr_update;
@@ -1486,6 +1511,9 @@ static __init int perf_ibs_op_init(void)
if (ibs_caps & IBS_CAPS_ZEN4)
perf_ibs_op.config_mask |= IBS_OP_L3MISSONLY;
+ if (ibs_caps & IBS_CAPS_DIS)
+ perf_ibs_op.disable_mask = IBS_OP_2_DIS;
+
perf_ibs_op.pmu.attr_groups = op_attr_groups;
perf_ibs_op.pmu.attr_update = op_attr_update;
@@ -1732,6 +1760,23 @@ static void clear_APIC_ibs(void)
static int x86_pmu_amd_ibs_starting_cpu(unsigned int cpu)
{
setup_APIC_ibs();
+
+ if (ibs_caps & IBS_CAPS_DIS) {
+ /*
+ * IBS enable sequence:
+ * CTL[En] = 1;
+ * CTL2[Dis] = 0;
+ *
+ * IBS disable sequence:
+ * CTL2[Dis] = 1;
+ *
+ * Set CTL2[Dis] when CPU comes up. This is needed to make
+ * enable sequence effective.
+ */
+ wrmsrq(MSR_AMD64_IBSFETCHCTL2, IBS_FETCH_2_DIS);
+ wrmsrq(MSR_AMD64_IBSOPCTL2, IBS_OP_2_DIS);
+ }
+
return 0;
}
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Add new MSRs and CPUID bits definitions
2026-02-16 4:25 ` [PATCH v2 2/7] perf/amd/ibs: Add new MSRs and CPUID bits definitions Ravi Bangoria
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
0 siblings, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: e267b4178134e36e83ddfe4f7f5b4b162a286148
Gitweb: https://git.kernel.org/tip/e267b4178134e36e83ddfe4f7f5b4b162a286148
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:25
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:24 +01:00
perf/amd/ibs: Add new MSRs and CPUID bits definitions
IBS on upcoming microarch introduced two new control MSRs and couple of
new features. Define macros for them.
New capabilities:
o IBS_CAPS_DIS: Alternate Fetch and Op IBS disable bits
o IBS_CAPS_FETCHLAT: Fetch Latency filter
o IBS_CAPS_BIT63_FILTER: Virtual address bit 63 based filters for Fetch
and Op
o IBS_CAPS_STRMST_RMTSOCKET: Streaming store filter and indicator,
remote socket indicator
New control MSRs for above features:
o MSR_AMD64_IBSFETCHCTL2
o MSR_AMD64_IBSOPCTL2
Also do cosmetic alignment changes.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260216042530.1546-3-ravi.bangoria@amd.com
---
arch/x86/include/asm/msr-index.h | 2 +-
arch/x86/include/asm/perf_event.h | 56 +++++++++++++++++++-----------
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index da5275d..e25434d 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -698,6 +698,8 @@
#define MSR_AMD64_IBSBRTARGET 0xc001103b
#define MSR_AMD64_ICIBSEXTDCTL 0xc001103c
#define MSR_AMD64_IBSOPDATA4 0xc001103d
+#define MSR_AMD64_IBSOPCTL2 0xc001103e
+#define MSR_AMD64_IBSFETCHCTL2 0xc001103f
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
#define MSR_AMD64_SVM_AVIC_DOORBELL 0xc001011b
#define MSR_AMD64_VM_PAGE_FLUSH 0xc001011e
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 67ecb98..752cb31 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -643,6 +643,10 @@ struct arch_pebs_cntr_header {
#define IBS_CAPS_OPDATA4 (1U<<10)
#define IBS_CAPS_ZEN4 (1U<<11)
#define IBS_CAPS_OPLDLAT (1U<<12)
+#define IBS_CAPS_DIS (1U<<13)
+#define IBS_CAPS_FETCHLAT (1U<<14)
+#define IBS_CAPS_BIT63_FILTER (1U<<15)
+#define IBS_CAPS_STRMST_RMTSOCKET (1U<<16)
#define IBS_CAPS_OPDTLBPGSIZE (1U<<19)
#define IBS_CAPS_DEFAULT (IBS_CAPS_AVAIL \
@@ -657,32 +661,44 @@ struct arch_pebs_cntr_header {
#define IBSCTL_LVT_OFFSET_MASK 0x0F
/* IBS fetch bits/masks */
-#define IBS_FETCH_L3MISSONLY (1ULL<<59)
-#define IBS_FETCH_RAND_EN (1ULL<<57)
-#define IBS_FETCH_VAL (1ULL<<49)
-#define IBS_FETCH_ENABLE (1ULL<<48)
-#define IBS_FETCH_CNT 0xFFFF0000ULL
-#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+#define IBS_FETCH_L3MISSONLY (1ULL << 59)
+#define IBS_FETCH_RAND_EN (1ULL << 57)
+#define IBS_FETCH_VAL (1ULL << 49)
+#define IBS_FETCH_ENABLE (1ULL << 48)
+#define IBS_FETCH_CNT 0xFFFF0000ULL
+#define IBS_FETCH_MAX_CNT 0x0000FFFFULL
+
+#define IBS_FETCH_2_DIS (1ULL << 0)
+#define IBS_FETCH_2_FETCHLAT_FILTER (0xFULL << 1)
+#define IBS_FETCH_2_FETCHLAT_FILTER_SHIFT (1)
+#define IBS_FETCH_2_EXCL_RIP_63_EQ_1 (1ULL << 5)
+#define IBS_FETCH_2_EXCL_RIP_63_EQ_0 (1ULL << 6)
/*
* IBS op bits/masks
* The lower 7 bits of the current count are random bits
* preloaded by hardware and ignored in software
*/
-#define IBS_OP_LDLAT_EN (1ULL<<63)
-#define IBS_OP_LDLAT_THRSH (0xFULL<<59)
-#define IBS_OP_LDLAT_THRSH_SHIFT (59)
-#define IBS_OP_CUR_CNT (0xFFF80ULL<<32)
-#define IBS_OP_CUR_CNT_RAND (0x0007FULL<<32)
-#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL<<52)
-#define IBS_OP_CNT_CTL (1ULL<<19)
-#define IBS_OP_VAL (1ULL<<18)
-#define IBS_OP_ENABLE (1ULL<<17)
-#define IBS_OP_L3MISSONLY (1ULL<<16)
-#define IBS_OP_MAX_CNT 0x0000FFFFULL
-#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
-#define IBS_OP_MAX_CNT_EXT_MASK (0x7FULL<<20) /* separate upper 7 bits */
-#define IBS_RIP_INVALID (1ULL<<38)
+#define IBS_OP_LDLAT_EN (1ULL << 63)
+#define IBS_OP_LDLAT_THRSH (0xFULL << 59)
+#define IBS_OP_LDLAT_THRSH_SHIFT (59)
+#define IBS_OP_CUR_CNT (0xFFF80ULL << 32)
+#define IBS_OP_CUR_CNT_RAND (0x0007FULL << 32)
+#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL << 52)
+#define IBS_OP_CNT_CTL (1ULL << 19)
+#define IBS_OP_VAL (1ULL << 18)
+#define IBS_OP_ENABLE (1ULL << 17)
+#define IBS_OP_L3MISSONLY (1ULL << 16)
+#define IBS_OP_MAX_CNT 0x0000FFFFULL
+#define IBS_OP_MAX_CNT_EXT 0x007FFFFFULL /* not a register bit mask */
+#define IBS_OP_MAX_CNT_EXT_MASK (0x7FULL << 20) /* separate upper 7 bits */
+#define IBS_RIP_INVALID (1ULL << 38)
+
+#define IBS_OP_2_DIS (1ULL << 0)
+#define IBS_OP_2_EXCL_RIP_63_EQ_0 (1ULL << 1)
+#define IBS_OP_2_EXCL_RIP_63_EQ_1 (1ULL << 2)
+#define IBS_OP_2_STRM_ST_FILTER (1ULL << 3)
+#define IBS_OP_2_STRM_ST_FILTER_SHIFT (3)
#ifdef CONFIG_X86_LOCAL_APIC
extern u32 get_ibs_caps(void);
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Define macro for ldlat mask and shift
2026-02-16 4:25 ` [PATCH v2 1/7] perf/amd/ibs: Define macro for ldlat mask and shift Ravi Bangoria
@ 2026-02-28 10:56 ` tip-bot2 for Ravi Bangoria
0 siblings, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 10:56 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), Dapeng Mi, x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: f9d55ccf0199d1a80c2519084578f0c345dedd2f
Gitweb: https://git.kernel.org/tip/f9d55ccf0199d1a80c2519084578f0c345dedd2f
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:24
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Fri, 27 Feb 2026 16:40:24 +01:00
perf/amd/ibs: Define macro for ldlat mask and shift
Load latency filter threshold is encoded in config1[11:0]. Define a mask
for it instead of hardcoded 0xFFF. Unlike "config" fields whose layout
maps to PERF_{FETCH|OP}_CTL MSR, layout of "config1" is custom defined
so a new set of macros are needed for "config1" fields.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260216042530.1546-2-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 11 +++++++----
arch/x86/include/asm/perf_event.h | 1 +
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 32e6456..2e8fb06 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -32,6 +32,9 @@ static u32 ibs_caps;
/* attr.config2 */
#define IBS_SW_FILTER_MASK 1
+/* attr.config1 */
+#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+
/*
* IBS states:
*
@@ -274,7 +277,7 @@ static bool perf_ibs_ldlat_event(struct perf_ibs *perf_ibs,
{
return perf_ibs == &perf_ibs_op &&
(ibs_caps & IBS_CAPS_OPLDLAT) &&
- (event->attr.config1 & 0xFFF);
+ (event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK);
}
static int perf_ibs_init(struct perf_event *event)
@@ -352,13 +355,13 @@ static int perf_ibs_init(struct perf_event *event)
}
if (perf_ibs_ldlat_event(perf_ibs, event)) {
- u64 ldlat = event->attr.config1 & 0xFFF;
+ u64 ldlat = event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK;
if (ldlat < 128 || ldlat > 2048)
return -EINVAL;
ldlat >>= 7;
- config |= (ldlat - 1) << 59;
+ config |= (ldlat - 1) << IBS_OP_LDLAT_THRSH_SHIFT;
config |= IBS_OP_LDLAT_EN;
if (cpu_feature_enabled(X86_FEATURE_ZEN5))
@@ -1305,7 +1308,7 @@ fail:
* within [128, 2048] range.
*/
if (!op_data3.ld_op || !op_data3.dc_miss ||
- op_data3.dc_miss_lat <= (event->attr.config1 & 0xFFF)) {
+ op_data3.dc_miss_lat <= (event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK)) {
throttle = perf_event_account_interrupt(event);
goto out;
}
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index ff5acb8..67ecb98 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -671,6 +671,7 @@ struct arch_pebs_cntr_header {
*/
#define IBS_OP_LDLAT_EN (1ULL<<63)
#define IBS_OP_LDLAT_THRSH (0xFULL<<59)
+#define IBS_OP_LDLAT_THRSH_SHIFT (59)
#define IBS_OP_CUR_CNT (0xFFF80ULL<<32)
#define IBS_OP_CUR_CNT_RAND (0x0007FULL<<32)
#define IBS_OP_CUR_CNT_EXT_MASK (0x7FULL<<52)
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [tip: perf/core] to eliminate RMW race
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
@ 2026-02-28 11:01 ` Peter Zijlstra
0 siblings, 0 replies; 26+ messages in thread
From: Peter Zijlstra @ 2026-02-28 11:01 UTC (permalink / raw)
To: linux-kernel; +Cc: linux-tip-commits, Ravi Bangoria, x86
On Sat, Feb 28, 2026 at 10:56:37AM -0000, tip-bot2 for Ravi Bangoria wrote:
> The following commit has been merged into the perf/core branch of tip:
>
> Commit-ID: 28063f05f38b5c114b0c8d2b0200604196b085ef
> Gitweb: https://git.kernel.org/tip/28063f05f38b5c114b0c8d2b0200604196b085ef
> Author: Ravi Bangoria <ravi.bangoria@amd.com>
> AuthorDate: Mon, 16 Feb 2026 04:25:26
> Committer: Peter Zijlstra <peterz@infradead.org>
> CommitterDate: Fri, 27 Feb 2026 16:40:24 +01:00
>
> to eliminate RMW race
Argh, Subject got mangled and I failed to spot sooner :-(
Let me go rebase to fix.
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Advertise remote socket capability
2026-02-16 4:25 ` [PATCH v2 7/7] perf/amd/ibs: Advertise remote socket capability Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
@ 2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 11:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: b2ea0f541d354c10186a894e8bf5bf83abf8a517
Gitweb: https://git.kernel.org/tip/b2ea0f541d354c10186a894e8bf5bf83abf8a517
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:30
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Sat, 28 Feb 2026 12:03:29 +01:00
perf/amd/ibs: Advertise remote socket capability
IBS OP on future hardware can indicate data source from remote socket
as well. Advertise this capability to userspace so that userspace tools
can decode IBS data accordingly.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-8-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 19 +++++++++++++++++++
arch/x86/include/asm/amd/ibs.h | 3 ++-
2 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 0a8313e..eeb607b 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -730,6 +730,7 @@ PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
+PMU_EVENT_ATTR_STRING(rmtsocket, ibs_op_rmtsocket_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -750,6 +751,12 @@ ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
}
static umode_t
+ibs_op_rmtsocket_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
+}
+
+static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return ibs_caps & IBS_CAPS_OPLDLAT ? attr->mode : 0;
@@ -802,6 +809,11 @@ static struct attribute *ibs_op_strmst_cap_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_rmtsocket_cap_attrs[] = {
+ &ibs_op_rmtsocket_cap.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_fetch_formats = {
.name = "format",
.attrs = fetch_attrs,
@@ -849,6 +861,12 @@ static struct attribute_group group_ibs_op_strmst_cap = {
.is_visible = ibs_op_strmst_is_visible,
};
+static struct attribute_group group_ibs_op_rmtsocket_cap = {
+ .name = "caps",
+ .attrs = ibs_op_rmtsocket_cap_attrs,
+ .is_visible = ibs_op_rmtsocket_is_visible,
+};
+
static const struct attribute_group *fetch_attr_groups[] = {
&group_fetch_formats,
&empty_caps_group,
@@ -938,6 +956,7 @@ static const struct attribute_group *op_attr_update[] = {
&group_ibs_op_dtlb_pgsize_cap,
&group_ibs_op_strmst_cap,
&group_ibs_op_strmst_format,
+ &group_ibs_op_rmtsocket_cap,
NULL,
};
diff --git a/arch/x86/include/asm/amd/ibs.h b/arch/x86/include/asm/amd/ibs.h
index 020916e..4eac36c 100644
--- a/arch/x86/include/asm/amd/ibs.h
+++ b/arch/x86/include/asm/amd/ibs.h
@@ -100,7 +100,8 @@ union ibs_op_data2 {
cache_hit_st:1, /* 5: cache hit state */
data_src_hi:2, /* 6-7: data source high */
strm_st:1, /* 8: streaming store */
- reserved1:55; /* 9-63: reserved */
+ rmt_socket:1, /* 9: remote socket */
+ reserved1:54; /* 10-63: reserved */
};
};
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Enable streaming store filter
2026-02-16 4:25 ` [PATCH v2 6/7] perf/amd/ibs: Enable streaming store filter Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
@ 2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 11:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 8ae68bfec97596a3656ce8d0a7b1240d888eab10
Gitweb: https://git.kernel.org/tip/8ae68bfec97596a3656ce8d0a7b1240d888eab10
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:29
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Sat, 28 Feb 2026 12:03:29 +01:00
perf/amd/ibs: Enable streaming store filter
IBS OP on future hardware supports recording samples only for instructions
that does streaming store. Like the existing IBS filters, samples pointing
to instruction which does not cause streaming store are discarded and IBS
restarts internally.
Example:
$ perf record -e ibs_op/strmst=1/ -- <workload>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-7-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 51 +++++++++++++++++++++++++++++++++-
arch/x86/include/asm/amd/ibs.h | 3 +-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 13ecc8d..0a8313e 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -34,6 +34,8 @@ static u32 ibs_caps;
/* attr.config1 */
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+#define IBS_OP_CONFIG1_STRMST_MASK (1ULL << 12)
+#define IBS_OP_CONFIG1_STRMST_SHIFT (12)
#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
@@ -292,6 +294,14 @@ static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
(event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
}
+static bool perf_ibs_strmst_event(struct perf_ibs *perf_ibs,
+ struct perf_event *event)
+{
+ return perf_ibs == &perf_ibs_op &&
+ (ibs_caps & IBS_CAPS_STRMST_RMTSOCKET) &&
+ (event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK);
+}
+
static int perf_ibs_init(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -419,6 +429,15 @@ static int perf_ibs_init(struct perf_event *event)
hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
}
+ if (perf_ibs_strmst_event(perf_ibs, event)) {
+ u64 strmst = event->attr.config1 & IBS_OP_CONFIG1_STRMST_MASK;
+
+ strmst >>= IBS_OP_CONFIG1_STRMST_SHIFT;
+
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ hwc->extra_reg.config |= strmst << IBS_OP_2_STRM_ST_FILTER_SHIFT;
+ }
+
/*
* If we modify hwc->sample_period, we also need to update
* hwc->last_period and hwc->period_left.
@@ -709,6 +728,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
+PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_format, "config1:12");
+PMU_EVENT_ATTR_STRING(strmst, ibs_op_strmst_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -723,6 +744,12 @@ ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
}
static umode_t
+ibs_op_strmst_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_STRMST_RMTSOCKET ? attr->mode : 0;
+}
+
+static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return ibs_caps & IBS_CAPS_OPLDLAT ? attr->mode : 0;
@@ -770,6 +797,11 @@ static struct attribute *ibs_op_dtlb_pgsize_cap_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_strmst_cap_attrs[] = {
+ &ibs_op_strmst_cap.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_fetch_formats = {
.name = "format",
.attrs = fetch_attrs,
@@ -811,6 +843,12 @@ static struct attribute_group group_ibs_op_dtlb_pgsize_cap = {
.is_visible = ibs_op_dtlb_pgsize_is_visible,
};
+static struct attribute_group group_ibs_op_strmst_cap = {
+ .name = "caps",
+ .attrs = ibs_op_strmst_cap_attrs,
+ .is_visible = ibs_op_strmst_is_visible,
+};
+
static const struct attribute_group *fetch_attr_groups[] = {
&group_fetch_formats,
&empty_caps_group,
@@ -856,6 +894,11 @@ static struct attribute *ibs_op_ldlat_format_attrs[] = {
NULL,
};
+static struct attribute *ibs_op_strmst_format_attrs[] = {
+ &ibs_op_strmst_format.attr.attr,
+ NULL,
+};
+
static struct attribute_group group_cnt_ctl = {
.name = "format",
.attrs = cnt_ctl_attrs,
@@ -880,6 +923,12 @@ static struct attribute_group group_ibs_op_ldlat_format = {
.is_visible = ibs_op_ldlat_is_visible,
};
+static struct attribute_group group_ibs_op_strmst_format = {
+ .name = "format",
+ .attrs = ibs_op_strmst_format_attrs,
+ .is_visible = ibs_op_strmst_is_visible,
+};
+
static const struct attribute_group *op_attr_update[] = {
&group_cnt_ctl,
&group_op_l3missonly,
@@ -887,6 +936,8 @@ static const struct attribute_group *op_attr_update[] = {
&group_ibs_op_ldlat_cap,
&group_ibs_op_ldlat_format,
&group_ibs_op_dtlb_pgsize_cap,
+ &group_ibs_op_strmst_cap,
+ &group_ibs_op_strmst_format,
NULL,
};
diff --git a/arch/x86/include/asm/amd/ibs.h b/arch/x86/include/asm/amd/ibs.h
index fcc8a5a..020916e 100644
--- a/arch/x86/include/asm/amd/ibs.h
+++ b/arch/x86/include/asm/amd/ibs.h
@@ -99,7 +99,8 @@ union ibs_op_data2 {
rmt_node:1, /* 4: destination node */
cache_hit_st:1, /* 5: cache hit state */
data_src_hi:2, /* 6-7: data source high */
- reserved1:56; /* 8-63: reserved */
+ strm_st:1, /* 8: streaming store */
+ reserved1:55; /* 9-63: reserved */
};
};
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-16 4:25 ` [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering Ravi Bangoria
2026-02-24 17:47 ` Ian Rogers
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
@ 2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2 siblings, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 11:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 8c63c4af92ac5f041ce437c1f2a31ce3ef03c585
Gitweb: https://git.kernel.org/tip/8c63c4af92ac5f041ce437c1f2a31ce3ef03c585
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:28
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Sat, 28 Feb 2026 12:03:29 +01:00
perf/amd/ibs: Enable RIP bit63 hardware filtering
IBS on future hardware adds the ability to filter IBS events by examining
RIP bit 63. Because Linux kernel addresses always have bit 63 set while
user-space addresses never do, this capability can be used as a privilege
filter.
So far, IBS supports privilege filtering in software (swfilt=1), where
samples are dropped in the NMI handler. The RIP bit63 hardware filter
enables IBS to be usable by unprivileged users without passing swfilt
flag. So, swfilt flag will silently be ignored when the hardware
filtering capability is present.
Example (non-root user):
$ perf record -e ibs_op//u -- <workload>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-6-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 46 +++++++++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index cb3ae4e..13ecc8d 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -321,11 +321,6 @@ static int perf_ibs_init(struct perf_event *event)
event->attr.exclude_idle)
return -EINVAL;
- if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
- (event->attr.exclude_kernel || event->attr.exclude_user ||
- event->attr.exclude_hv))
- return -EINVAL;
-
ret = validate_group(event);
if (ret)
return ret;
@@ -338,6 +333,32 @@ static int perf_ibs_init(struct perf_event *event)
hwc->extra_reg.reg = perf_ibs->msr2;
}
+ if (ibs_caps & IBS_CAPS_BIT63_FILTER) {
+ if (perf_ibs == &perf_ibs_fetch) {
+ if (event->attr.exclude_kernel) {
+ hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_1;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ if (event->attr.exclude_user) {
+ hwc->extra_reg.config |= IBS_FETCH_2_EXCL_RIP_63_EQ_0;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ } else {
+ if (event->attr.exclude_kernel) {
+ hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_1;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ if (event->attr.exclude_user) {
+ hwc->extra_reg.config |= IBS_OP_2_EXCL_RIP_63_EQ_0;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+ }
+ } else if (!(event->attr.config2 & IBS_SW_FILTER_MASK) &&
+ (event->attr.exclude_kernel || event->attr.exclude_user ||
+ event->attr.exclude_hv)) {
+ return -EINVAL;
+ }
+
if (hwc->sample_period) {
if (config & perf_ibs->cnt_mask)
/* raw max_cnt may not be set */
@@ -1280,7 +1301,7 @@ static bool perf_ibs_is_kernel_br_target(struct perf_event *event,
op_data.op_brn_ret && kernel_ip(br_target));
}
-static bool perf_ibs_swfilt_discard(struct perf_ibs *perf_ibs, struct perf_event *event,
+static bool perf_ibs_discard_sample(struct perf_ibs *perf_ibs, struct perf_event *event,
struct pt_regs *regs, struct perf_ibs_data *ibs_data,
int br_target_idx)
{
@@ -1435,8 +1456,9 @@ fail:
regs.flags |= PERF_EFLAGS_EXACT;
}
- if ((event->attr.config2 & IBS_SW_FILTER_MASK) &&
- perf_ibs_swfilt_discard(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
+ if (((ibs_caps & IBS_CAPS_BIT63_FILTER) ||
+ (event->attr.config2 & IBS_SW_FILTER_MASK)) &&
+ perf_ibs_discard_sample(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
throttle = perf_event_account_interrupt(event);
goto out;
}
@@ -1899,6 +1921,14 @@ static __init int amd_ibs_init(void)
perf_ibs_pm_init();
+#ifdef CONFIG_X86_32
+ /*
+ * IBS_CAPS_BIT63_FILTER is used for exclude_kernel/user filtering,
+ * which obviously won't work for 32 bit kernel.
+ */
+ caps &= ~IBS_CAPS_BIT63_FILTER;
+#endif
+
ibs_caps = caps;
/* make ibs_caps visible to other cpus: */
smp_mb();
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Enable fetch latency filtering
2026-02-16 4:25 ` [PATCH v2 4/7] perf/amd/ibs: Enable fetch latency filtering Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
@ 2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 11:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: 35247fa60b74e1c643423c3bc7c6a59cbca262bb
Gitweb: https://git.kernel.org/tip/35247fa60b74e1c643423c3bc7c6a59cbca262bb
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:27
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Sat, 28 Feb 2026 12:03:29 +01:00
perf/amd/ibs: Enable fetch latency filtering
IBS Fetch on future hardware adds fetch latency filtering which
generates interrupt only when FetchLat value exceeds a programmable
threshold.
Hardware allows threshold in 128-cycle increment (i.e. 128, 256, 384
etc.) from 128 to 1920 cycles. Like the existing IBS filters, samples
that fail the latency test are dropped and IBS restarts internally.
Since hardware supports threshold in multiple of 128, add a software
filter on top to support latency threshold with the granularity of 1
cycle in between [128-1920].
Example:
# perf record -e ibs_fetch/fetchlat=128/ -c 10000 -a -- sleep 5
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-5-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 66 +++++++++++++++++++++++++++++++++++++-
1 file changed, 65 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index b7f0aad..cb3ae4e 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -35,6 +35,8 @@ static u32 ibs_caps;
/* attr.config1 */
#define IBS_OP_CONFIG1_LDLAT_MASK (0xFFFULL << 0)
+#define IBS_FETCH_CONFIG1_FETCHLAT_MASK (0x7FFULL << 0)
+
/*
* IBS states:
*
@@ -282,6 +284,14 @@ static bool perf_ibs_ldlat_event(struct perf_ibs *perf_ibs,
(event->attr.config1 & IBS_OP_CONFIG1_LDLAT_MASK);
}
+static bool perf_ibs_fetch_lat_event(struct perf_ibs *perf_ibs,
+ struct perf_event *event)
+{
+ return perf_ibs == &perf_ibs_fetch &&
+ (ibs_caps & IBS_CAPS_FETCHLAT) &&
+ (event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK);
+}
+
static int perf_ibs_init(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -377,6 +387,17 @@ static int perf_ibs_init(struct perf_event *event)
config |= IBS_OP_L3MISSONLY;
}
+ if (perf_ibs_fetch_lat_event(perf_ibs, event)) {
+ u64 fetchlat = event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK;
+
+ if (fetchlat < 128 || fetchlat > 1920)
+ return -EINVAL;
+ fetchlat >>= 7;
+
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ hwc->extra_reg.config |= fetchlat << IBS_FETCH_2_FETCHLAT_FILTER_SHIFT;
+ }
+
/*
* If we modify hwc->sample_period, we also need to update
* hwc->last_period and hwc->period_left.
@@ -665,6 +686,8 @@ PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_format, "config1:0-11");
PMU_EVENT_ATTR_STRING(zen4_ibs_extensions, zen4_ibs_extensions, "1");
PMU_EVENT_ATTR_STRING(ldlat, ibs_op_ldlat_cap, "1");
PMU_EVENT_ATTR_STRING(dtlb_pgsize, ibs_op_dtlb_pgsize_cap, "1");
+PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_format, "config1:0-10");
+PMU_EVENT_ATTR_STRING(fetchlat, ibs_fetch_lat_cap, "1");
static umode_t
zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int i)
@@ -673,6 +696,12 @@ zen4_ibs_extensions_is_visible(struct kobject *kobj, struct attribute *attr, int
}
static umode_t
+ibs_fetch_lat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+ return ibs_caps & IBS_CAPS_FETCHLAT ? attr->mode : 0;
+}
+
+static umode_t
ibs_op_ldlat_is_visible(struct kobject *kobj, struct attribute *attr, int i)
{
return ibs_caps & IBS_CAPS_OPLDLAT ? attr->mode : 0;
@@ -700,6 +729,16 @@ static struct attribute *zen4_ibs_extensions_attrs[] = {
NULL,
};
+static struct attribute *ibs_fetch_lat_format_attrs[] = {
+ &ibs_fetch_lat_format.attr.attr,
+ NULL,
+};
+
+static struct attribute *ibs_fetch_lat_cap_attrs[] = {
+ &ibs_fetch_lat_cap.attr.attr,
+ NULL,
+};
+
static struct attribute *ibs_op_ldlat_cap_attrs[] = {
&ibs_op_ldlat_cap.attr.attr,
NULL,
@@ -727,6 +766,18 @@ static struct attribute_group group_zen4_ibs_extensions = {
.is_visible = zen4_ibs_extensions_is_visible,
};
+static struct attribute_group group_ibs_fetch_lat_cap = {
+ .name = "caps",
+ .attrs = ibs_fetch_lat_cap_attrs,
+ .is_visible = ibs_fetch_lat_is_visible,
+};
+
+static struct attribute_group group_ibs_fetch_lat_format = {
+ .name = "format",
+ .attrs = ibs_fetch_lat_format_attrs,
+ .is_visible = ibs_fetch_lat_is_visible,
+};
+
static struct attribute_group group_ibs_op_ldlat_cap = {
.name = "caps",
.attrs = ibs_op_ldlat_cap_attrs,
@@ -748,6 +799,8 @@ static const struct attribute_group *fetch_attr_groups[] = {
static const struct attribute_group *fetch_attr_update[] = {
&group_fetch_l3missonly,
&group_zen4_ibs_extensions,
+ &group_ibs_fetch_lat_cap,
+ &group_ibs_fetch_lat_format,
NULL,
};
@@ -1191,7 +1244,8 @@ static int perf_ibs_get_offset_max(struct perf_ibs *perf_ibs,
{
if (event->attr.sample_type & PERF_SAMPLE_RAW ||
perf_ibs_is_mem_sample_type(perf_ibs, event) ||
- perf_ibs_ldlat_event(perf_ibs, event))
+ perf_ibs_ldlat_event(perf_ibs, event) ||
+ perf_ibs_fetch_lat_event(perf_ibs, event))
return perf_ibs->offset_max;
else if (check_rip)
return 3;
@@ -1333,6 +1387,16 @@ fail:
}
}
+ if (perf_ibs_fetch_lat_event(perf_ibs, event)) {
+ union ibs_fetch_ctl fetch_ctl;
+
+ fetch_ctl.val = ibs_data.regs[ibs_fetch_msr_idx(MSR_AMD64_IBSFETCHCTL)];
+ if (fetch_ctl.fetch_lat < (event->attr.config1 & IBS_FETCH_CONFIG1_FETCHLAT_MASK)) {
+ throttle = perf_event_account_interrupt(event);
+ goto out;
+ }
+ }
+
/*
* Read IbsBrTarget, IbsOpData4, and IbsExtdCtl separately
* depending on their availability.
^ permalink raw reply [flat|nested] 26+ messages in thread
* [tip: perf/core] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race
2026-02-16 4:25 ` [PATCH v2 3/7] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
@ 2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
1 sibling, 0 replies; 26+ messages in thread
From: tip-bot2 for Ravi Bangoria @ 2026-02-28 11:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Ravi Bangoria, Peter Zijlstra (Intel), x86, linux-kernel
The following commit has been merged into the perf/core branch of tip:
Commit-ID: efa5700ec0da66662dc8375fe4e4b888487a6b84
Gitweb: https://git.kernel.org/tip/efa5700ec0da66662dc8375fe4e4b888487a6b84
Author: Ravi Bangoria <ravi.bangoria@amd.com>
AuthorDate: Mon, 16 Feb 2026 04:25:26
Committer: Peter Zijlstra <peterz@infradead.org>
CommitterDate: Sat, 28 Feb 2026 12:02:49 +01:00
perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race
The existing IBS_{FETCH|OP}_CTL MSRs combine control and status bits
which leads to RMW race between HW and SW:
HW SW
------------------------ ------------------------------
config = rdmsr(IBS_OP_CTL);
config &= ~EN;
Set IBS_OP_CTL[Val] to 1
trigger NMI
wrmsr(IBS_OP_CTL, config);
// Val is accidentally cleared
Future hardware adds a control-only MSR, IBS_{FETCH|OP}_CTL2, which
provides a second-level "disable" bit (Dis). IBS is now:
Enabled: IBS_{FETCH|OP}_CTL[En] = 1 && IBS_{FETCH|OP}_CTL2[Dis] = 0
Disabled: IBS_{FETCH|OP}_CTL[En] = 0 || IBS_{FETCH|OP}_CTL2[Dis] = 1
The separate "Dis" bit lets software disable IBS without touching any
status fields, eliminating the hardware/software race.
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260216042530.1546-4-ravi.bangoria@amd.com
---
arch/x86/events/amd/ibs.c | 45 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index 2e8fb06..b7f0aad 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -86,9 +86,11 @@ struct cpu_perf_ibs {
struct perf_ibs {
struct pmu pmu;
unsigned int msr;
+ unsigned int msr2;
u64 config_mask;
u64 cnt_mask;
u64 enable_mask;
+ u64 disable_mask;
u64 valid_mask;
u16 min_period;
u64 max_period;
@@ -292,6 +294,8 @@ static int perf_ibs_init(struct perf_event *event)
return -ENOENT;
config = event->attr.config;
+ hwc->extra_reg.config = 0;
+ hwc->extra_reg.reg = 0;
if (event->pmu != &perf_ibs->pmu)
return -ENOENT;
@@ -319,6 +323,11 @@ static int perf_ibs_init(struct perf_event *event)
if (perf_allow_kernel())
hwc->flags |= PERF_X86_EVENT_UNPRIVILEGED;
+ if (ibs_caps & IBS_CAPS_DIS) {
+ hwc->extra_reg.config &= ~perf_ibs->disable_mask;
+ hwc->extra_reg.reg = perf_ibs->msr2;
+ }
+
if (hwc->sample_period) {
if (config & perf_ibs->cnt_mask)
/* raw max_cnt may not be set */
@@ -448,6 +457,9 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
wrmsrq(hwc->config_base, tmp & ~perf_ibs->enable_mask);
wrmsrq(hwc->config_base, tmp | perf_ibs->enable_mask);
+
+ if (hwc->extra_reg.reg)
+ wrmsrq(hwc->extra_reg.reg, hwc->extra_reg.config);
}
/*
@@ -460,6 +472,11 @@ static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
static inline void perf_ibs_disable_event(struct perf_ibs *perf_ibs,
struct hw_perf_event *hwc, u64 config)
{
+ if (ibs_caps & IBS_CAPS_DIS) {
+ wrmsrq(hwc->extra_reg.reg, perf_ibs->disable_mask);
+ return;
+ }
+
config &= ~perf_ibs->cnt_mask;
if (boot_cpu_data.x86 == 0x10)
wrmsrq(hwc->config_base, config);
@@ -812,6 +829,7 @@ static struct perf_ibs perf_ibs_fetch = {
.check_period = perf_ibs_check_period,
},
.msr = MSR_AMD64_IBSFETCHCTL,
+ .msr2 = MSR_AMD64_IBSFETCHCTL2,
.config_mask = IBS_FETCH_MAX_CNT | IBS_FETCH_RAND_EN,
.cnt_mask = IBS_FETCH_MAX_CNT,
.enable_mask = IBS_FETCH_ENABLE,
@@ -837,6 +855,7 @@ static struct perf_ibs perf_ibs_op = {
.check_period = perf_ibs_check_period,
},
.msr = MSR_AMD64_IBSOPCTL,
+ .msr2 = MSR_AMD64_IBSOPCTL2,
.config_mask = IBS_OP_MAX_CNT,
.cnt_mask = IBS_OP_MAX_CNT | IBS_OP_CUR_CNT |
IBS_OP_CUR_CNT_RAND,
@@ -1394,6 +1413,9 @@ fail:
out:
if (!throttle) {
+ if (ibs_caps & IBS_CAPS_DIS)
+ wrmsrq(hwc->extra_reg.reg, perf_ibs->disable_mask);
+
if (perf_ibs == &perf_ibs_op) {
if (ibs_caps & IBS_CAPS_OPCNTEXT) {
new_config = period & IBS_OP_MAX_CNT_EXT_MASK;
@@ -1465,6 +1487,9 @@ static __init int perf_ibs_fetch_init(void)
if (ibs_caps & IBS_CAPS_ZEN4)
perf_ibs_fetch.config_mask |= IBS_FETCH_L3MISSONLY;
+ if (ibs_caps & IBS_CAPS_DIS)
+ perf_ibs_fetch.disable_mask = IBS_FETCH_2_DIS;
+
perf_ibs_fetch.pmu.attr_groups = fetch_attr_groups;
perf_ibs_fetch.pmu.attr_update = fetch_attr_update;
@@ -1486,6 +1511,9 @@ static __init int perf_ibs_op_init(void)
if (ibs_caps & IBS_CAPS_ZEN4)
perf_ibs_op.config_mask |= IBS_OP_L3MISSONLY;
+ if (ibs_caps & IBS_CAPS_DIS)
+ perf_ibs_op.disable_mask = IBS_OP_2_DIS;
+
perf_ibs_op.pmu.attr_groups = op_attr_groups;
perf_ibs_op.pmu.attr_update = op_attr_update;
@@ -1732,6 +1760,23 @@ static void clear_APIC_ibs(void)
static int x86_pmu_amd_ibs_starting_cpu(unsigned int cpu)
{
setup_APIC_ibs();
+
+ if (ibs_caps & IBS_CAPS_DIS) {
+ /*
+ * IBS enable sequence:
+ * CTL[En] = 1;
+ * CTL2[Dis] = 0;
+ *
+ * IBS disable sequence:
+ * CTL2[Dis] = 1;
+ *
+ * Set CTL2[Dis] when CPU comes up. This is needed to make
+ * enable sequence effective.
+ */
+ wrmsrq(MSR_AMD64_IBSFETCHCTL2, IBS_FETCH_2_DIS);
+ wrmsrq(MSR_AMD64_IBSOPCTL2, IBS_OP_2_DIS);
+ }
+
return 0;
}
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-02-26 9:20 ` Ravi Bangoria
2026-02-26 16:53 ` Ian Rogers
@ 2026-03-09 2:58 ` Ravi Bangoria
2026-03-09 15:57 ` Ian Rogers
1 sibling, 1 reply; 26+ messages in thread
From: Ravi Bangoria @ 2026-03-09 2:58 UTC (permalink / raw)
To: Ian Rogers
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das, Stephane Eranian, Ravi Bangoria
Hi Ian,
>> Does the bit 63 assumption hold for guest operating systems?
>
> Yes, this seems to be an issue, even with current swfilt approach. Let
> me inspect the code and get back.
All mainstream 64 bit OSes use the bit-63 set for kernel addresses and zero
for userspace addresses. This norm does not apply to 32 bit guests, but
those are rare, and profiling them with IBS would be even rarer. So, I'll
document this limitation in the perf-amd-ibs man page.
While looking at this, I found some issues in IBS. Below patch fixes it:
---
From deb6cdcbc60778b57a6eef60b2b7bd1b8e3cea74 Mon Sep 17 00:00:00 2001
From: Ravi Bangoria <ravi.bangoria@amd.com>
Date: Fri, 6 Mar 2026 04:52:00 +0000
Subject: [PATCH] perf/amd/ibs: Improve guest profiling
IBS captures the RIP but not its privilege level. Since the NMI is
delivered with delay, CPL can change between the IBS tag and NMI
delivery. Add a check to catch and discard invalid guest samples
using CPL stored in vCPU save area. This will work when there is
user/kernel CPL change in between IBS tag and NMI delivery within
the guest boundary. But it won't work when there is a guest entry
or exit in between IBS tag and NMI delivery.
When profiling a guest and the IBS RIP is valid, assign the sample
IP from the IBS-captured RIP and set PERF_SAMPLE_IP in sample_flags
so that perf_prepare_sample() do not overwrite the RIP with
perf_guest_get_ip() from the vCPU save area. This keeps the perf
sample IP consistent with IBS raw data, data_src, weight, phy_addr
etc. The privilege level in the perf "misc" field can now go out
of sync, as it is taken from the vCPU save area.
Reported-by: Ian Rogers <irogers@google.com>
Closes: https://lore.kernel.org/r/CAP-5=fV_cJskvLRZhQQXMGAcPUb_Rg_b30PDJNXzxL49JK4B5g@mail.gmail.com
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
---
arch/x86/events/amd/ibs.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
index eeb607b84dda..70408b0b1597 100644
--- a/arch/x86/events/amd/ibs.c
+++ b/arch/x86/events/amd/ibs.c
@@ -1415,6 +1415,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
unsigned int msr;
u64 *buf, *config, period, new_config = 0;
int br_target_idx = -1;
+ unsigned int guest_state;
if (!test_bit(IBS_STARTED, pcpu->state)) {
fail:
@@ -1526,6 +1527,42 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
regs.flags |= PERF_EFLAGS_EXACT;
}
+ guest_state = perf_guest_state();
+ if (!event->attr.exclude_guest && guest_state & PERF_GUEST_ACTIVE) {
+ /*
+ * IBS captures the RIP but not its privilege level. Since
+ * NMI arrives delayed, CPL might change in between IBS tag
+ * and the NMI delivery. Below checks can identify and filter
+ * out invalid samples when the CPL changes are within the
+ * guest boundary. However, these checks fail to handle cases
+ * where the CPU performs a guest entry or exit in between
+ * the IBS tag and the NMI delivery.
+ */
+ if (event->attr.exclude_kernel && !(guest_state & PERF_GUEST_USER)) {
+ throttle = perf_event_account_interrupt(event);
+ goto out;
+ }
+ if (event->attr.exclude_user && guest_state & PERF_GUEST_USER) {
+ throttle = perf_event_account_interrupt(event);
+ goto out;
+ }
+
+ /*
+ * Assign the IBS RIP value directly in the perf sample here
+ * to prevent perf_prepare_sample() from retrieving it from
+ * the vCPU save-area. With this, rest of the perf sample
+ * fields (raw data, data_src, weight, phy_addr, etc.) will
+ * remain in sync with sample IP. However, privilege level
+ * captured as part of perf sample "misc" field could now
+ * go out of sync since privilege level is fetched from the
+ * vCPU save area.
+ */
+ if (regs.flags & PERF_EFLAGS_EXACT) {
+ data.ip = regs.ip;
+ data.sample_flags |= PERF_SAMPLE_IP;
+ }
+ }
+
if (((ibs_caps & IBS_CAPS_BIT63_FILTER) ||
(event->attr.config2 & IBS_SW_FILTER_MASK)) &&
perf_ibs_discard_sample(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering
2026-03-09 2:58 ` Ravi Bangoria
@ 2026-03-09 15:57 ` Ian Rogers
0 siblings, 0 replies; 26+ messages in thread
From: Ian Rogers @ 2026-03-09 15:57 UTC (permalink / raw)
To: Ravi Bangoria
Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Dapeng Mi, James Clark, Sadasivan Shaiju, x86,
linux-perf-users, linux-kernel, Manali Shukla, Santosh Shukla,
Ananth Narayan, Sandipan Das, Stephane Eranian
On Sun, Mar 8, 2026 at 7:58 PM Ravi Bangoria <ravi.bangoria@amd.com> wrote:
>
> Hi Ian,
>
> >> Does the bit 63 assumption hold for guest operating systems?
> >
> > Yes, this seems to be an issue, even with current swfilt approach. Let
> > me inspect the code and get back.
>
> All mainstream 64 bit OSes use the bit-63 set for kernel addresses and zero
> for userspace addresses. This norm does not apply to 32 bit guests, but
> those are rare, and profiling them with IBS would be even rarer. So, I'll
> document this limitation in the perf-amd-ibs man page.
>
> While looking at this, I found some issues in IBS. Below patch fixes it:
>
> ---
>
> From deb6cdcbc60778b57a6eef60b2b7bd1b8e3cea74 Mon Sep 17 00:00:00 2001
> From: Ravi Bangoria <ravi.bangoria@amd.com>
> Date: Fri, 6 Mar 2026 04:52:00 +0000
> Subject: [PATCH] perf/amd/ibs: Improve guest profiling
>
> IBS captures the RIP but not its privilege level. Since the NMI is
> delivered with delay, CPL can change between the IBS tag and NMI
> delivery. Add a check to catch and discard invalid guest samples
> using CPL stored in vCPU save area. This will work when there is
> user/kernel CPL change in between IBS tag and NMI delivery within
> the guest boundary. But it won't work when there is a guest entry
> or exit in between IBS tag and NMI delivery.
>
> When profiling a guest and the IBS RIP is valid, assign the sample
> IP from the IBS-captured RIP and set PERF_SAMPLE_IP in sample_flags
> so that perf_prepare_sample() do not overwrite the RIP with
> perf_guest_get_ip() from the vCPU save area. This keeps the perf
> sample IP consistent with IBS raw data, data_src, weight, phy_addr
> etc. The privilege level in the perf "misc" field can now go out
> of sync, as it is taken from the vCPU save area.
>
> Reported-by: Ian Rogers <irogers@google.com>
> Closes: https://lore.kernel.org/r/CAP-5=fV_cJskvLRZhQQXMGAcPUb_Rg_b30PDJNXzxL49JK4B5g@mail.gmail.com
> Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Thanks Ravi!
Reviewed-by: Ian Rogers <irogers@google.com>
Thanks,
Ian
> ---
> arch/x86/events/amd/ibs.c | 37 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
> diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c
> index eeb607b84dda..70408b0b1597 100644
> --- a/arch/x86/events/amd/ibs.c
> +++ b/arch/x86/events/amd/ibs.c
> @@ -1415,6 +1415,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
> unsigned int msr;
> u64 *buf, *config, period, new_config = 0;
> int br_target_idx = -1;
> + unsigned int guest_state;
>
> if (!test_bit(IBS_STARTED, pcpu->state)) {
> fail:
> @@ -1526,6 +1527,42 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs)
> regs.flags |= PERF_EFLAGS_EXACT;
> }
>
> + guest_state = perf_guest_state();
> + if (!event->attr.exclude_guest && guest_state & PERF_GUEST_ACTIVE) {
> + /*
> + * IBS captures the RIP but not its privilege level. Since
> + * NMI arrives delayed, CPL might change in between IBS tag
> + * and the NMI delivery. Below checks can identify and filter
> + * out invalid samples when the CPL changes are within the
> + * guest boundary. However, these checks fail to handle cases
> + * where the CPU performs a guest entry or exit in between
> + * the IBS tag and the NMI delivery.
> + */
> + if (event->attr.exclude_kernel && !(guest_state & PERF_GUEST_USER)) {
> + throttle = perf_event_account_interrupt(event);
> + goto out;
> + }
> + if (event->attr.exclude_user && guest_state & PERF_GUEST_USER) {
> + throttle = perf_event_account_interrupt(event);
> + goto out;
> + }
> +
> + /*
> + * Assign the IBS RIP value directly in the perf sample here
> + * to prevent perf_prepare_sample() from retrieving it from
> + * the vCPU save-area. With this, rest of the perf sample
> + * fields (raw data, data_src, weight, phy_addr, etc.) will
> + * remain in sync with sample IP. However, privilege level
> + * captured as part of perf sample "misc" field could now
> + * go out of sync since privilege level is fetched from the
> + * vCPU save area.
> + */
> + if (regs.flags & PERF_EFLAGS_EXACT) {
> + data.ip = regs.ip;
> + data.sample_flags |= PERF_SAMPLE_IP;
> + }
> + }
> +
> if (((ibs_caps & IBS_CAPS_BIT63_FILTER) ||
> (event->attr.config2 & IBS_SW_FILTER_MASK)) &&
> perf_ibs_discard_sample(perf_ibs, event, ®s, &ibs_data, br_target_idx)) {
> --
> 2.43.0
>
>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-03-09 15:57 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-16 4:25 [PATCH v2 0/7] perf/amd/ibs: Future enhancements Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 1/7] perf/amd/ibs: Define macro for ldlat mask and shift Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 2/7] perf/amd/ibs: Add new MSRs and CPUID bits definitions Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 3/7] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] to eliminate RMW race Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:01 ` Peter Zijlstra
2026-02-28 11:07 ` [tip: perf/core] perf/amd/ibs: Support IBS_{FETCH|OP}_CTL2[Dis] " tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 4/7] perf/amd/ibs: Enable fetch latency filtering Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 5/7] perf/amd/ibs: Enable RIP bit63 hardware filtering Ravi Bangoria
2026-02-24 17:47 ` Ian Rogers
2026-02-26 9:20 ` Ravi Bangoria
2026-02-26 16:53 ` Ian Rogers
2026-03-09 2:58 ` Ravi Bangoria
2026-03-09 15:57 ` Ian Rogers
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 6/7] perf/amd/ibs: Enable streaming store filter Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
2026-02-16 4:25 ` [PATCH v2 7/7] perf/amd/ibs: Advertise remote socket capability Ravi Bangoria
2026-02-28 10:56 ` [tip: perf/core] " tip-bot2 for Ravi Bangoria
2026-02-28 11:07 ` tip-bot2 for Ravi Bangoria
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®