* [PATCH v5 0/2] perf: marvell: Add CN20K DDR PMU support
From: Geetha sowjanya @ 2026-04-13 16:56 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt
This series adds support for the DDR Performance Monitoring Unit (PMU)
present in Marvell CN20K SoCs.
The DDR PMU is part of the DRAM Subsystem (DSS) and provides hardware
counters to monitor DDR traffic and performance events. The block
implements eight programmable counters and two fixed-function counters
tracking DDR read and write activity, and is accessed via a dedicated
MMIO region.
CN20K is the successor to CN10K, and the DDR PMU hardware is functionally
equivalent to the CN10K implementation, with only minor differences in
register offsets and event mappings. To allow software to distinguish
between the two silicon variants, this series introduces a specific
"marvell,cn20k-ddr-pmu" compatible and extends the existing
marvell_cn10k_ddr_pmu driver to handle CN20K via variant-specific data.
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Chnages in v4:
- Fixed document file name.
Chnages in v3:
- Expanded cover letter and commit message to better describe the DDR PMU
hardware and its relationship to CN10K
- Fixed the file name.
Changes in v2:
- Fixed YAML syntax error triggered by a tab character in the examples
section, which caused dt_binding_check to fail.
Changes in v1:
- Added a description field to the binding.
- Simplified the compatible property using 'const' instead of 'items/enum'.
- Updated the example node name to include a unit-address matching the reg base.
Geetha sowjanya (2):
dt-bindings: perf: marvell: Document CN20K DDR PMU
perf: marvell: Add CN20K DDR PMU support
.../bindings/perf/marvell,cn20k-ddr-pmu.yaml | 39 ++++
drivers/perf/marvell_cn10k_ddr_pmu.c | 187 ++++++++++++++++--
2 files changed, 210 insertions(+), 16 deletions(-)
create mode 100644 Documentation/devicetree/bindings/perf/marvell,cn20k-ddr-pmu.yaml
--
2.25.1
^ permalink raw reply
* [PATCH v5 2/2] perf: marvell: Add CN20K DDR PMU support
From: Geetha sowjanya @ 2026-04-13 16:56 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt
In-Reply-To: <20260413165621.10921-1-gakula@marvell.com>
The CN20K DRAM Subsystem exposes eight programmable
performance counters and two fixed counters for DDR
read and write traffic. Software selects events for
the programmable counters from traffic at the DDR PHY
interface, the CHI interconnect, or inside the DDR controller.
Add CN20K register offsets, event maps, and sysfs attributes;
match the device via OF (marvell,cn20k-ddr-pmu) and ACPI (MRVL000B).
Represent the SoC variant in platform data with bit flags so
CN20K can reuse the CN10K PMU code path where appropriate.
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
drivers/perf/marvell_cn10k_ddr_pmu.c | 187 ++++++++++++++++++++++++---
1 file changed, 171 insertions(+), 16 deletions(-)
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 72ac17efd846..7e2e1823b009 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -13,31 +13,43 @@
#include <linux/hrtimer.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
+#include <linux/bits.h>
+
+/* SoC variant flags for struct ddr_pmu_platform_data (mutually exclusive in pdata) */
+#define IS_CN10K BIT(0)
+#define IS_ODY BIT(1)
+#define IS_CN20K BIT(2)
/* Performance Counters Operating Mode Control Registers */
#define CN10K_DDRC_PERF_CNT_OP_MODE_CTRL 0x8020
#define ODY_DDRC_PERF_CNT_OP_MODE_CTRL 0x20020
+#define CN20K_DDRC_PERF_CNT_OP_MODE_CTRL 0x20000
#define OP_MODE_CTRL_VAL_MANUAL 0x1
/* Performance Counters Start Operation Control Registers */
#define CN10K_DDRC_PERF_CNT_START_OP_CTRL 0x8028
#define ODY_DDRC_PERF_CNT_START_OP_CTRL 0x200A0
+#define CN20K_DDRC_PERF_CNT_START_OP_CTRL 0x20080
#define START_OP_CTRL_VAL_START 0x1ULL
#define START_OP_CTRL_VAL_ACTIVE 0x2
/* Performance Counters End Operation Control Registers */
#define CN10K_DDRC_PERF_CNT_END_OP_CTRL 0x8030
#define ODY_DDRC_PERF_CNT_END_OP_CTRL 0x200E0
+#define CN20K_DDRC_PERF_CNT_END_OP_CTRL 0x200C0
#define END_OP_CTRL_VAL_END 0x1ULL
/* Performance Counters End Status Registers */
#define CN10K_DDRC_PERF_CNT_END_STATUS 0x8038
#define ODY_DDRC_PERF_CNT_END_STATUS 0x20120
+#define CN20K_DDRC_PERF_CNT_END_STATUS 0x20100
#define END_STATUS_VAL_END_TIMER_MODE_END 0x1
/* Performance Counters Configuration Registers */
#define CN10K_DDRC_PERF_CFG_BASE 0x8040
#define ODY_DDRC_PERF_CFG_BASE 0x20160
+#define CN20K_DDRC_PERF_CFG_BASE 0x20140
+#define CN20K_DDRC_PERF_CFG1_BASE 0x20180
/* 8 Generic event counter + 2 fixed event counters */
#define DDRC_PERF_NUM_GEN_COUNTERS 8
@@ -61,6 +73,23 @@
* DO NOT change these event-id numbers, they are used to
* program event bitmap in h/w.
*/
+
+/* CN20K specific events */
+#define EVENT_PERF_OP_IS_RD16 61
+#define EVENT_PERF_OP_IS_RD32 60
+#define EVENT_PERF_OP_IS_WR16 59
+#define EVENT_PERF_OP_IS_WR32 58
+#define EVENT_OP_IS_ENTER_DSM 44
+#define EVENT_OP_IS_RFM 43
+
+#define EVENT_CN20K_OP_IS_TCR_MRR 50
+#define EVENT_CN20K_OP_IS_DQSOSC_MRR 49
+#define EVENT_CN20K_OP_IS_DQSOSC_MPC 48
+#define EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_WR 47
+#define EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_RD 46
+#define EVENT_CN20K_OP_IS_ZQLATCH 21
+#define EVENT_CN20K_OP_IS_ZQSTART 22
+
#define EVENT_DFI_CMD_IS_RETRY 61
#define EVENT_RD_UC_ECC_ERROR 60
#define EVENT_RD_CRC_ERROR 59
@@ -87,6 +116,9 @@
#define EVENT_OP_IS_SPEC_REF 41
#define EVENT_OP_IS_CRIT_REF 40
#define EVENT_OP_IS_REFRESH 39
+#define EVENT_OP_IS_CAS_WCK_SUS 38
+#define EVENT_OP_IS_CAS_WS_OFF 37
+#define EVENT_OP_IS_CAS_WS 36
#define EVENT_OP_IS_ENTER_MPSM 35
#define EVENT_OP_IS_ENTER_POWERDOWN 31
#define EVENT_OP_IS_ENTER_SELFREF 27
@@ -183,8 +215,8 @@ struct ddr_pmu_platform_data {
u64 cnt_freerun_clr;
u64 cnt_value_wr_op;
u64 cnt_value_rd_op;
- bool is_cn10k;
- bool is_ody;
+ u64 cfg1_base;
+ unsigned int silicon_flags; /* IS_CN10K, IS_ODY, or IS_CN20K */
};
static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
@@ -336,6 +368,80 @@ static struct attribute *odyssey_ddr_perf_events_attrs[] = {
NULL
};
+static struct attribute *cn20k_ddr_perf_events_attrs[] = {
+ /* Programmable */
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dfi_wr_data_access,
+ EVENT_DFI_WR_DATA_CYCLES),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dfi_rd_data_access,
+ EVENT_DFI_RD_DATA_CYCLES),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
+ EVENT_HPR_XACT_WHEN_CRITICAL),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
+ EVENT_LPR_XACT_WHEN_CRITICAL),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
+ EVENT_WR_XACT_WHEN_CRITICAL),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access,
+ EVENT_OP_IS_RD_OR_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access,
+ EVENT_OP_IS_RD_ACTIVATE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr,
+ EVENT_PRECHARGE_FOR_RDWR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
+ EVENT_PRECHARGE_FOR_OTHER),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown,
+ EVENT_OP_IS_ENTER_POWERDOWN),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cas_ws, EVENT_OP_IS_CAS_WS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cas_ws_off, EVENT_OP_IS_CAS_WS_OFF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cas_wck_sus, EVENT_OP_IS_CAS_WCK_SUS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_rfm, EVENT_OP_IS_RFM),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_dsm, EVENT_OP_IS_ENTER_DSM),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dfi_cycles, EVENT_DFI_CYCLES),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
+ EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
+ EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_CN20K_OP_IS_DQSOSC_MPC),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_CN20K_OP_IS_DQSOSC_MRR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_CN20K_OP_IS_TCR_MRR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_CN20K_OP_IS_ZQSTART),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_CN20K_OP_IS_ZQLATCH),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_read16, EVENT_PERF_OP_IS_RD16),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_read32, EVENT_PERF_OP_IS_RD32),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_write16, EVENT_PERF_OP_IS_WR16),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_write32, EVENT_PERF_OP_IS_WR32),
+ /* Free run event counters */
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
+ NULL
+};
+
+static struct attribute_group cn20k_ddr_perf_events_attr_group = {
+ .name = "events",
+ .attrs = cn20k_ddr_perf_events_attrs,
+};
+
static struct attribute_group odyssey_ddr_perf_events_attr_group = {
.name = "events",
.attrs = odyssey_ddr_perf_events_attrs,
@@ -393,6 +499,13 @@ static const struct attribute_group *odyssey_attr_groups[] = {
NULL
};
+static const struct attribute_group *cn20k_attr_groups[] = {
+ &cn20k_ddr_perf_events_attr_group,
+ &cn10k_ddr_perf_format_attr_group,
+ &cn10k_ddr_perf_cpumask_attr_group,
+ NULL
+};
+
/* Default poll timeout is 100 sec, which is very sufficient for
* 48 bit counter incremented max at 5.6 GT/s, which may take many
* hours to overflow.
@@ -412,7 +525,7 @@ static int ddr_perf_get_event_bitmap(int eventid, u64 *event_bitmap,
switch (eventid) {
case EVENT_DFI_PARITY_POISON ...EVENT_DFI_CMD_IS_RETRY:
- if (!ddr_pmu->p_data->is_ody) {
+ if (!(ddr_pmu->p_data->silicon_flags & IS_ODY)) {
err = -EINVAL;
break;
}
@@ -524,9 +637,9 @@ static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
int counter, bool enable)
{
const struct ddr_pmu_platform_data *p_data = pmu->p_data;
+ unsigned int silicon_flags = pmu->p_data->silicon_flags;
u64 ctrl_reg = pmu->p_data->cnt_op_mode_ctrl;
const struct ddr_pmu_ops *ops = pmu->ops;
- bool is_ody = pmu->p_data->is_ody;
u32 reg;
u64 val;
@@ -546,7 +659,7 @@ static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
writeq_relaxed(val, pmu->base + reg);
- if (is_ody) {
+ if (silicon_flags & IS_ODY) {
if (enable) {
/*
* Setup the PMU counter to work in
@@ -621,6 +734,7 @@ static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
{
struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
const struct ddr_pmu_platform_data *p_data = pmu->p_data;
+ unsigned int silicon_flags = pmu->p_data->silicon_flags;
const struct ddr_pmu_ops *ops = pmu->ops;
struct hw_perf_event *hwc = &event->hw;
u8 config = event->attr.config;
@@ -642,10 +756,17 @@ static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
/* Generic counters, configure event id */
reg_offset = DDRC_PERF_CFG(p_data->cfg_base, counter);
- ret = ddr_perf_get_event_bitmap(config, &val, pmu);
- if (ret)
- return ret;
+ if (silicon_flags & IS_CN20K) {
+ val = (1ULL << (config - 1));
+ if (config == EVENT_CN20K_OP_IS_ZQSTART ||
+ config == EVENT_CN20K_OP_IS_ZQLATCH)
+ reg_offset = DDRC_PERF_CFG(p_data->cfg1_base, counter);
+ } else {
+ ret = ddr_perf_get_event_bitmap(config, &val, pmu);
+ if (ret)
+ return ret;
+ }
writeq_relaxed(val, pmu->base + reg_offset);
} else {
/* fixed event counter, clear counter value */
@@ -952,7 +1073,25 @@ static const struct ddr_pmu_platform_data cn10k_ddr_pmu_pdata = {
.cnt_freerun_clr = 0,
.cnt_value_wr_op = CN10K_DDRC_PERF_CNT_VALUE_WR_OP,
.cnt_value_rd_op = CN10K_DDRC_PERF_CNT_VALUE_RD_OP,
- .is_cn10k = TRUE,
+ .silicon_flags = IS_CN10K,
+};
+
+static const struct ddr_pmu_platform_data cn20k_ddr_pmu_pdata = {
+ .counter_overflow_val = 0,
+ .counter_max_val = GENMASK_ULL(63, 0),
+ .cnt_base = ODY_DDRC_PERF_CNT_VALUE_BASE,
+ .cfg_base = CN20K_DDRC_PERF_CFG_BASE,
+ .cfg1_base = CN20K_DDRC_PERF_CFG1_BASE,
+ .cnt_op_mode_ctrl = CN20K_DDRC_PERF_CNT_OP_MODE_CTRL,
+ .cnt_start_op_ctrl = CN20K_DDRC_PERF_CNT_START_OP_CTRL,
+ .cnt_end_op_ctrl = CN20K_DDRC_PERF_CNT_END_OP_CTRL,
+ .cnt_end_status = CN20K_DDRC_PERF_CNT_END_STATUS,
+ .cnt_freerun_en = 0,
+ .cnt_freerun_ctrl = ODY_DDRC_PERF_CNT_FREERUN_CTRL,
+ .cnt_freerun_clr = ODY_DDRC_PERF_CNT_FREERUN_CLR,
+ .cnt_value_wr_op = ODY_DDRC_PERF_CNT_VALUE_WR_OP,
+ .cnt_value_rd_op = ODY_DDRC_PERF_CNT_VALUE_RD_OP,
+ .silicon_flags = IS_CN20K,
};
#endif
@@ -979,7 +1118,7 @@ static const struct ddr_pmu_platform_data odyssey_ddr_pmu_pdata = {
.cnt_freerun_clr = ODY_DDRC_PERF_CNT_FREERUN_CLR,
.cnt_value_wr_op = ODY_DDRC_PERF_CNT_VALUE_WR_OP,
.cnt_value_rd_op = ODY_DDRC_PERF_CNT_VALUE_RD_OP,
- .is_ody = TRUE,
+ .silicon_flags = IS_ODY,
};
#endif
@@ -989,8 +1128,7 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
struct cn10k_ddr_pmu *ddr_pmu;
struct resource *res;
void __iomem *base;
- bool is_cn10k;
- bool is_ody;
+ unsigned int silicon_flags;
char *name;
int ret;
@@ -1014,10 +1152,9 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
ddr_pmu->base = base;
ddr_pmu->p_data = dev_data;
- is_cn10k = ddr_pmu->p_data->is_cn10k;
- is_ody = ddr_pmu->p_data->is_ody;
+ silicon_flags = ddr_pmu->p_data->silicon_flags;
- if (is_cn10k) {
+ if (silicon_flags & IS_CN10K) {
ddr_pmu->ops = &ddr_pmu_ops;
/* Setup the PMU counter to work in manual mode */
writeq_relaxed(OP_MODE_CTRL_VAL_MANUAL, ddr_pmu->base +
@@ -1039,7 +1176,7 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
};
}
- if (is_ody) {
+ if (silicon_flags & IS_ODY) {
ddr_pmu->ops = &ddr_pmu_ody_ops;
ddr_pmu->pmu = (struct pmu) {
@@ -1056,6 +1193,22 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
};
}
+ if (silicon_flags & IS_CN20K) {
+ ddr_pmu->ops = &ddr_pmu_ody_ops;
+
+ ddr_pmu->pmu = (struct pmu) {
+ .module = THIS_MODULE,
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+ .task_ctx_nr = perf_invalid_context,
+ .attr_groups = cn20k_attr_groups,
+ .event_init = cn10k_ddr_perf_event_init,
+ .add = cn10k_ddr_perf_event_add,
+ .del = cn10k_ddr_perf_event_del,
+ .start = cn10k_ddr_perf_event_start,
+ .stop = cn10k_ddr_perf_event_stop,
+ .read = cn10k_ddr_perf_event_update,
+ };
+ }
/* Choose this cpu to collect perf data */
ddr_pmu->cpu = raw_smp_processor_id();
@@ -1098,6 +1251,7 @@ static void cn10k_ddr_perf_remove(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
{ .compatible = "marvell,cn10k-ddr-pmu", .data = &cn10k_ddr_pmu_pdata },
+ { .compatible = "marvell,cn20k-ddr-pmu", .data = &cn20k_ddr_pmu_pdata },
{ },
};
MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
@@ -1107,6 +1261,7 @@ MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
static const struct acpi_device_id cn10k_ddr_pmu_acpi_match[] = {
{"MRVL000A", (kernel_ulong_t)&cn10k_ddr_pmu_pdata },
{"MRVL000C", (kernel_ulong_t)&odyssey_ddr_pmu_pdata},
+ {"MRVL000B", (kernel_ulong_t)&cn20k_ddr_pmu_pdata},
{},
};
MODULE_DEVICE_TABLE(acpi, cn10k_ddr_pmu_acpi_match);
--
2.25.1
^ permalink raw reply related
* [PATCH v5 1/2] dt-bindings: perf: marvell: Add CN20K DDR PMU binding
From: Geetha sowjanya @ 2026-04-13 16:56 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt
In-Reply-To: <20260413165621.10921-1-gakula@marvell.com>
Marvell CN20K SoCs integrate a DDR Performance Monitoring Unit (PMU)
associated with the DDR controller. The block provides hardware counters
to monitor DDR traffic and performance events and is accessed via a
dedicated MMIO region.
The CN20K DDR PMU is functionally equivalent to the CN10K DDR PMU, with
minor register offset differences.
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
.../bindings/perf/marvell,cn20k-ddr-pmu.yaml | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 Documentation/devicetree/bindings/perf/marvell,cn20k-ddr-pmu.yaml
diff --git a/Documentation/devicetree/bindings/perf/marvell,cn20k-ddr-pmu.yaml b/Documentation/devicetree/bindings/perf/marvell,cn20k-ddr-pmu.yaml
new file mode 100644
index 000000000000..cc6aa760de49
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/marvell,cn20k-ddr-pmu.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell,cn20k-ddr-pmu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN20K DDR performance monitor
+
+description:
+ Performance Monitoring Unit (PMU) for the DDR controller
+ in Marvell CN20K SoCs.
+
+maintainers:
+ - Geetha sowjanya <gakula@marvell.com>
+
+properties:
+ compatible:
+ const: marvell,cn20k-ddr-pmu
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ddr-pmu@c200000000 {
+ compatible = "marvell,cn20k-ddr-pmu";
+ reg = <0xc200 0x00000000 0x0 0x100000>;
+ };
+ };
--
2.25.1
^ permalink raw reply related
* Re: [PATCH bpf-next 1/2] bpf, arm64: Remove redundant bpf_flush_icache() after pack allocator finalize
From: Song Liu @ 2026-04-13 16:56 UTC (permalink / raw)
To: Puranjay Mohan
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Yonghong Song, Jiri Olsa, Xu Kuohai, Catalin Marinas, Will Deacon,
Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
linux-arm-kernel, linux-riscv, linux-kernel
In-Reply-To: <20260413123256.3296452-2-puranjay@kernel.org>
On Mon, Apr 13, 2026 at 5:33 AM Puranjay Mohan <puranjay@kernel.org> wrote:
>
> bpf_flush_icache() calls flush_icache_range() to clean the data cache
> and invalidate the instruction cache for the JITed code region. However,
> since commit 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory
> management"), this flush is redundant.
>
> bpf_jit_binary_pack_finalize() copies the JITed instructions to the ROX
> region via bpf_arch_text_copy() -> aarch64_insn_copy() -> __text_poke(),
> and __text_poke() already calls flush_icache_range() on the written
> range. The subsequent bpf_flush_icache() repeats the same cache
> maintenance on an overlapping range, including an unnecessary second
> synchronous IPI to all CPUs via kick_all_cpus_sync().
>
> Remove the redundant bpf_flush_icache() call and its now-unused
> definition.
>
> Fixes: 1dad391daef1 ("bpf, arm64: use bpf_prog_pack for memory management")
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
We can now remove "#include <asm/cacheflush.h>".
Other than that,
Acked-by: Song Liu <song@kernel.org>
^ permalink raw reply
* Re: [PATCH 1/7] x86/vdso: Respect COMPAT_32BIT_TIME
From: Arnd Bergmann @ 2026-04-13 16:57 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: H. Peter Anvin, Andy Lutomirski, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, Russell King, Catalin Marinas,
Will Deacon, Madhavan Srinivasan, Michael Ellerman,
Nicholas Piggin, Christophe Leroy, Thomas Bogendoerfer,
Vincenzo Frascino, linux-kernel, linux-arm-kernel, linuxppc-dev,
linux-mips
In-Reply-To: <20260413180541-e13f374c-b990-4236-bc83-8fde948899df@linutronix.de>
On Mon, Apr 13, 2026, at 18:13, Thomas Weißschuh wrote:
> On Mon, Apr 13, 2026 at 05:59:52PM +0200, Arnd Bergmann wrote:
>> On Fri, Apr 10, 2026, at 09:24, Thomas Weißschuh wrote:
>
>> > * Always provide settimeofday(). If CONFIG_COMPAT_32BIT_TIME is *not*
>> > set, reject passing any 'tv' argument where it may not be y2038 safe.
>>
>> This sounds wrong to me now: the case I'm worried about is a 32-bit
>> system calling settimeofday() based on the value of an RTC or NTP.
>> The idea of CONFIG_COMPAT_32BIT_TIME=n is to catch this by causing
>> an intentional ENOSYS error even for valid times, so it doesn't
>> suddenly start breaking in 2038.
>
> This is what I meant with "where it *may*" be not y2038 safe.
> Even if the value fits, the call would be rejected.
Ok, that's fine then.
> My wording was crappy indeed, though.
>
> In code:
>
> if (tv && !IS_ENABLED(CONFIG_COMPAT_32BIT_TIME) && sizeof(tv->tv_sec) < 8) {
> pr_warn_once(...);
> return -EINVAL;
> }
>
> Or maybe drop the EINVAL but still emit a warning. That warning would be
> useful for gettimeofday(), too.
We discussed this during the original y2038 work and decided
at the time to not have those warnings for syscalls. We could
bring that back, but I think I would want one level of abstraction
there and control this using a global Kconfig switch for all
syscalls as well as ioctl commands that could use such a check.
Arnd
^ permalink raw reply
* Re: [PATCH] pinctrl: mediatek: moore: implement gpio_chip::get_direction()
From: Frank Wunderlich @ 2026-04-13 16:59 UTC (permalink / raw)
To: Linus Walleij, Frank Wunderlich
Cc: bartosz.golaszewski, linux, sean.wang, matthias.bgg,
angelogioacchino.delregno, brgl, linux-mediatek, linux-gpio,
linux-kernel, linux-arm-kernel
In-Reply-To: <CAD++jLnjN-gUdCbmdmLaMYck=sP9wrhT2fFRB0TGCAVGvSsY1w@mail.gmail.com>
Am 13. April 2026 um 10:01 schrieb "Linus Walleij" <linusw@kernel.org mailto:linusw@kernel.org?to=%22Linus%20Walleij%22%20%3Clinusw%40kernel.org%3E >:
>
> On Fri, Apr 10, 2026 at 11:24 AM Frank Wunderlich
> <frank-w@public-files.de> wrote:
>
> >
> > Gesendet: Freitag, 10. April 2026 um 09:09
> > Von: "Bartosz Golaszewski" <bartosz.golaszewski@oss.qualcomm.com>
> > An: "Frank Wunderlich" <linux@fw-web.de>, "Sean Wang" <sean.wang@kernel.org>, "Linus Walleij" <linusw@kernel.org>, "Matthias Brugger" <matthias.bgg@gmail.com>, "AngeloGioacchino Del Regno" <angelogioacchino.delregno@collabora.com>, "Bartosz Golaszewski" <brgl@kernel.org>
> > CC: linux-mediatek@lists.infradead.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, "Bartosz Golaszewski" <bartosz.golaszewski@oss.qualcomm.com>
> > Betreff: [PATCH] pinctrl: mediatek: moore: implement gpio_chip::get_direction()
> >
> > If the gpio_chip::get_direction() callback is not implemented by the GPIO
> > controller driver, GPIOLIB emits a warning.
> >
> > Implement get_direction() for the GPIO part of pinctrl-moore.
> >
> > Fixes: 471e998c0e31 ("gpiolib: remove redundant callback check")
> > Fixes: e623c4303ed1 ("gpiolib: sanitize the return value of gpio_chip::get_direction()")
> > Reported-by: Frank Wunderlich <linux@fw-web.de>
> >
> > please use the email i used for SoB in my linked patch (closes link below), the other email i use only for sending patches due to mail provider limitation.
> >
> I can't fix this up because the closes link isn't working right now.
> Is it the same
> as the one this mail came from frank-w@public-files.de?
yes, closes-link works for me
> Yours,
> Linus Walleij
>
regards Frank
^ permalink raw reply
* Re: [PATCH 01/10] drm/bridge: add of_drm_get_bridge_by_endpoint()
From: Luca Ceresoli @ 2026-04-13 17:07 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <u2awvqh2uoc2acuuvyavwwtuvtiaidhbkkj5a2d2wwph2s7j7g@b4j73kwzblgk>
Hi Dmitry, Maxime,
thanks Dmitry for the quick feedback!
On Mon Apr 13, 2026 at 4:58 PM CEST, Dmitry Baryshkov wrote:
>> --- a/drivers/gpu/drm/drm_bridge.c
>> +++ b/drivers/gpu/drm/drm_bridge.c
>> @@ -1581,6 +1581,52 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
>> return bridge;
>> }
>> EXPORT_SYMBOL(of_drm_find_bridge);
>> +
>> +/**
>> + * of_drm_get_bridge_by_endpoint - return DRM bridge connected to a port/endpoint
>> + * @np: device tree node containing output ports
>> + * @port: port in the device tree node, or -1 for the first port found
>> + * @endpoint: endpoint in the device tree node, or -1 for the first endpoint found
>> + * @bridge: pointer to hold returned drm_bridge, must not be NULL
>> + *
>> + * Given a DT node's port and endpoint number, find the connected node and
>> + * return the associated drm_bridge device.
>> + *
>> + * The refcount of the returned bridge is incremented. Use drm_bridge_put()
>> + * when done with it.
>> + *
>> + * Returns zero (and sets *bridge to a valid bridge pointer) if successful,
>> + * or one of the standard error codes (and the value in *bridge is
>> + * unspecified) if it fails.
>
> Can we return drm_bridge or error cookie instead?
(while replying I realized there is a design flaw in my implementation, but
see below)
I initially thought I'd do it, but I don't like returning an error cookie
for functions getting a bridge pointer. The main reason is that with bridge
refcounting the __free() cleanup actions are handy in a lot of places, so we
are introdugin a lot of code like:
struct drm_bridge *foo __free(drm_bridge_put) = some_func(...);
Where some_func can be one of of_drm_find_bridge(),
drm_bridge_get_next_bridge(), drm_bridge_chain_get_{first,last}_bridge()
etc.
Such code is very handy exactly because these functions return either a
valid pointer or NULL, and thus the cleanup actions always does the right
thing. If an error cookie were returned, the caller would have to be very
careful in inhibiting the cleanup action by clearing the pointer before
returning. This originate for example this discussion: [0]
[0] https://lore.kernel.org/lkml/4cd29943-a8d0-4706-b0c5-01d6b33863e4@bootlin.com/
So I think never having a negative error value in the bridge pointer is
useful to prevent bugs slipping in drivers. For this we should take one of
these two opposite approaches:
1. don't return a bridge pointer which can be an ERR_PTR; return an int
with the error code and take a **drm_bridge and:
- on success, set the valid pointer in *bridge
- on failure, set *bridge = NULL (*)
2. like the above-mentioned functions (of_drm_find_bridge(),
drm_bridge_get_next_bridge() etc) return a drm_bridge pointer which is
either a valid pointer or NULL
(*) I didn't do it in this patch, that's a design flaw, I'll fix in case
approach 1 is taken
Clearly option 2 is the simplest to use, but it loses information about
which error happened.
What do you think about these options?
>> + */
>> +int of_drm_get_bridge_by_endpoint(const struct device_node *np,
>> + int port, int endpoint,
>> + struct drm_bridge **bridge)
>
> Nit: can it be drm_of_get_bridge_by_endpoint?
Argh, this convention is changing periodically it seems! :-)
I previous discussions I was asked to do either drm_of_ [1] of of_drm_ [2],
but since the latter was the last one requested I sticked on it.
@Maxime, Dmitry, I'm OK with either, just let me know if I need to change.
[1] https://lore.kernel.org/dri-devel/20250319-stylish-lime-mongoose-0a18ad@houat/
-> search "called drm_of_find_bridge"
[2] https://lore.kernel.org/all/DEH1VJUEJ8HQ.MIS45UOLCPXL@bootlin.com/
-> search "What about"
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH bpf-next 2/2] bpf, riscv: Remove redundant bpf_flush_icache() after pack allocator finalize
From: Song Liu @ 2026-04-13 17:20 UTC (permalink / raw)
To: Puranjay Mohan
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Yonghong Song, Jiri Olsa, Xu Kuohai, Catalin Marinas, Will Deacon,
Luke Nelson, Xi Wang, Björn Töpel, Pu Lehui,
Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
linux-arm-kernel, linux-riscv, linux-kernel
In-Reply-To: <20260413123256.3296452-3-puranjay@kernel.org>
On Mon, Apr 13, 2026 at 5:33 AM Puranjay Mohan <puranjay@kernel.org> wrote:
>
> bpf_flush_icache() calls flush_icache_range() to clean the data cache
> and invalidate the instruction cache for the JITed code region. However,
> since commit 48a8f78c50bd ("bpf, riscv: use prog pack allocator in the
> BPF JIT"), this flush is redundant.
>
> bpf_jit_binary_pack_finalize() copies the JITed instructions to the ROX
> region via bpf_arch_text_copy() -> patch_text_nosync(), and
> patch_text_nosync() already calls flush_icache_range() on the written
> range. The subsequent bpf_flush_icache() repeats the same cache
> maintenance on an overlapping range.
>
> Remove the redundant bpf_flush_icache() call and its now-unused
> definition.
>
> Fixes: 48a8f78c50bd ("bpf, riscv: use prog pack allocator in the BPF JIT")
> Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Acked-by: Song Liu <song@kernel.org>
ditto on #include <asm/cacheflush.h>.
^ permalink raw reply
* Re: [PATCH v4 1/9] coresight: etm4x: introduce struct etm4_caps
From: Leo Yan @ 2026-04-13 17:21 UTC (permalink / raw)
To: Yeoreum Yun
Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
mike.leach, james.clark, alexander.shishkin, jie.gan
In-Reply-To: <20260413142003.3549310-2-yeoreum.yun@arm.com>
On Mon, Apr 13, 2026 at 03:19:54PM +0100, Yeoreum Yun wrote:
> Introduce struct etm4_caps to describe ETMv4 capabilities
> and move capabilities information into it.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
LGTM:
Reviewed-by: Leo Yan <leo.yan@arm.com>
FWIW, two comments from Sashiko are valuable for me, please see below.
> ---
> .../coresight/coresight-etm4x-core.c | 234 +++++++++---------
> .../coresight/coresight-etm4x-sysfs.c | 190 ++++++++------
> drivers/hwtracing/coresight/coresight-etm4x.h | 176 ++++++-------
> 3 files changed, 328 insertions(+), 272 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index d565a73f0042..6443f3717b37 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -88,8 +88,9 @@ static int etm4_probe_cpu(unsigned int cpu);
> */
> static bool etm4x_sspcicrn_present(struct etmv4_drvdata *drvdata, int n)
> {
> - return (n < drvdata->nr_ss_cmp) &&
> - drvdata->nr_pe &&
> + const struct etmv4_caps *caps = &drvdata->caps;
> +
> + return (n < caps->nr_ss_cmp) && caps->nr_pe &&
> (drvdata->config.ss_status[n] & TRCSSCSRn_PC);
As Sashiko suggests:
"This isn't a regression introduced by this patch, but should this be
checking caps->nr_pe_cmp instead of caps->nr_pe?"
I confirmed the ETMv4 specification (ARM IHI0064H.b), the comment
above is valid as the we should check caps->nr_pe_cmp instead.
Could you first use a patch to fix the typo and then apply
capabilities afterwards? This is helpful for porting to stable
kernels.
[...]
> @@ -525,14 +530,14 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
> if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1))
> dev_err(etm_dev,
> "timeout while waiting for Idle Trace Status\n");
> - if (drvdata->nr_pe)
> + if (caps->nr_pe)
> etm4x_relaxed_write32(csa, config->pe_sel, TRCPROCSELR);
> etm4x_relaxed_write32(csa, config->cfg, TRCCONFIGR);
> /* nothing specific implemented */
> etm4x_relaxed_write32(csa, 0x0, TRCAUXCTLR);
> etm4x_relaxed_write32(csa, config->eventctrl0, TRCEVENTCTL0R);
> etm4x_relaxed_write32(csa, config->eventctrl1, TRCEVENTCTL1R);
> - if (drvdata->stallctl)
> + if (caps->stallctl)
> etm4x_relaxed_write32(csa, config->stall_ctrl, TRCSTALLCTLR);
> etm4x_relaxed_write32(csa, config->ts_ctrl, TRCTSCTLR);
> etm4x_relaxed_write32(csa, config->syncfreq, TRCSYNCPR);
> @@ -542,17 +547,17 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata)
> etm4x_relaxed_write32(csa, config->vinst_ctrl, TRCVICTLR);
> etm4x_relaxed_write32(csa, config->viiectlr, TRCVIIECTLR);
> etm4x_relaxed_write32(csa, config->vissctlr, TRCVISSCTLR);
> - if (drvdata->nr_pe_cmp)
> + if (caps->nr_pe_cmp)
> etm4x_relaxed_write32(csa, config->vipcssctlr, TRCVIPCSSCTLR);
> - for (i = 0; i < drvdata->nrseqstate - 1; i++)
> + for (i = 0; i < caps->nrseqstate - 1; i++)
> etm4x_relaxed_write32(csa, config->seq_ctrl[i], TRCSEQEVRn(i));
Sashiko's comment:
"If the hardware does not implement a sequencer, caps->nrseqstate (a u8)
will be 0. Does 0 - 1 evaluate to -1 as an int, which then gets promoted
to ULONG_MAX against val (an unsigned long)?"
This is a good catch. The condition check should be:
for (i = 0; i < caps->nrseqstate; i++)
...;
The issue is irrelevant to your patch, but could you use a patch to fix
"nrseqstate - 1" first and then apply the cap refactoring on it? This
would be friendly for porting to stable kernel.
Thanks,
Leo
^ permalink raw reply
* Re: [PATCH v2] dt-bindings: ARM: arm,vexpress-scc: convert to DT schema
From: Rob Herring @ 2026-04-13 17:28 UTC (permalink / raw)
To: Khushal Chitturi
Cc: krzk+dt, conor+dt, liviu.dudau, sudeep.holla, lpieralisi,
pawel.moll, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20260411183355.8847-1-khushalchitturi@gmail.com>
On Sun, Apr 12, 2026 at 12:03:55AM +0530, Khushal Chitturi wrote:
> Convert the ARM Versatile Express Serial Configuration Controller
> bindings to DT schema.
>
> Signed-off-by: Khushal Chitturi <khushalchitturi@gmail.com>
> ---
> Changelog:
> v1 -> v2:
> - Modified compatible string to use an enum instead of a generic pattern.
> - Updated maintainers list.
>
> .../bindings/arm/arm,vexpress-scc.yaml | 53 +++++++++++++++++++
> .../devicetree/bindings/arm/vexpress-scc.txt | 33 ------------
> 2 files changed, 53 insertions(+), 33 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/arm/arm,vexpress-scc.yaml
> delete mode 100644 Documentation/devicetree/bindings/arm/vexpress-scc.txt
Applied, thanks.
Rob
^ permalink raw reply
* Re: [RFC PATCH] mmc: host: sdhci-iproc: implement the .hw_reset callback
From: Meagan Lloyd @ 2026-04-13 17:38 UTC (permalink / raw)
To: rjui; +Cc: sbranden, linux-arm-kernel, tgopinath, adrian.hunter, linux-mmc
In-Reply-To: <20260327222150.2108111-1-meaganlloyd@linux.microsoft.com>
On 3/27/2026 3:21 PM, Meagan Lloyd wrote:
> Implement the .hw_reset callback so that the eMMC can be reset as needed
> given cap-mmc-hw-reset is set in the devicetree and the functionality is
> enabled on the eMMC.
>
> Signed-off-by: Meagan Lloyd <meaganlloyd@linux.microsoft.com>
> ---
>
> SDHCI_POWER_CONTROL[4] (SD Host Controller Standard) has been repurposed
> on my Broadcomm processor to be eMMC hardware reset
> (SDIO*_eMMCSDXC_CTRL[12], HRESET).
>
> Can you confirm this repurposed bit is consistent across the Broadcomm
> iProc processors and thus the .hw_reset callback can be uniformly
> applied in this driver?
Hi Ray & Scott,
I hope you're doing well. This bit looks to have been repurposed from
the SD Host Controller Standard's VDD2 Power Control to being used for
toggling the hardware reset signal to eMMCs. Can you verify that it
applies across the iProc processors so that I may finalize this patch?
Thank you,
Meagan
>
> ---
> drivers/mmc/host/sdhci-iproc.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c
> index 35ef5c5f51467..9018ed7fe2e66 100644
> --- a/drivers/mmc/host/sdhci-iproc.c
> +++ b/drivers/mmc/host/sdhci-iproc.c
> @@ -181,12 +181,26 @@ static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host)
> return 200000;
> }
>
> +static void sdhci_iproc_hw_reset(struct sdhci_host *host)
> +{
> + u8 val = sdhci_readb(host, SDHCI_POWER_CONTROL);
> +
> + /* Trigger reset and hold for at least 1us (eMMC spec requirement) */
> + sdhci_writeb(host, val | BIT(4), SDHCI_POWER_CONTROL);
> + usleep_range(2, 10);
> +
> + /* Release from reset and wait for at least 200us (eMMC spec requirement) */
> + sdhci_writeb(host, val & ~BIT(4), SDHCI_POWER_CONTROL);
> + usleep_range(250, 300);
> +}
> +
> static const struct sdhci_ops sdhci_iproc_ops = {
> .set_clock = sdhci_set_clock,
> .get_max_clock = sdhci_iproc_get_max_clock,
> .set_bus_width = sdhci_set_bus_width,
> .reset = sdhci_reset,
> .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .hw_reset = sdhci_iproc_hw_reset,
> };
>
> static const struct sdhci_ops sdhci_iproc_32only_ops = {
> @@ -201,6 +215,7 @@ static const struct sdhci_ops sdhci_iproc_32only_ops = {
> .set_bus_width = sdhci_set_bus_width,
> .reset = sdhci_reset,
> .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .hw_reset = sdhci_iproc_hw_reset,
> };
>
> static const struct sdhci_pltfm_data sdhci_iproc_cygnus_pltfm_data = {
> @@ -283,6 +298,7 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = {
> .set_bus_width = sdhci_set_bus_width,
> .reset = sdhci_reset,
> .set_uhs_signaling = sdhci_set_uhs_signaling,
> + .hw_reset = sdhci_iproc_hw_reset,
> };
>
> static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = {
^ permalink raw reply
* Re: [RFC PATCH] mmc: host: sdhci-iproc: implement the .hw_reset callback
From: Florian Fainelli @ 2026-04-13 17:43 UTC (permalink / raw)
To: Meagan Lloyd, rjui
Cc: sbranden, linux-arm-kernel, tgopinath, adrian.hunter, linux-mmc
In-Reply-To: <3305684d-8517-47dd-8852-2e34d40fc712@linux.microsoft.com>
On 4/13/26 10:38, Meagan Lloyd wrote:
>
> On 3/27/2026 3:21 PM, Meagan Lloyd wrote:
>> Implement the .hw_reset callback so that the eMMC can be reset as needed
>> given cap-mmc-hw-reset is set in the devicetree and the functionality is
>> enabled on the eMMC.
>>
>> Signed-off-by: Meagan Lloyd <meaganlloyd@linux.microsoft.com>
>> ---
>>
>> SDHCI_POWER_CONTROL[4] (SD Host Controller Standard) has been repurposed
>> on my Broadcomm processor to be eMMC hardware reset
>> (SDIO*_eMMCSDXC_CTRL[12], HRESET).
>>
>> Can you confirm this repurposed bit is consistent across the Broadcomm
>> iProc processors and thus the .hw_reset callback can be uniformly
>> applied in this driver?
>
> Hi Ray & Scott,
>
> I hope you're doing well. This bit looks to have been repurposed from
> the SD Host Controller Standard's VDD2 Power Control to being used for
> toggling the hardware reset signal to eMMCs. Can you verify that it
> applies across the iProc processors so that I may finalize this patch?
Which iProc process are you using? If you are not sure this applies
broadly, can you at least make it specific to the SoC you are using?
--
Florian
^ permalink raw reply
* Re: [PATCH 01/10] drm/bridge: add of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 17:56 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <DHS6WZRYGWZQ.1X6ABU4UWF730@bootlin.com>
On Mon, Apr 13, 2026 at 07:07:14PM +0200, Luca Ceresoli wrote:
> Hi Dmitry, Maxime,
>
> thanks Dmitry for the quick feedback!
>
> On Mon Apr 13, 2026 at 4:58 PM CEST, Dmitry Baryshkov wrote:
>
> >> --- a/drivers/gpu/drm/drm_bridge.c
> >> +++ b/drivers/gpu/drm/drm_bridge.c
> >> @@ -1581,6 +1581,52 @@ struct drm_bridge *of_drm_find_bridge(struct device_node *np)
> >> return bridge;
> >> }
> >> EXPORT_SYMBOL(of_drm_find_bridge);
> >> +
> >> +/**
> >> + * of_drm_get_bridge_by_endpoint - return DRM bridge connected to a port/endpoint
> >> + * @np: device tree node containing output ports
> >> + * @port: port in the device tree node, or -1 for the first port found
> >> + * @endpoint: endpoint in the device tree node, or -1 for the first endpoint found
> >> + * @bridge: pointer to hold returned drm_bridge, must not be NULL
> >> + *
> >> + * Given a DT node's port and endpoint number, find the connected node and
> >> + * return the associated drm_bridge device.
> >> + *
> >> + * The refcount of the returned bridge is incremented. Use drm_bridge_put()
> >> + * when done with it.
> >> + *
> >> + * Returns zero (and sets *bridge to a valid bridge pointer) if successful,
> >> + * or one of the standard error codes (and the value in *bridge is
> >> + * unspecified) if it fails.
> >
> > Can we return drm_bridge or error cookie instead?
>
> (while replying I realized there is a design flaw in my implementation, but
> see below)
>
> I initially thought I'd do it, but I don't like returning an error cookie
> for functions getting a bridge pointer. The main reason is that with bridge
> refcounting the __free() cleanup actions are handy in a lot of places, so we
> are introdugin a lot of code like:
>
> struct drm_bridge *foo __free(drm_bridge_put) = some_func(...);
>
> Where some_func can be one of of_drm_find_bridge(),
> drm_bridge_get_next_bridge(), drm_bridge_chain_get_{first,last}_bridge()
> etc.
This is fine even with the functions returning a cookie: the free
function can explicitly check and return early if IS_ERR() pointer is
passed to it.
>
> Such code is very handy exactly because these functions return either a
> valid pointer or NULL, and thus the cleanup actions always does the right
> thing. If an error cookie were returned, the caller would have to be very
> careful in inhibiting the cleanup action by clearing the pointer before
> returning. This originate for example this discussion: [0]
>
> [0] https://lore.kernel.org/lkml/4cd29943-a8d0-4706-b0c5-01d6b33863e4@bootlin.com/
>
> So I think never having a negative error value in the bridge pointer is
> useful to prevent bugs slipping in drivers. For this we should take one of
> these two opposite approaches:
>
> 1. don't return a bridge pointer which can be an ERR_PTR; return an int
> with the error code and take a **drm_bridge and:
> - on success, set the valid pointer in *bridge
> - on failure, set *bridge = NULL (*)
> 2. like the above-mentioned functions (of_drm_find_bridge(),
> drm_bridge_get_next_bridge() etc) return a drm_bridge pointer which is
> either a valid pointer or NULL
3. Return pointer or cookie, ignore cookie in the release function.
>
> (*) I didn't do it in this patch, that's a design flaw, I'll fix in case
> approach 1 is taken
>
> Clearly option 2 is the simplest to use, but it loses information about
> which error happened.
>
> What do you think about these options?
>
> >> + */
> >> +int of_drm_get_bridge_by_endpoint(const struct device_node *np,
> >> + int port, int endpoint,
> >> + struct drm_bridge **bridge)
> >
> > Nit: can it be drm_of_get_bridge_by_endpoint?
>
> Argh, this convention is changing periodically it seems! :-)
>
> I previous discussions I was asked to do either drm_of_ [1] of of_drm_ [2],
> but since the latter was the last one requested I sticked on it.
>
> @Maxime, Dmitry, I'm OK with either, just let me know if I need to change.
I missed Maxime's response, sorry. I'm fine with the suggested
convention of using the first argument.
>
> [1] https://lore.kernel.org/dri-devel/20250319-stylish-lime-mongoose-0a18ad@houat/
> -> search "called drm_of_find_bridge"
> [2] https://lore.kernel.org/all/DEH1VJUEJ8HQ.MIS45UOLCPXL@bootlin.com/
> -> search "What about"
>
> Luca
>
> --
> Luca Ceresoli, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 02/10] drm/msm/hdmi: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 17:57 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-2-acd01cd79a1f@bootlin.com>
On Mon, Apr 13, 2026 at 03:58:34PM +0200, Luca Ceresoli wrote:
> This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> @panel parameter, thus using a reduced feature set of that function.
> Replace this call with the simpler of_drm_get_bridge_by_endpoint().
>
> Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> returned bridge, ensure it is put on removal.
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> ---
> drivers/gpu/drm/msm/hdmi/hdmi.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
Acked-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
How common is the probe / remove path? Would it make sense to have a
devm_ version of the function?
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 05/10] drm/bridge: lontium-lt9611uxc: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 18:01 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-5-acd01cd79a1f@bootlin.com>
On Mon, Apr 13, 2026 at 03:58:37PM +0200, Luca Ceresoli wrote:
> This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> @panel parameter, thus using a reduced feature set of that function.
> Replace this call with the simpler of_drm_get_bridge_by_endpoint().
>
> Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> returned bridge, ensure it is put on removal. To achieve this, instead of
> adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
> pointer which is automatically put when the bridge is eventually freed.
What if the driver's _probe fails between increasing this refcount and
actually registering the bridge? There are enough possible cases. I
think this also applies to other patches in the series (BTW, including
the msm/hdmi, which I ack'ed).
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> ---
> drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
> index 11aab07d88df..55b80a488c33 100644
> --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
> +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
> @@ -35,7 +35,6 @@
> struct lt9611uxc {
> struct device *dev;
> struct drm_bridge bridge;
> - struct drm_bridge *next_bridge;
>
> struct regmap *regmap;
> /* Protects all accesses to registers by stopping the on-chip MCU */
> @@ -284,7 +283,7 @@ static int lt9611uxc_bridge_attach(struct drm_bridge *bridge,
> {
> struct lt9611uxc *lt9611uxc = bridge_to_lt9611uxc(bridge);
>
> - return drm_bridge_attach(encoder, lt9611uxc->next_bridge,
> + return drm_bridge_attach(encoder, lt9611uxc->bridge.next_bridge,
> bridge, flags);
> }
>
> @@ -487,7 +486,7 @@ static int lt9611uxc_parse_dt(struct device *dev,
>
> lt9611uxc->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);
>
> - return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, <9611uxc->next_bridge);
> + return of_drm_get_bridge_by_endpoint(dev->of_node, 2, -1, <9611uxc->bridge.next_bridge);
> }
>
> static int lt9611uxc_gpio_init(struct lt9611uxc *lt9611uxc)
>
> --
> 2.53.0
>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH net-next] net: stmmac: enable RPS and RBU interrupts
From: Jakub Kicinski @ 2026-04-13 18:02 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, Alexandre Torgue, Andrew Lunn, David S. Miller,
Eric Dumazet, linux-arm-kernel, linux-stm32, netdev, Paolo Abeni,
Sam Edwards
In-Reply-To: <E1wBBaR-0000000GZHR-1dbM@rmk-PC.armlinux.org.uk>
On Fri, 10 Apr 2026 14:07:51 +0100 Russell King (Oracle) wrote:
> Since we are seeing receive buffer exhaustion on several platforms,
> let's enable the interrupts so the statistics we publish via ethtool -S
> actually work to aid diagnosis. I've been in two minds about whether
> to send this patch, but given the problems with stmmac at the moment,
> I think it should be merged.
Sorry for a under-research response but wasn't there are person trying
to fix the OOM starvation issue? Who was supposed to add a timer?
Is your problem also OOM related or do you suspect something else?
Firing interrupts when Rx fill ring runs dry (which IIUC this patches
dies?) is not a good idea.
^ permalink raw reply
* Re: [PATCH 10/10] drm: of: forbid bridge-only calls to drm_of_find_panel_or_bridge()
From: Dmitry Baryshkov @ 2026-04-13 18:04 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-10-acd01cd79a1f@bootlin.com>
On Mon, Apr 13, 2026 at 03:58:42PM +0200, Luca Ceresoli wrote:
> Up to now drm_of_find_panel_or_bridge() can be called with a bridge pointer
> only, a panel pointer only, or both a bridge and a panel pointers. The
> logic to handle all the three cases is somewhat complex to read however.
>
> Now all bridge-only callers have been converted to
> of_drm_get_bridge_by_endpoint(), which is simpler and handles bridge
> refcounting. So forbid new bridge-only users by mandating a non-NULL panel
> pointer in the docs and in the sanity checks along with a warning.
Are there remaining users which still use either the bridge or the
panel? Would it be possible / better to drop the two-arg version?
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> ---
> drivers/gpu/drm/drm_of.c | 26 ++++++++++++--------------
> 1 file changed, 12 insertions(+), 14 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 02/10] drm/msm/hdmi: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 18:10 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <t45cmunr6lhxrvqgwa2mrh765zmjjderfpd32islrbg7jey4fq@d5635guivyla>
On Mon, Apr 13, 2026 at 08:57:42PM +0300, Dmitry Baryshkov wrote:
> On Mon, Apr 13, 2026 at 03:58:34PM +0200, Luca Ceresoli wrote:
> > This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> > @panel parameter, thus using a reduced feature set of that function.
> > Replace this call with the simpler of_drm_get_bridge_by_endpoint().
> >
> > Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> > returned bridge, ensure it is put on removal.
> >
> > Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> > ---
> > drivers/gpu/drm/msm/hdmi/hdmi.c | 3 ++-
> > 1 file changed, 2 insertions(+), 1 deletion(-)
> >
>
> Acked-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
>
> How common is the probe / remove path? Would it make sense to have a
> devm_ version of the function?
And probably the best way would be to change the driver to allocate the
bridge early and follow the rest of the bridge drivers. I will check it
out and possibly send a patch.
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 05/10] drm/bridge: lontium-lt9611uxc: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 18:12 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <rivgablnl6s7u54gyv77vr5pitlvvgzby7qnu4ryc4tttaqa7t@hztujmxw5njt>
On Mon, Apr 13, 2026 at 09:01:34PM +0300, Dmitry Baryshkov wrote:
> On Mon, Apr 13, 2026 at 03:58:37PM +0200, Luca Ceresoli wrote:
> > This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> > @panel parameter, thus using a reduced feature set of that function.
> > Replace this call with the simpler of_drm_get_bridge_by_endpoint().
> >
> > Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> > returned bridge, ensure it is put on removal. To achieve this, instead of
> > adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
> > pointer which is automatically put when the bridge is eventually freed.
>
> What if the driver's _probe fails between increasing this refcount and
> actually registering the bridge? There are enough possible cases. I
> think this also applies to other patches in the series (BTW, including
> the msm/hdmi, which I ack'ed).
And after reading the code, I missed that it's handled as a part of
bridge_alloc / __drm_bridge_free(). Please ignore the comment.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 07/10] drm/bridge: adv7511: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 18:17 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-7-acd01cd79a1f@bootlin.com>
On Mon, Apr 13, 2026 at 03:58:39PM +0200, Luca Ceresoli wrote:
> This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> @panel parameter, thus using a reduced feature set of that function.
> Replace this call with the simpler of_drm_get_bridge_by_endpoint().
>
> Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> returned bridge, ensure it is put on removal. To achieve this, instead of
> adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
> pointer which is automatically put when the bridge is eventually freed.
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> ---
> drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 -
> drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 8 ++++----
> 2 files changed, 4 insertions(+), 5 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 06/10] drm/bridge: lt9611: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 18:18 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-6-acd01cd79a1f@bootlin.com>
On Mon, Apr 13, 2026 at 03:58:38PM +0200, Luca Ceresoli wrote:
> This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> @panel parameter, thus using a reduced feature set of that function.
> Replace this call with the simpler of_drm_get_bridge_by_endpoint().
>
> Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> returned bridge, ensure it is put on removal. To achieve this, instead of
> adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
> pointer which is automatically put when the bridge is eventually freed.
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> ---
> drivers/gpu/drm/bridge/lontium-lt9611.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH 08/10] drm/bridge: lt8713sx: switch to of_drm_get_bridge_by_endpoint()
From: Dmitry Baryshkov @ 2026-04-13 18:18 UTC (permalink / raw)
To: Luca Ceresoli
Cc: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, Xinliang Liu, Tian Tao,
Xinwei Kong, Sumit Semwal, Yongqin Liu, John Stultz,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Tomi Valkeinen, Michal Simek,
Hui Pu, Ian Ray, Thomas Petazzoni, dri-devel, linux-kernel,
linux-arm-msm, freedreno, linux-arm-kernel
In-Reply-To: <20260413-drm-bridge-alloc-getput-panel_or_bridge-v1-8-acd01cd79a1f@bootlin.com>
On Mon, Apr 13, 2026 at 03:58:40PM +0200, Luca Ceresoli wrote:
> This driver calls drm_of_find_panel_or_bridge() with a NULL pointer in the
> @panel parameter, thus using a reduced feature set of that function.
> Replace this call with the simpler of_drm_get_bridge_by_endpoint().
>
> Since of_drm_get_bridge_by_endpoint() increases the refcount of the
> returned bridge, ensure it is put on removal. To achieve this, instead of
> adding an explicit drm_bridge_put(), migrate to the bridge::next_bridge
> pointer which is automatically put when the bridge is eventually freed.
>
> Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> ---
> drivers/gpu/drm/bridge/lontium-lt8713sx.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH RFC bpf-next 0/8] bpf: add support for KASAN checks in JITed programs
From: Alexis Lothoré (eBPF Foundation) @ 2026-04-13 18:28 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Andrew Morton
Cc: ebpf, Bastien Curutchet, Thomas Petazzoni, Xu Kuohai, bpf,
linux-kernel, netdev, linux-kselftest, linux-stm32,
linux-arm-kernel, kasan-dev, linux-mm,
Alexis Lothoré (eBPF Foundation)
Hello,
this series aims to bring basic support for KASAN checks to BPF JITed
programs. This follows the first RFC posted in [1].
KASAN allows to spot memory management mistakes by reserving a fraction
of memory as "shadow memory" that will map to the rest of the memory and
allow its monitoring. Each memory-accessing instruction is then
instrumented at build time to call some ASAN check function, that will
analyze the corresponding bits in shadow memory, and if it detects the
access as invalid, trigger a detailed report. The goal of this series is
to replicate this mechanism for BPF programs when they are being JITed
into native instructions: that's then the (runtime) JIT compiler who is
in charge of inserting calls to the corresponding kasan checks, when a
program is being loaded into the kernel. This task involves:
- identifying at program load time the instructions performing memory
accesses
- identifying those accesses properties (size ? read or write ?) to
define the relevant kasan check function to call
- just before the identified instructions:
- perform the basic context saving (ie: saving registers)
- inserting a call to the relevant kasan check function
- restore context
- whenever the instrumented program executes, if it performs an invalid
access, it triggers a kasan report identical to those instrumented on
kernel side at build time.
As discussed in [1], this series is based on some choices and
assumptions:
- it focuses on x86_64 for now, and so only on KASAN_GENERIC
- not all memory accessing BPF instructions are being instrumented:
- it focuses on STX/LDX instructions
- it discards instructions accessing BPF program stack (already
monitored by page guards)
- it discards possibly faulting instructions, like BPF_PROBE_MEM or
BPF_PROBE_ATOMIC insns
The series is marked and sent as RFC:
- to allow collecting feedback early and make sure that it goes into the
right direction
- because it depends on Xu's work to pass data between the verifier and
JIT compilers. This work is not merged yet, see [2]. I have been
tracking the various revisions he sent on the ML and based my local
branch on his work
- because tests brought by this series currently can't run on BPF CI:
they expect kasan multishot to be enabled, otherwise the first test
will make all other kasan-related tests fail.
- because some cases like atomic loads/stores are not instrumented yet
(and are still making me scratch my head)
- because it will hopefully provide a good basis to discuss the topic at
LSFMMBPF (see [3])
Despite this series not being ready for integration yet, anyone
interested in running it locally can perform the following steps to run
the JITed KASAN instrumentation selftests:
- rebasing locally this series on [2]
- building and running the corresponding kernel with kasan_multi_shot
enabled
- running `test_progs -a kasan`
And should get a variety of KASAN tests executed for BPF programs:
#162/1 kasan/bpf_kasan_uaf_read_1:OK
#162/2 kasan/bpf_kasan_uaf_read_2:OK
#162/3 kasan/bpf_kasan_uaf_read_4:OK
#162/4 kasan/bpf_kasan_uaf_read_8:OK
#162/5 kasan/bpf_kasan_uaf_write_1:OK
#162/6 kasan/bpf_kasan_uaf_write_2:OK
#162/7 kasan/bpf_kasan_uaf_write_4:OK
#162/8 kasan/bpf_kasan_uaf_write_8:OK
#162/9 kasan/bpf_kasan_oob_read_1:OK
#162/10 kasan/bpf_kasan_oob_read_2:OK
#162/11 kasan/bpf_kasan_oob_read_4:OK
#162/12 kasan/bpf_kasan_oob_read_8:OK
#162/13 kasan/bpf_kasan_oob_write_1:OK
#162/14 kasan/bpf_kasan_oob_write_2:OK
#162/15 kasan/bpf_kasan_oob_write_4:OK
#162/16 kasan/bpf_kasan_oob_write_8:OK
#162 kasan:OK
Summary: 1/16 PASSED, 0 SKIPPED, 0 FAILED
[1] https://lore.kernel.org/bpf/DG7UG112AVBC.JKYISDTAM30T@bootlin.com/
[2] https://lore.kernel.org/bpf/cover.1776062885.git.xukuohai@hotmail.com/
[3] https://lore.kernel.org/bpf/DGGNCXX79H8O.2P6K8L1QW1M8K@bootlin.com/
Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
---
Alexis Lothoré (eBPF Foundation) (8):
kasan: expose generic kasan helpers
bpf: mark instructions accessing program stack
bpf: add BPF_JIT_KASAN for KASAN instrumentation of JITed programs
bpf, x86: add helper to emit kasan checks in x86 JITed programs
bpf, x86: emit KASAN checks into x86 JITed programs
selftests/bpf: do not run verifier JIT tests when BPF_JIT_KASAN is enabled
bpf, x86: enable KASAN for JITed programs on x86
selftests/bpf: add tests to validate KASAN on JIT programs
arch/x86/Kconfig | 1 +
arch/x86/net/bpf_jit_comp.c | 106 +++++++++++++
include/linux/bpf.h | 2 +
include/linux/bpf_verifier.h | 2 +
include/linux/kasan.h | 13 ++
kernel/bpf/Kconfig | 9 ++
kernel/bpf/core.c | 10 ++
kernel/bpf/verifier.c | 7 +
mm/kasan/kasan.h | 10 --
tools/testing/selftests/bpf/prog_tests/kasan.c | 165 +++++++++++++++++++++
tools/testing/selftests/bpf/progs/kasan.c | 146 ++++++++++++++++++
.../testing/selftests/bpf/test_kmods/bpf_testmod.c | 79 ++++++++++
tools/testing/selftests/bpf/test_loader.c | 5 +
tools/testing/selftests/bpf/unpriv_helpers.c | 5 +
tools/testing/selftests/bpf/unpriv_helpers.h | 1 +
15 files changed, 551 insertions(+), 10 deletions(-)
---
base-commit: 7990a071b32887a1a883952e8cf60134b6d6fea0
change-id: 20260126-kasan-fcd68f64cd7b
Best regards,
--
Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
^ permalink raw reply
* [PATCH RFC bpf-next 1/8] kasan: expose generic kasan helpers
From: Alexis Lothoré (eBPF Foundation) @ 2026-04-13 18:28 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Andrew Morton
Cc: ebpf, Bastien Curutchet, Thomas Petazzoni, Xu Kuohai, bpf,
linux-kernel, netdev, linux-kselftest, linux-stm32,
linux-arm-kernel, kasan-dev, linux-mm,
Alexis Lothoré (eBPF Foundation)
In-Reply-To: <20260413-kasan-v1-0-1a5831230821@bootlin.com>
In order to prepare KASAN helpers to be called from the eBPF subsystem
(to add KASAN instrumentation at runtime when JITing eBPF programs),
expose the __asan_{load,store}X functions in linux/kasan.h
Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
---
include/linux/kasan.h | 13 +++++++++++++
mm/kasan/kasan.h | 10 ----------
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 338a1921a50a..6f580d4a39e4 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -710,4 +710,17 @@ void kasan_non_canonical_hook(unsigned long addr);
static inline void kasan_non_canonical_hook(unsigned long addr) { }
#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+#ifdef CONFIG_KASAN_GENERIC
+void __asan_load1(void *p);
+void __asan_store1(void *p);
+void __asan_load2(void *p);
+void __asan_store2(void *p);
+void __asan_load4(void *p);
+void __asan_store4(void *p);
+void __asan_load8(void *p);
+void __asan_store8(void *p);
+void __asan_load16(void *p);
+void __asan_store16(void *p);
+#endif /* CONFIG_KASAN_GENERIC */
+
#endif /* LINUX_KASAN_H */
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index fc9169a54766..3bfce8eb3135 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -594,16 +594,6 @@ void __asan_handle_no_return(void);
void __asan_alloca_poison(void *, ssize_t size);
void __asan_allocas_unpoison(void *stack_top, ssize_t stack_bottom);
-void __asan_load1(void *);
-void __asan_store1(void *);
-void __asan_load2(void *);
-void __asan_store2(void *);
-void __asan_load4(void *);
-void __asan_store4(void *);
-void __asan_load8(void *);
-void __asan_store8(void *);
-void __asan_load16(void *);
-void __asan_store16(void *);
void __asan_loadN(void *, ssize_t size);
void __asan_storeN(void *, ssize_t size);
--
2.53.0
^ permalink raw reply related
* [PATCH RFC bpf-next 2/8] bpf: mark instructions accessing program stack
From: Alexis Lothoré (eBPF Foundation) @ 2026-04-13 18:28 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
Vincenzo Frascino, Andrew Morton
Cc: ebpf, Bastien Curutchet, Thomas Petazzoni, Xu Kuohai, bpf,
linux-kernel, netdev, linux-kselftest, linux-stm32,
linux-arm-kernel, kasan-dev, linux-mm,
Alexis Lothoré (eBPF Foundation)
In-Reply-To: <20260413-kasan-v1-0-1a5831230821@bootlin.com>
In order to prepare to emit KASAN checks in JITed programs, JIT
compilers need to be aware about whether some load/store instructions
are targeting the bpf program stack, as those should not be monitored
(we already have guard pages for that, and it is difficult anyway to
correctly monitor any kind of data passed on stack).
To support this need, make the BPF verifier mark the instructions that
access program stack:
- add a setter that allows the verifier to mark instructions accessing
the program stack
- add a getter that allows JIT compilers to check whether instructions
being JITed are accessing the stack
Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
---
include/linux/bpf.h | 2 ++
include/linux/bpf_verifier.h | 2 ++
kernel/bpf/core.c | 10 ++++++++++
kernel/bpf/verifier.c | 7 +++++++
4 files changed, 21 insertions(+)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index b4b703c90ca9..774a0395c498 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1543,6 +1543,8 @@ void bpf_jit_uncharge_modmem(u32 size);
bool bpf_prog_has_trampoline(const struct bpf_prog *prog);
bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const struct bpf_prog *prog,
int insn_idx);
+bool bpf_insn_accesses_stack(const struct bpf_verifier_env *env,
+ const struct bpf_prog *prog, int insn_idx);
#else
static inline int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
struct bpf_trampoline *tr,
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index b148f816f25b..ab99ed4c4227 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -660,6 +660,8 @@ struct bpf_insn_aux_data {
u16 const_reg_map_mask;
u16 const_reg_subprog_mask;
u32 const_reg_vals[10];
+ /* instruction accesses stack */
+ bool accesses_stack;
};
#define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 8b018ff48875..340abfdadbed 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1582,6 +1582,16 @@ bool bpf_insn_is_indirect_target(const struct bpf_verifier_env *env, const struc
insn_idx += prog->aux->subprog_start;
return env->insn_aux_data[insn_idx].indirect_target;
}
+
+bool bpf_insn_accesses_stack(const struct bpf_verifier_env *env,
+ const struct bpf_prog *prog, int insn_idx)
+{
+ if (!env)
+ return false;
+ insn_idx += prog->aux->subprog_start;
+ return env->insn_aux_data[insn_idx].accesses_stack;
+}
+
#endif /* CONFIG_BPF_JIT */
/* Base function for offset calculation. Needs to go into .text section,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1e36b9e91277..7bce4fb4e540 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3502,6 +3502,11 @@ static void mark_indirect_target(struct bpf_verifier_env *env, int idx)
env->insn_aux_data[idx].indirect_target = true;
}
+static void mark_insn_accesses_stack(struct bpf_verifier_env *env, int idx)
+{
+ env->insn_aux_data[idx].accesses_stack = true;
+}
+
#define LR_FRAMENO_BITS 3
#define LR_SPI_BITS 6
#define LR_ENTRY_BITS (LR_SPI_BITS + LR_FRAMENO_BITS + 1)
@@ -6490,6 +6495,8 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn
else
err = check_stack_write(env, regno, off, size,
value_regno, insn_idx);
+
+ mark_insn_accesses_stack(env, insn_idx);
} else if (reg_is_pkt_pointer(reg)) {
if (t == BPF_WRITE && !may_access_direct_pkt_data(env, NULL, t)) {
verbose(env, "cannot write into packet\n");
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox