mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 00/11] accel: ethosu: Another batch of fixes
@ 2026-08-27 20:32 Rob Herring (Arm)
  2026-08-27 20:33 ` [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value Rob Herring (Arm)
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:32 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

This is another series of fixes to the ethosu driver. It's mostly probe 
error paths and cmd stream validation fixes. It's a mixture of 
AI reported issues, different solutions to other posted issues and 
fixes[1] and my own fixes.

The series adds rejecting OFM tranpose in cmd stream, but then the last 
patch adds support for it. I did this so the rejection can be 
backported, but maybe supporting OFM transpose is small enough that it 
should just be backported too?

Rob

[1] https://lore.kernel.org/all/20260717061145.1478139-1-zhaoguohan@kylinos.cn

Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
Rob Herring (Arm) (11):
      accel: ethosu: Fix ethosu_job_open() return value
      accel: ethosu: Drop IRQF_SHARED flag
      accel: ethosu: Ensure cmd stream ends with a stop op
      accel: ethosu: Ensure SRAM size is 0 on mapping failure
      accel: ethosu: Ensure SRAM region size matches job
      accel: ethosu: Fix probe error cleanup
      accel: ethosu: Factor buffer bounds checks
      accel: ethosu: Validate secondary streams
      accel: ethosu: Reject unsupported commands
      accel: ethosu: Validate all feature map tiles
      accel: ethosu: Validate OFM transpose

 drivers/accel/ethosu/ethosu_device.h |   6 +
 drivers/accel/ethosu/ethosu_drv.c    |  17 ++-
 drivers/accel/ethosu/ethosu_gem.c    | 240 ++++++++++++++++++++++++++++++-----
 drivers/accel/ethosu/ethosu_job.c    |  22 ++--
 4 files changed, 233 insertions(+), 52 deletions(-)
---
base-commit: f7e3f4d9f425cf4c5577cd84a096e6e618488083
change-id: 20260827-ethosu-fixes-ee58386e9000

Best regards,
--  
Rob Herring (Arm) <robh@kernel.org>


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

* [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 20:48   ` Frank Li
  2026-08-27 20:33 ` [PATCH 02/11] accel: ethosu: Drop IRQF_SHARED flag Rob Herring (Arm)
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

A WARN_ON() returns a 0 or 1, not the original negative errno. Just drop
the WARN_ON() as the FD open will pass the return code to userspace and
there's only one possible source of the error (drm_sched_entity_init()).

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_job.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
index 6a038c0384cc..99c8812691e5 100644
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -368,12 +368,10 @@ int ethosu_job_open(struct ethosu_file_priv *ethosu_priv)
 {
 	struct ethosu_device *dev = ethosu_priv->edev;
 	struct drm_gpu_scheduler *sched = &dev->sched;
-	int ret;
 
-	ret = drm_sched_entity_init(&ethosu_priv->sched_entity,
-				    DRM_SCHED_PRIORITY_NORMAL,
-				    &sched, 1, NULL);
-	return WARN_ON(ret);
+	return drm_sched_entity_init(&ethosu_priv->sched_entity,
+				     DRM_SCHED_PRIORITY_NORMAL,
+				     &sched, 1, NULL);
 }
 
 void ethosu_job_close(struct ethosu_file_priv *ethosu_priv)

-- 
2.53.0


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

* [PATCH 02/11] accel: ethosu: Drop IRQF_SHARED flag
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
  2026-08-27 20:33 ` [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 20:49   ` Frank Li
  2026-08-27 20:33 ` [PATCH 03/11] accel: ethosu: Ensure cmd stream ends with a stop op Rob Herring (Arm)
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

The IRQF_SHARED flag doesn't work with runtime-pm as the IRQ handler
could run without resuming the device. This could also be fixed with
runtime-pm calls in the IRQ handler, but there is no known need for a
shared IRQ.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_job.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
index 99c8812691e5..c33f2877b385 100644
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -337,7 +337,7 @@ int ethosu_job_init(struct ethosu_device *edev)
 	ret = devm_request_threaded_irq(dev, edev->irq,
 					ethosu_job_irq_handler,
 					ethosu_job_irq_handler_thread,
-					IRQF_SHARED, KBUILD_MODNAME,
+					0, KBUILD_MODNAME,
 					edev);
 	if (ret) {
 		dev_err(dev, "failed to request irq\n");

-- 
2.53.0


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

* [PATCH 03/11] accel: ethosu: Ensure cmd stream ends with a stop op
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
  2026-08-27 20:33 ` [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value Rob Herring (Arm)
  2026-08-27 20:33 ` [PATCH 02/11] accel: ethosu: Drop IRQF_SHARED flag Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 20:52   ` Frank Li
  2026-08-27 20:33 ` [PATCH 04/11] accel: ethosu: Ensure SRAM size is 0 on mapping failure Rob Herring (Arm)
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

While the QSIZE register setting should prevent an out of bounds access
of the command stream, it is not clear whether the h/w generates an
interrupt in this case as is required (to prevent a timeout). As a stop op
is expected end of the command stream, let's just ensure it is present. A
stop op in the middle of the command stream also makes no sense.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_device.h | 1 +
 drivers/accel/ethosu/ethosu_gem.c    | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h
index d4458eac8447..1eca8590e68d 100644
--- a/drivers/accel/ethosu/ethosu_device.h
+++ b/drivers/accel/ethosu/ethosu_device.h
@@ -87,6 +87,7 @@ struct gen_pool;
 #define PMU_EV_TYPE_IDLE	0x20
 
 enum ethosu_cmds {
+	NPU_OP_STOP = 0x0,
 	NPU_OP_CONV = 0x2,
 	NPU_OP_DEPTHWISE = 0x3,
 	NPU_OP_POOL = 0x5,
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index d50fed64d4d9..eda9f42239be 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -390,6 +390,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 	struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc_obj(*info);
 	struct ethosu_device *edev = to_ethosu_device(ddev);
 	u32 *bocmds = bo->base.vaddr;
+	bool ends_with_stop = false;
 	struct cmd_state st;
 	int i, ret;
 
@@ -426,6 +427,11 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 		}
 
 		switch (cmd) {
+		case NPU_OP_STOP:
+			if (i != size / 4 - 1)
+				return -EINVAL;
+			ends_with_stop = true;
+			break;
 		case NPU_OP_DMA_START:
 			srclen = dma_length(info, &st.dma, &st.dma.src);
 			dstlen = dma_length(info, &st.dma, &st.dma.dst);
@@ -688,6 +694,9 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 		}
 	}
 
+	if (!ends_with_stop)
+		return -EINVAL;
+
 	for (i = 0; i < NPU_BASEP_REGION_MAX; i++) {
 		if (!info->region_size[i])
 			continue;

-- 
2.53.0


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

* [PATCH 04/11] accel: ethosu: Ensure SRAM size is 0 on mapping failure
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (2 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 03/11] accel: ethosu: Ensure cmd stream ends with a stop op Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 20:55   ` Frank Li
  2026-08-27 20:33 ` [PATCH 05/11] accel: ethosu: Ensure SRAM region size matches job Rob Herring (Arm)
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

On a mapping failure of the SRAM, the SRAM size is left as non-zero. The
probe will succeed as the error return is not checked since having SRAM is
not a hard requirement. The non-zero size allows jobs to access SRAM which
is left pointing to physical base address 0x0.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c
index d121fb0d7732..f1af7b3ea038 100644
--- a/drivers/accel/ethosu/ethosu_drv.c
+++ b/drivers/accel/ethosu/ethosu_drv.c
@@ -281,8 +281,6 @@ static int ethosu_device_suspend(struct device *dev)
 
 static int ethosu_sram_init(struct ethosu_device *ethosudev)
 {
-	ethosudev->npu_info.sram_size = 0;
-
 	ethosudev->srampool = of_gen_pool_get(ethosudev->base.dev->of_node, "sram", 0);
 	if (!ethosudev->srampool)
 		return 0;
@@ -293,6 +291,7 @@ static int ethosu_sram_init(struct ethosu_device *ethosudev)
 							     ethosudev->npu_info.sram_size,
 							     &ethosudev->sramphys);
 	if (!ethosudev->sram) {
+		ethosudev->npu_info.sram_size = 0;
 		dev_err(ethosudev->base.dev, "failed to allocate from SRAM pool\n");
 		return -ENOMEM;
 	}

-- 
2.53.0


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

* [PATCH 05/11] accel: ethosu: Ensure SRAM region size matches job
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (3 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 04/11] accel: ethosu: Ensure SRAM size is 0 on mapping failure Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 20:57   ` Frank Li
  2026-08-27 20:33 ` [PATCH 06/11] accel: ethosu: Fix probe error cleanup Rob Herring (Arm)
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

It is possible for userspace to set the job SRAM size to 0, but then still
have SRAM accesses in the command stream. When the job SRAM size is 0,
setting the region base register is skipped and a stale base address from
a prior job is used.

Check the region size against the job's SRAM size instead of just the size
of the SRAM. The job's SRAM size was already checked against the total SRAM
size.

Fixes: 9cff90774872 ("accel: ethosu: Validate SRAM size on submit")
Cc: stable@vger.kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_job.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
index c33f2877b385..0982722a9195 100644
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -441,13 +441,13 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file
 			if (!cmd_info->region_size[i])
 				continue;
 			if (i == ETHOSU_SRAM_REGION) {
-				if (cmd_info->region_size[i] <= edev->npu_info.sram_size)
+				if (cmd_info->region_size[i] <= ejob->sram_size)
 					continue;
 
 				dev_err(dev->dev,
-					"cmd stream region %d size greater than SRAM size (%llu > %u)\n",
+					"cmd stream region %d size greater than job SRAM size (%llu > %u)\n",
 					i, cmd_info->region_size[i],
-					edev->npu_info.sram_size);
+					ejob->sram_size);
 				ret = -EINVAL;
 				goto out_cleanup_job;
 			}

-- 
2.53.0


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

* [PATCH 06/11] accel: ethosu: Fix probe error cleanup
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (4 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 05/11] accel: ethosu: Ensure SRAM region size matches job Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 21:08   ` Frank Li
  2026-08-27 20:33 ` [PATCH 07/11] accel: ethosu: Factor buffer bounds checks Rob Herring (Arm)
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

Once the job scheduler has been initialized, failures from ethosu_init()
or drm_dev_register() return from probe without tearing it down. The
registration failure also leaves the SRAM-pool allocation in use, because
the platform remove callback is not called after a failed probe.

Unwind the initialized resources on both paths. Also do not call
drm_sched_fini() after a failed drm_sched_init(): the scheduler initializer
already unwinds its partial setup, while drm_sched_fini() requires a
successfully initialized scheduler.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_drv.c | 14 ++++++++++++--
 drivers/accel/ethosu/ethosu_job.c |  6 +-----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c
index f1af7b3ea038..41ecfc623d42 100644
--- a/drivers/accel/ethosu/ethosu_drv.c
+++ b/drivers/accel/ethosu/ethosu_drv.c
@@ -371,13 +371,23 @@ static int ethosu_probe(struct platform_device *pdev)
 
 	ret = ethosu_init(ethosudev);
 	if (ret)
-		return ret;
+		goto err_job_fini;
 
 	ret = drm_dev_register(&ethosudev->base, 0);
 	if (ret)
-		pm_runtime_dont_use_autosuspend(ethosudev->base.dev);
+		goto err_pm_runtime;
+
+	pm_runtime_put_autosuspend(ethosudev->base.dev);
+	return 0;
 
+err_pm_runtime:
+	pm_runtime_dont_use_autosuspend(ethosudev->base.dev);
 	pm_runtime_put_autosuspend(ethosudev->base.dev);
+	if (ethosudev->sram)
+		gen_pool_free(ethosudev->srampool, (unsigned long)ethosudev->sram,
+			      ethosudev->npu_info.sram_size);
+err_job_fini:
+	ethosu_job_fini(ethosudev);
 	return ret;
 }
 
diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
index 0982722a9195..7cadd75ad0ba 100644
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -349,14 +349,10 @@ int ethosu_job_init(struct ethosu_device *edev)
 	ret = drm_sched_init(&edev->sched, &args);
 	if (ret) {
 		dev_err(dev, "Failed to create scheduler: %d\n", ret);
-		goto err_sched;
+		return ret;
 	}
 
 	return 0;
-
-err_sched:
-	drm_sched_fini(&edev->sched);
-	return ret;
 }
 
 void ethosu_job_fini(struct ethosu_device *dev)

-- 
2.53.0


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

* [PATCH 07/11] accel: ethosu: Factor buffer bounds checks
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (5 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 06/11] accel: ethosu: Fix probe error cleanup Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 21:10   ` Frank Li
  2026-08-27 20:33 ` [PATCH 08/11] accel: ethosu: Validate secondary streams Rob Herring (Arm)
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

Move the repeated command-stream buffer range validation into a
helper in preparation for validating all weight and scale streams.

Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_gem.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index eda9f42239be..9fce7caeeb9a 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -259,6 +259,22 @@ static u64 feat_matrix_length(struct ethosu_device *edev,
 	return addr;
 }
 
+static int buffer_size(struct ethosu_validated_cmdstream_info *info,
+		       struct buffer *buf, s8 region)
+{
+	u64 end;
+
+	if (region < 0 || buf->base == U64_MAX || buf->length == U32_MAX)
+		return -EINVAL;
+
+	if (check_add_overflow(buf->base, (u64)buf->length, &end))
+		return -EINVAL;
+
+	info->region_size[region] = max(info->region_size[region], end);
+
+	return 0;
+}
+
 static int calc_sizes(struct drm_device *ddev,
 		      struct ethosu_validated_cmdstream_info *info,
 		      u16 op, struct cmd_state *st,
@@ -303,24 +319,16 @@ static int calc_sizes(struct drm_device *ddev,
 		dev_dbg(ddev->dev, "op %d: W:%d:0x%llx-0x%llx\n",
 			op, st->weight[0].region, st->weight[0].base,
 			st->weight[0].base + st->weight[0].length - 1);
-		if (st->weight[0].region < 0 || st->weight[0].base == U64_MAX ||
-		    st->weight[0].length == U32_MAX)
+		if (buffer_size(info, &st->weight[0], st->weight[0].region))
 			return -EINVAL;
-		info->region_size[st->weight[0].region] =
-			max(info->region_size[st->weight[0].region],
-			    st->weight[0].base + st->weight[0].length);
 	}
 
 	if (scale) {
 		dev_dbg(ddev->dev, "op %d: S:%d:0x%llx-0x%llx\n",
 			op, st->scale[0].region, st->scale[0].base,
 			st->scale[0].base + st->scale[0].length - 1);
-		if (st->scale[0].region < 0 || st->scale[0].base == U64_MAX ||
-		    st->scale[0].length == U32_MAX)
+		if (buffer_size(info, &st->scale[0], st->scale[0].region))
 			return -EINVAL;
-		info->region_size[st->scale[0].region] =
-			max(info->region_size[st->scale[0].region],
-			    st->scale[0].base + st->scale[0].length);
 	}
 
 	len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,

-- 
2.53.0


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

* [PATCH 08/11] accel: ethosu: Validate secondary streams
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (6 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 07/11] accel: ethosu: Factor buffer bounds checks Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 21:14   ` Frank Li
  2026-08-27 20:33 ` [PATCH 09/11] accel: ethosu: Reject unsupported commands Rob Herring (Arm)
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

The command-stream validator records the additional U65 scale and
weight stream addresses and the U85 weight decoder addresses, but only
checked stream 0 against its region buffer.

Check every configured secondary stream against the matching weight or
scale region before accepting a kernel operation.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_gem.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index 9fce7caeeb9a..3d1f4121db4f 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -321,6 +321,15 @@ static int calc_sizes(struct drm_device *ddev,
 			st->weight[0].base + st->weight[0].length - 1);
 		if (buffer_size(info, &st->weight[0], st->weight[0].region))
 			return -EINVAL;
+
+		for (int i = 1; i < ARRAY_SIZE(st->weight); i++) {
+			if (st->weight[i].base == U64_MAX &&
+			    st->weight[i].length == U32_MAX)
+				continue;
+
+			if (buffer_size(info, &st->weight[i], st->weight[0].region))
+				return -EINVAL;
+		}
 	}
 
 	if (scale) {
@@ -329,6 +338,12 @@ static int calc_sizes(struct drm_device *ddev,
 			st->scale[0].base + st->scale[0].length - 1);
 		if (buffer_size(info, &st->scale[0], st->scale[0].region))
 			return -EINVAL;
+
+		if (ethosu_is_u65(edev) &&
+		    (st->scale[1].base != U64_MAX ||
+		     st->scale[1].length != U32_MAX) &&
+		    buffer_size(info, &st->scale[1], st->scale[0].region))
+			return -EINVAL;
 	}
 
 	len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,

-- 
2.53.0


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

* [PATCH 09/11] accel: ethosu: Reject unsupported commands
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (7 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 08/11] accel: ethosu: Validate secondary streams Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 21:16   ` Frank Li
  2026-08-27 20:33 ` [PATCH 10/11] accel: ethosu: Validate all feature map tiles Rob Herring (Arm)
  2026-08-27 20:33 ` [PATCH 11/11] accel: ethosu: Validate OFM transpose Rob Herring (Arm)
  10 siblings, 1 reply; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

The command-stream validator does not model U85 branches, indexed DMA,
or OFM transposes. A branch can bypass the linear validation state,
indexed DMA accesses an unchecked index buffer, and a transpose changes
the feature-map address calculation.

Reject those commands and configurations, as well as the reserved DMA
stride mode and feature-map formats. Reject command-stream IRQs because
they can signal job completion before later commands finish.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_device.h |  4 ++++
 drivers/accel/ethosu/ethosu_gem.c    | 17 +++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h
index 1eca8590e68d..c330048dbcca 100644
--- a/drivers/accel/ethosu/ethosu_device.h
+++ b/drivers/accel/ethosu/ethosu_device.h
@@ -86,14 +86,18 @@ struct gen_pool;
 #define PMU_EV_TYPE_CYCLES	0x11
 #define PMU_EV_TYPE_IDLE	0x20
 
+#define NPU_DMA_REGION_INDEX_MODE	BIT(11)
+
 enum ethosu_cmds {
 	NPU_OP_STOP = 0x0,
+	NPU_OP_IRQ = 0x1,
 	NPU_OP_CONV = 0x2,
 	NPU_OP_DEPTHWISE = 0x3,
 	NPU_OP_POOL = 0x5,
 	NPU_OP_ELEMENTWISE = 0x6,
 	NPU_OP_RESIZE = 0x7,	// U85 only
 	NPU_OP_DMA_START = 0x10,
+	NPU_OP_BRANCH = 0x4100,	// U85 only
 	NPU_SET_IFM_PAD_TOP = 0x100,
 	NPU_SET_IFM_PAD_LEFT = 0x101,
 	NPU_SET_IFM_PAD_RIGHT = 0x102,
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index 3d1f4121db4f..2aafbfe95a8c 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -450,6 +450,9 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 		}
 
 		switch (cmd) {
+		case NPU_OP_BRANCH:
+		case NPU_OP_IRQ:
+			return -EINVAL;
 		case NPU_OP_STOP:
 			if (i != size / 4 - 1)
 				return -EINVAL;
@@ -522,6 +525,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 			st.ifm.depth = param;
 			break;
 		case NPU_SET_IFM_PRECISION:
+			if (((param >> 6) & 0x3) > 1)
+				return -EINVAL;
 			st.ifm.precision = param;
 			break;
 		case NPU_SET_IFM_BROADCAST:
@@ -565,6 +570,10 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 			st.ofm.depth = param;
 			break;
 		case NPU_SET_OFM_PRECISION:
+			if (((param >> 6) & 0x3) > 1)
+				return -EINVAL;
+			if (!ethosu_is_u65(edev) && (param & GENMASK(13, 11)))
+				return -EINVAL;
 			st.ofm.precision = param;
 			break;
 		case NPU_SET_OFM_REGION:
@@ -599,6 +608,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 			st.ifm2.broadcast = param;
 			break;
 		case NPU_SET_IFM2_PRECISION:
+			if (((param >> 6) & 0x3) > 1)
+				return -EINVAL;
 			st.ifm2.precision = param;
 			break;
 		case NPU_SET_IFM2_REGION:
@@ -673,13 +684,19 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 			break;
 
 		case NPU_SET_DMA0_SRC_REGION:
+			if (param & NPU_DMA_REGION_INDEX_MODE)
+				return -EINVAL;
 			if (param & 0x100)
 				st.dma.src.region = -1;
 			else
 				st.dma.src.region = param & 0x7;
 			st.dma.mode = (param >> 9) & 0x3;
+			if (st.dma.mode == 3)
+				return -EINVAL;
 			break;
 		case NPU_SET_DMA0_DST_REGION:
+			if (param & NPU_DMA_REGION_INDEX_MODE)
+				return -EINVAL;
 			if (param & 0x100)
 				st.dma.dst.region = -1;
 			else

-- 
2.53.0


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

* [PATCH 10/11] accel: ethosu: Validate all feature map tiles
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (8 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 09/11] accel: ethosu: Reject unsupported commands Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  2026-08-27 20:33 ` [PATCH 11/11] accel: ethosu: Validate OFM transpose Rob Herring (Arm)
  10 siblings, 0 replies; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

The command-stream validator checked only the final feature-map
coordinate. For tiled tensors, this can leave an earlier tile base
address unchecked even though the operation accesses it.

Check the final coordinate of every tile touched by an operation. Also
treat U65 feature maps as 2x2 tiled: its precision rounding bits are not
the U85 storage encoding.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_gem.c | 117 ++++++++++++++++++++++++++++++--------
 1 file changed, 93 insertions(+), 24 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index 2aafbfe95a8c..a042e650f626 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -259,6 +259,72 @@ static u64 feat_matrix_length(struct ethosu_device *edev,
 	return addr;
 }
 
+static int feat_matrix_check_location(struct ethosu_device *edev,
+				      struct ethosu_validated_cmdstream_info *info,
+				      struct feat_matrix *fm, u32 x, u32 y, u32 c,
+				      bool ofm, u64 *max_len)
+{
+	u64 len;
+
+	len = feat_matrix_length(edev, info, fm, x, y, c, ofm);
+	if (len == U64_MAX)
+		return -EINVAL;
+
+	*max_len = max(*max_len, len);
+	return 0;
+}
+
+static int feat_matrix_size(struct ethosu_device *edev,
+			    struct ethosu_validated_cmdstream_info *info,
+			    struct feat_matrix *fm,
+			    u32 x, u32 y, u32 c, bool ofm, u64 *max_len)
+{
+	u32 storage = ethosu_is_u65(edev) ? 0 : fm->precision >> 14;
+	int ret;
+
+	*max_len = 0;
+
+	if (ethosu_is_u65(edev) || storage == 0) {
+		for (int xi = 0; xi < 2; xi++) {
+			for (int yi = 0; yi < 2; yi++) {
+				ret = feat_matrix_check_location(edev, info, fm,
+								 xi ? x : 0,
+								 yi ? y : 0, c, ofm,
+								 max_len);
+				if (ret)
+					return ret;
+			}
+		}
+		return 0;
+	}
+
+	if (storage == 1) {
+		ret = feat_matrix_check_location(edev, info, fm, x, 0, c,
+						 ofm, max_len);
+		if (ret)
+			return ret;
+		if (fm->height[0] < fm->height[1] && fm->height[1] <= y) {
+			ret = feat_matrix_check_location(edev, info, fm, x,
+							 fm->height[1], c, ofm,
+							 max_len);
+			if (ret)
+				return ret;
+		}
+		if (fm->height[1] < y) {
+			ret = feat_matrix_check_location(edev, info, fm, x,
+							 fm->height[1] + 1, c, ofm,
+							 max_len);
+			if (ret)
+				return ret;
+		}
+		return feat_matrix_check_location(edev, info, fm, x, y, c,
+						  ofm, max_len);
+	}
+
+	return feat_matrix_check_location(edev, info, fm, x, y, c, ofm,
+					  max_len);
+}
+
 static int buffer_size(struct ethosu_validated_cmdstream_info *info,
 		       struct buffer *buf, s8 region)
 {
@@ -282,6 +348,7 @@ static int calc_sizes(struct drm_device *ddev,
 {
 	struct ethosu_device *edev = to_ethosu_device(ddev);
 	u64 len;
+	int ret;
 
 	if (ifm) {
 		if (st->ifm.stride_kernel == U16_MAX)
@@ -298,21 +365,22 @@ static int calc_sizes(struct drm_device *ddev,
 		if (ifm_height < 0 || ifm_width < 0)
 			return -EINVAL;
 
-		len = feat_matrix_length(edev, info, &st->ifm, ifm_width,
-					 ifm_height, st->ifm.depth, false);
+		ret = feat_matrix_size(edev, info, &st->ifm,
+				       ifm_width, ifm_height, st->ifm.depth, false,
+					       &len);
 		dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n",
 			op, st->ifm.region, st->ifm.base[0], len);
-		if (len == U64_MAX)
-			return -EINVAL;
+		if (ret)
+			return ret;
 	}
 
 	if (ifm2) {
-		len = feat_matrix_length(edev, info, &st->ifm2, st->ifm.depth,
-					 0, st->ofm.depth, false);
+		ret = feat_matrix_size(edev, info, &st->ifm2,
+				       st->ifm.depth, 0, st->ofm.depth, false, &len);
 		dev_dbg(ddev->dev, "op %d: IFM2:%d:0x%llx-0x%llx\n",
 			op, st->ifm2.region, st->ifm2.base[0], len);
-		if (len == U64_MAX)
-			return -EINVAL;
+		if (ret)
+			return ret;
 	}
 
 	if (weight) {
@@ -346,12 +414,12 @@ static int calc_sizes(struct drm_device *ddev,
 			return -EINVAL;
 	}
 
-	len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,
-				 st->ofm.height[2], st->ofm.depth, true);
+	ret = feat_matrix_size(edev, info, &st->ofm, st->ofm.width,
+			       st->ofm.height[2], st->ofm.depth, true, &len);
 	dev_dbg(ddev->dev, "op %d: OFM:%d:0x%llx-0x%llx\n",
 		op, st->ofm.region, st->ofm.base[0], len);
-	if (len == U64_MAX)
-		return -EINVAL;
+	if (ret)
+		return ret;
 	if (!feat_matrix_chained(edev, &st->ofm))
 		info->output_region[st->ofm.region] = true;
 
@@ -366,18 +434,19 @@ static int calc_sizes_elemwise(struct drm_device *ddev,
 	struct ethosu_device *edev = to_ethosu_device(ddev);
 	u32 height, width, depth;
 	u64 len;
+	int ret;
 
 	if (ifm) {
 		height = st->ifm.broadcast & 0x1 ? 0 : st->ofm.height[2];
 		width = st->ifm.broadcast & 0x2 ? 0 : st->ofm.width;
 		depth = st->ifm.broadcast & 0x4 ? 0 : st->ofm.depth;
 
-		len = feat_matrix_length(edev, info, &st->ifm, width,
-					 height, depth, false);
+		ret = feat_matrix_size(edev, info, &st->ifm, width, height,
+				       depth, false, &len);
 		dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n",
 			op, st->ifm.region, st->ifm.base[0], len);
-		if (len == U64_MAX)
-			return -EINVAL;
+		if (ret)
+			return ret;
 	}
 
 	if (ifm2) {
@@ -385,20 +454,20 @@ static int calc_sizes_elemwise(struct drm_device *ddev,
 		width = st->ifm2.broadcast & 0x2 ? 0 : st->ofm.width;
 		depth = st->ifm2.broadcast & 0x4 ? 0 : st->ofm.depth;
 
-		len = feat_matrix_length(edev, info, &st->ifm2, width,
-					 height, depth, false);
+		ret = feat_matrix_size(edev, info, &st->ifm2, width, height,
+				       depth, false, &len);
 		dev_dbg(ddev->dev, "op %d: IFM2:%d:0x%llx-0x%llx\n",
 			op, st->ifm2.region, st->ifm2.base[0], len);
-		if (len == U64_MAX)
-			return -EINVAL;
+		if (ret)
+			return ret;
 	}
 
-	len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,
-				 st->ofm.height[2], st->ofm.depth, true);
+	ret = feat_matrix_size(edev, info, &st->ofm, st->ofm.width,
+			       st->ofm.height[2], st->ofm.depth, true, &len);
 	dev_dbg(ddev->dev, "op %d: OFM:%d:0x%llx-0x%llx\n",
 		op, st->ofm.region, st->ofm.base[0], len);
-	if (len == U64_MAX)
-		return -EINVAL;
+	if (ret)
+		return ret;
 	if (!feat_matrix_chained(edev, &st->ofm))
 		info->output_region[st->ofm.region] = true;
 

-- 
2.53.0


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

* [PATCH 11/11] accel: ethosu: Validate OFM transpose
  2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
                   ` (9 preceding siblings ...)
  2026-08-27 20:33 ` [PATCH 10/11] accel: ethosu: Validate all feature map tiles Rob Herring (Arm)
@ 2026-08-27 20:33 ` Rob Herring (Arm)
  10 siblings, 0 replies; 21+ messages in thread
From: Rob Herring (Arm) @ 2026-08-27 20:33 UTC (permalink / raw)
  To: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann
  Cc: dri-devel, linux-kernel

U85 OFM dimensions are specified before transposition, while
tile bases and strides address the transposed feature map. Permute
the output endpoint before validating its tile and stride accesses.

Allow the defined U85 transpose encodings and reject the two
reserved encodings.

Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
---
 drivers/accel/ethosu/ethosu_device.h |  1 +
 drivers/accel/ethosu/ethosu_gem.c    | 58 ++++++++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h
index c330048dbcca..1731c43aa045 100644
--- a/drivers/accel/ethosu/ethosu_device.h
+++ b/drivers/accel/ethosu/ethosu_device.h
@@ -87,6 +87,7 @@ struct gen_pool;
 #define PMU_EV_TYPE_IDLE	0x20
 
 #define NPU_DMA_REGION_INDEX_MODE	BIT(11)
+#define NPU_OFM_TRANSPOSE_MASK		GENMASK(13, 11)
 
 enum ethosu_cmds {
 	NPU_OP_STOP = 0x0,
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index a042e650f626..ad36fb8b3b30 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -199,6 +199,52 @@ static bool feat_matrix_chained(struct ethosu_device *edev, struct feat_matrix *
 	return !ethosu_is_u65(edev) && storage == 2;
 }
 
+static int feat_matrix_permute(struct ethosu_device *edev,
+			       struct feat_matrix *fm, u32 *x, u32 *y,
+			       u32 *c, bool ofm)
+{
+	u32 width = *x;
+	u32 height = *y;
+	u32 depth = *c;
+	u32 transpose;
+
+	if (ethosu_is_u65(edev) || !ofm)
+		return 0;
+
+	transpose = FIELD_GET(NPU_OFM_TRANSPOSE_MASK, fm->precision);
+
+	switch (transpose) {
+	case 0: /* HWC */
+		break;
+	case 1: /* WHC */
+		*x = height;
+		*y = width;
+		break;
+	case 2: /* HCW */
+		*x = depth;
+		*c = width;
+		break;
+	case 3: /* WCH */
+		*x = depth;
+		*y = width;
+		*c = height;
+		break;
+	case 6: /* CHW */
+		*x = height;
+		*y = depth;
+		*c = width;
+		break;
+	case 7: /* CWH */
+		*y = depth;
+		*c = height;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static u64 feat_matrix_length(struct ethosu_device *edev,
 			      struct ethosu_validated_cmdstream_info *info,
 			      struct feat_matrix *fm,
@@ -283,6 +329,9 @@ static int feat_matrix_size(struct ethosu_device *edev,
 	int ret;
 
 	*max_len = 0;
+	ret = feat_matrix_permute(edev, fm, &x, &y, &c, ofm);
+	if (ret)
+		return ret;
 
 	if (ethosu_is_u65(edev) || storage == 0) {
 		for (int xi = 0; xi < 2; xi++) {
@@ -641,8 +690,13 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
 		case NPU_SET_OFM_PRECISION:
 			if (((param >> 6) & 0x3) > 1)
 				return -EINVAL;
-			if (!ethosu_is_u65(edev) && (param & GENMASK(13, 11)))
-				return -EINVAL;
+			if (!ethosu_is_u65(edev)) {
+				switch (FIELD_GET(NPU_OFM_TRANSPOSE_MASK, param)) {
+				case 4:
+				case 5:
+					return -EINVAL;
+				}
+			}
 			st.ofm.precision = param;
 			break;
 		case NPU_SET_OFM_REGION:

-- 
2.53.0


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

* Re: [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value
  2026-08-27 20:33 ` [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value Rob Herring (Arm)
@ 2026-08-27 20:48   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 20:48 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:00PM -0500, Rob Herring (Arm) wrote:
> A WARN_ON() returns a 0 or 1, not the original negative errno. Just drop
> the WARN_ON() as the FD open will pass the return code to userspace and
> there's only one possible source of the error (drm_sched_entity_init()).
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_job.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
> index 6a038c0384cc..99c8812691e5 100644
> --- a/drivers/accel/ethosu/ethosu_job.c
> +++ b/drivers/accel/ethosu/ethosu_job.c
> @@ -368,12 +368,10 @@ int ethosu_job_open(struct ethosu_file_priv *ethosu_priv)
>  {
>  	struct ethosu_device *dev = ethosu_priv->edev;
>  	struct drm_gpu_scheduler *sched = &dev->sched;
> -	int ret;
>
> -	ret = drm_sched_entity_init(&ethosu_priv->sched_entity,
> -				    DRM_SCHED_PRIORITY_NORMAL,
> -				    &sched, 1, NULL);
> -	return WARN_ON(ret);
> +	return drm_sched_entity_init(&ethosu_priv->sched_entity,
> +				     DRM_SCHED_PRIORITY_NORMAL,
> +				     &sched, 1, NULL);
>  }
>
>  void ethosu_job_close(struct ethosu_file_priv *ethosu_priv)
>
> --
> 2.53.0
>

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

* Re: [PATCH 02/11] accel: ethosu: Drop IRQF_SHARED flag
  2026-08-27 20:33 ` [PATCH 02/11] accel: ethosu: Drop IRQF_SHARED flag Rob Herring (Arm)
@ 2026-08-27 20:49   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 20:49 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:01PM -0500, Rob Herring (Arm) wrote:
> The IRQF_SHARED flag doesn't work with runtime-pm as the IRQ handler
> could run without resuming the device. This could also be fixed with
> runtime-pm calls in the IRQ handler, but there is no known need for a
> shared IRQ.
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_job.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
> index 99c8812691e5..c33f2877b385 100644
> --- a/drivers/accel/ethosu/ethosu_job.c
> +++ b/drivers/accel/ethosu/ethosu_job.c
> @@ -337,7 +337,7 @@ int ethosu_job_init(struct ethosu_device *edev)
>  	ret = devm_request_threaded_irq(dev, edev->irq,
>  					ethosu_job_irq_handler,
>  					ethosu_job_irq_handler_thread,
> -					IRQF_SHARED, KBUILD_MODNAME,
> +					0, KBUILD_MODNAME,
>  					edev);
>  	if (ret) {
>  		dev_err(dev, "failed to request irq\n");
>
> --
> 2.53.0
>

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

* Re: [PATCH 03/11] accel: ethosu: Ensure cmd stream ends with a stop op
  2026-08-27 20:33 ` [PATCH 03/11] accel: ethosu: Ensure cmd stream ends with a stop op Rob Herring (Arm)
@ 2026-08-27 20:52   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 20:52 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:02PM -0500, Rob Herring (Arm) wrote:
> While the QSIZE register setting should prevent an out of bounds access
> of the command stream, it is not clear whether the h/w generates an
> interrupt in this case as is required (to prevent a timeout). As a stop op
> is expected end of the command stream, let's just ensure it is present. A
> stop op in the middle of the command stream also makes no sense.
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_device.h | 1 +
>  drivers/accel/ethosu/ethosu_gem.c    | 9 +++++++++
>  2 files changed, 10 insertions(+)
>
> diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h
> index d4458eac8447..1eca8590e68d 100644
> --- a/drivers/accel/ethosu/ethosu_device.h
> +++ b/drivers/accel/ethosu/ethosu_device.h
> @@ -87,6 +87,7 @@ struct gen_pool;
>  #define PMU_EV_TYPE_IDLE	0x20
>
>  enum ethosu_cmds {
> +	NPU_OP_STOP = 0x0,
>  	NPU_OP_CONV = 0x2,
>  	NPU_OP_DEPTHWISE = 0x3,
>  	NPU_OP_POOL = 0x5,
> diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
> index d50fed64d4d9..eda9f42239be 100644
> --- a/drivers/accel/ethosu/ethosu_gem.c
> +++ b/drivers/accel/ethosu/ethosu_gem.c
> @@ -390,6 +390,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  	struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc_obj(*info);
>  	struct ethosu_device *edev = to_ethosu_device(ddev);
>  	u32 *bocmds = bo->base.vaddr;
> +	bool ends_with_stop = false;
>  	struct cmd_state st;
>  	int i, ret;
>
> @@ -426,6 +427,11 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  		}
>
>  		switch (cmd) {
> +		case NPU_OP_STOP:
> +			if (i != size / 4 - 1)
> +				return -EINVAL;
> +			ends_with_stop = true;
> +			break;
>  		case NPU_OP_DMA_START:
>  			srclen = dma_length(info, &st.dma, &st.dma.src);
>  			dstlen = dma_length(info, &st.dma, &st.dma.dst);
> @@ -688,6 +694,9 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  		}
>  	}
>
> +	if (!ends_with_stop)
> +		return -EINVAL;
> +
>  	for (i = 0; i < NPU_BASEP_REGION_MAX; i++) {
>  		if (!info->region_size[i])
>  			continue;
>
> --
> 2.53.0
>

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

* Re: [PATCH 04/11] accel: ethosu: Ensure SRAM size is 0 on mapping failure
  2026-08-27 20:33 ` [PATCH 04/11] accel: ethosu: Ensure SRAM size is 0 on mapping failure Rob Herring (Arm)
@ 2026-08-27 20:55   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 20:55 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:03PM -0500, Rob Herring (Arm) wrote:
> On a mapping failure of the SRAM, the SRAM size is left as non-zero. The
> probe will succeed as the error return is not checked since having SRAM is
> not a hard requirement. The non-zero size allows jobs to access SRAM which
> is left pointing to physical base address 0x0.
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_drv.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c
> index d121fb0d7732..f1af7b3ea038 100644
> --- a/drivers/accel/ethosu/ethosu_drv.c
> +++ b/drivers/accel/ethosu/ethosu_drv.c
> @@ -281,8 +281,6 @@ static int ethosu_device_suspend(struct device *dev)
>
>  static int ethosu_sram_init(struct ethosu_device *ethosudev)
>  {
> -	ethosudev->npu_info.sram_size = 0;
> -
>  	ethosudev->srampool = of_gen_pool_get(ethosudev->base.dev->of_node, "sram", 0);
>  	if (!ethosudev->srampool)
>  		return 0;
> @@ -293,6 +291,7 @@ static int ethosu_sram_init(struct ethosu_device *ethosudev)
>  							     ethosudev->npu_info.sram_size,
>  							     &ethosudev->sramphys);
>  	if (!ethosudev->sram) {
> +		ethosudev->npu_info.sram_size = 0;
>  		dev_err(ethosudev->base.dev, "failed to allocate from SRAM pool\n");
>  		return -ENOMEM;
>  	}
>
> --
> 2.53.0
>

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

* Re: [PATCH 05/11] accel: ethosu: Ensure SRAM region size matches job
  2026-08-27 20:33 ` [PATCH 05/11] accel: ethosu: Ensure SRAM region size matches job Rob Herring (Arm)
@ 2026-08-27 20:57   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 20:57 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:04PM -0500, Rob Herring (Arm) wrote:
> It is possible for userspace to set the job SRAM size to 0, but then still
> have SRAM accesses in the command stream. When the job SRAM size is 0,
> setting the region base register is skipped and a stale base address from
> a prior job is used.
>
> Check the region size against the job's SRAM size instead of just the size
> of the SRAM. The job's SRAM size was already checked against the total SRAM
> size.
>
> Fixes: 9cff90774872 ("accel: ethosu: Validate SRAM size on submit")
> Cc: stable@vger.kernel.org
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_job.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
> index c33f2877b385..0982722a9195 100644
> --- a/drivers/accel/ethosu/ethosu_job.c
> +++ b/drivers/accel/ethosu/ethosu_job.c
> @@ -441,13 +441,13 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file
>  			if (!cmd_info->region_size[i])
>  				continue;
>  			if (i == ETHOSU_SRAM_REGION) {
> -				if (cmd_info->region_size[i] <= edev->npu_info.sram_size)
> +				if (cmd_info->region_size[i] <= ejob->sram_size)
>  					continue;
>
>  				dev_err(dev->dev,
> -					"cmd stream region %d size greater than SRAM size (%llu > %u)\n",
> +					"cmd stream region %d size greater than job SRAM size (%llu > %u)\n",
>  					i, cmd_info->region_size[i],
> -					edev->npu_info.sram_size);
> +					ejob->sram_size);
>  				ret = -EINVAL;
>  				goto out_cleanup_job;
>  			}
>
> --
> 2.53.0
>

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

* Re: [PATCH 06/11] accel: ethosu: Fix probe error cleanup
  2026-08-27 20:33 ` [PATCH 06/11] accel: ethosu: Fix probe error cleanup Rob Herring (Arm)
@ 2026-08-27 21:08   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 21:08 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:05PM -0500, Rob Herring (Arm) wrote:
> Once the job scheduler has been initialized, failures from ethosu_init()
> or drm_dev_register() return from probe without tearing it down. The
> registration failure also leaves the SRAM-pool allocation in use, because
> the platform remove callback is not called after a failed probe.
>
> Unwind the initialized resources on both paths. Also do not call
> drm_sched_fini() after a failed drm_sched_init(): the scheduler initializer
> already unwinds its partial setup, while drm_sched_fini() requires a
> successfully initialized scheduler.
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
>  drivers/accel/ethosu/ethosu_drv.c | 14 ++++++++++++--
>  drivers/accel/ethosu/ethosu_job.c |  6 +-----
>  2 files changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c
> index f1af7b3ea038..41ecfc623d42 100644
> --- a/drivers/accel/ethosu/ethosu_drv.c
> +++ b/drivers/accel/ethosu/ethosu_drv.c
> @@ -371,13 +371,23 @@ static int ethosu_probe(struct platform_device *pdev)
>
>  	ret = ethosu_init(ethosudev);
>  	if (ret)
> -		return ret;
> +		goto err_job_fini;
>
>  	ret = drm_dev_register(&ethosudev->base, 0);

Does this involve any hardware access by callbck? I suppose
pm_runtime_put_autosuspend() should be end of ethosu_init().

>  	if (ret)
> -		pm_runtime_dont_use_autosuspend(ethosudev->base.dev);
> +		goto err_pm_runtime;
> +
> +	pm_runtime_put_autosuspend(ethosudev->base.dev);
> +	return 0;
>
> +err_pm_runtime:
> +	pm_runtime_dont_use_autosuspend(ethosudev->base.dev);

it should be call by pm_runtime_disable_action().

Frank
>  	pm_runtime_put_autosuspend(ethosudev->base.dev);
> +	if (ethosudev->sram)
> +		gen_pool_free(ethosudev->srampool, (unsigned long)ethosudev->sram,
> +			      ethosudev->npu_info.sram_size);
> +err_job_fini:
> +	ethosu_job_fini(ethosudev);
>  	return ret;
>  }
>
> diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c
> index 0982722a9195..7cadd75ad0ba 100644
> --- a/drivers/accel/ethosu/ethosu_job.c
> +++ b/drivers/accel/ethosu/ethosu_job.c
> @@ -349,14 +349,10 @@ int ethosu_job_init(struct ethosu_device *edev)
>  	ret = drm_sched_init(&edev->sched, &args);
>  	if (ret) {
>  		dev_err(dev, "Failed to create scheduler: %d\n", ret);
> -		goto err_sched;
> +		return ret;
>  	}
>
>  	return 0;
> -
> -err_sched:
> -	drm_sched_fini(&edev->sched);
> -	return ret;
>  }
>
>  void ethosu_job_fini(struct ethosu_device *dev)
>
> --
> 2.53.0
>

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

* Re: [PATCH 07/11] accel: ethosu: Factor buffer bounds checks
  2026-08-27 20:33 ` [PATCH 07/11] accel: ethosu: Factor buffer bounds checks Rob Herring (Arm)
@ 2026-08-27 21:10   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 21:10 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:06PM -0500, Rob Herring (Arm) wrote:
> Move the repeated command-stream buffer range validation into a
> helper in preparation for validating all weight and scale streams.
>
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_gem.c | 28 ++++++++++++++++++----------
>  1 file changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
> index eda9f42239be..9fce7caeeb9a 100644
> --- a/drivers/accel/ethosu/ethosu_gem.c
> +++ b/drivers/accel/ethosu/ethosu_gem.c
> @@ -259,6 +259,22 @@ static u64 feat_matrix_length(struct ethosu_device *edev,
>  	return addr;
>  }
>
> +static int buffer_size(struct ethosu_validated_cmdstream_info *info,
> +		       struct buffer *buf, s8 region)
> +{
> +	u64 end;
> +
> +	if (region < 0 || buf->base == U64_MAX || buf->length == U32_MAX)
> +		return -EINVAL;
> +
> +	if (check_add_overflow(buf->base, (u64)buf->length, &end))
> +		return -EINVAL;
> +
> +	info->region_size[region] = max(info->region_size[region], end);
> +
> +	return 0;
> +}
> +
>  static int calc_sizes(struct drm_device *ddev,
>  		      struct ethosu_validated_cmdstream_info *info,
>  		      u16 op, struct cmd_state *st,
> @@ -303,24 +319,16 @@ static int calc_sizes(struct drm_device *ddev,
>  		dev_dbg(ddev->dev, "op %d: W:%d:0x%llx-0x%llx\n",
>  			op, st->weight[0].region, st->weight[0].base,
>  			st->weight[0].base + st->weight[0].length - 1);
> -		if (st->weight[0].region < 0 || st->weight[0].base == U64_MAX ||
> -		    st->weight[0].length == U32_MAX)
> +		if (buffer_size(info, &st->weight[0], st->weight[0].region))
>  			return -EINVAL;
> -		info->region_size[st->weight[0].region] =
> -			max(info->region_size[st->weight[0].region],
> -			    st->weight[0].base + st->weight[0].length);
>  	}
>
>  	if (scale) {
>  		dev_dbg(ddev->dev, "op %d: S:%d:0x%llx-0x%llx\n",
>  			op, st->scale[0].region, st->scale[0].base,
>  			st->scale[0].base + st->scale[0].length - 1);
> -		if (st->scale[0].region < 0 || st->scale[0].base == U64_MAX ||
> -		    st->scale[0].length == U32_MAX)
> +		if (buffer_size(info, &st->scale[0], st->scale[0].region))
>  			return -EINVAL;
> -		info->region_size[st->scale[0].region] =
> -			max(info->region_size[st->scale[0].region],
> -			    st->scale[0].base + st->scale[0].length);
>  	}
>
>  	len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,
>
> --
> 2.53.0
>

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

* Re: [PATCH 08/11] accel: ethosu: Validate secondary streams
  2026-08-27 20:33 ` [PATCH 08/11] accel: ethosu: Validate secondary streams Rob Herring (Arm)
@ 2026-08-27 21:14   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 21:14 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:07PM -0500, Rob Herring (Arm) wrote:
> The command-stream validator records the additional U65 scale and
> weight stream addresses and the U85 weight decoder addresses, but only
> checked stream 0 against its region buffer.
>
> Check every configured secondary stream against the matching weight or
> scale region before accepting a kernel operation.
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
>  drivers/accel/ethosu/ethosu_gem.c | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
>
> diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
> index 9fce7caeeb9a..3d1f4121db4f 100644
> --- a/drivers/accel/ethosu/ethosu_gem.c
> +++ b/drivers/accel/ethosu/ethosu_gem.c
> @@ -321,6 +321,15 @@ static int calc_sizes(struct drm_device *ddev,
>  			st->weight[0].base + st->weight[0].length - 1);
>  		if (buffer_size(info, &st->weight[0], st->weight[0].region))
>  			return -EINVAL;
> +
> +		for (int i = 1; i < ARRAY_SIZE(st->weight); i++) {

why not also put 0 into this loop?

> +			if (st->weight[i].base == U64_MAX &&
> +			    st->weight[i].length == U32_MAX)
> +				continue;
> +
> +			if (buffer_size(info, &st->weight[i], st->weight[0].region))

Just make sure 0 of st->weight[0].region is not typo, all weight share
one region?

Frank

> +				return -EINVAL;
> +		}
>  	}
>
>  	if (scale) {
> @@ -329,6 +338,12 @@ static int calc_sizes(struct drm_device *ddev,
>  			st->scale[0].base + st->scale[0].length - 1);
>  		if (buffer_size(info, &st->scale[0], st->scale[0].region))
>  			return -EINVAL;
> +
> +		if (ethosu_is_u65(edev) &&
> +		    (st->scale[1].base != U64_MAX ||
> +		     st->scale[1].length != U32_MAX) &&
> +		    buffer_size(info, &st->scale[1], st->scale[0].region))
> +			return -EINVAL;
>  	}
>
>  	len = feat_matrix_length(edev, info, &st->ofm, st->ofm.width,
>
> --
> 2.53.0
>

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

* Re: [PATCH 09/11] accel: ethosu: Reject unsupported commands
  2026-08-27 20:33 ` [PATCH 09/11] accel: ethosu: Reject unsupported commands Rob Herring (Arm)
@ 2026-08-27 21:16   ` Frank Li
  0 siblings, 0 replies; 21+ messages in thread
From: Frank Li @ 2026-08-27 21:16 UTC (permalink / raw)
  To: Rob Herring (Arm)
  Cc: Tomeu Vizoso, Oded Gabbay, Frank Li, Thomas Zimmermann,
	dri-devel, linux-kernel

On Thu, Aug 27, 2026 at 03:33:08PM -0500, Rob Herring (Arm) wrote:
> The command-stream validator does not model U85 branches, indexed DMA,
> or OFM transposes. A branch can bypass the linear validation state,
> indexed DMA accesses an unchecked index buffer, and a transpose changes
> the feature-map address calculation.
>
> Reject those commands and configurations, as well as the reserved DMA
> stride mode and feature-map formats. Reject command-stream IRQs because
> they can signal job completion before later commands finish.
>
> Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
> Cc: stable@vger.kernel.org
> Assisted-by: LLM
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/accel/ethosu/ethosu_device.h |  4 ++++
>  drivers/accel/ethosu/ethosu_gem.c    | 17 +++++++++++++++++
>  2 files changed, 21 insertions(+)
>
> diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h
> index 1eca8590e68d..c330048dbcca 100644
> --- a/drivers/accel/ethosu/ethosu_device.h
> +++ b/drivers/accel/ethosu/ethosu_device.h
> @@ -86,14 +86,18 @@ struct gen_pool;
>  #define PMU_EV_TYPE_CYCLES	0x11
>  #define PMU_EV_TYPE_IDLE	0x20
>
> +#define NPU_DMA_REGION_INDEX_MODE	BIT(11)
> +
>  enum ethosu_cmds {
>  	NPU_OP_STOP = 0x0,
> +	NPU_OP_IRQ = 0x1,
>  	NPU_OP_CONV = 0x2,
>  	NPU_OP_DEPTHWISE = 0x3,
>  	NPU_OP_POOL = 0x5,
>  	NPU_OP_ELEMENTWISE = 0x6,
>  	NPU_OP_RESIZE = 0x7,	// U85 only
>  	NPU_OP_DMA_START = 0x10,
> +	NPU_OP_BRANCH = 0x4100,	// U85 only
>  	NPU_SET_IFM_PAD_TOP = 0x100,
>  	NPU_SET_IFM_PAD_LEFT = 0x101,
>  	NPU_SET_IFM_PAD_RIGHT = 0x102,
> diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
> index 3d1f4121db4f..2aafbfe95a8c 100644
> --- a/drivers/accel/ethosu/ethosu_gem.c
> +++ b/drivers/accel/ethosu/ethosu_gem.c
> @@ -450,6 +450,9 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  		}
>
>  		switch (cmd) {
> +		case NPU_OP_BRANCH:
> +		case NPU_OP_IRQ:
> +			return -EINVAL;
>  		case NPU_OP_STOP:
>  			if (i != size / 4 - 1)
>  				return -EINVAL;
> @@ -522,6 +525,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  			st.ifm.depth = param;
>  			break;
>  		case NPU_SET_IFM_PRECISION:
> +			if (((param >> 6) & 0x3) > 1)
> +				return -EINVAL;
>  			st.ifm.precision = param;
>  			break;
>  		case NPU_SET_IFM_BROADCAST:
> @@ -565,6 +570,10 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  			st.ofm.depth = param;
>  			break;
>  		case NPU_SET_OFM_PRECISION:
> +			if (((param >> 6) & 0x3) > 1)
> +				return -EINVAL;
> +			if (!ethosu_is_u65(edev) && (param & GENMASK(13, 11)))
> +				return -EINVAL;
>  			st.ofm.precision = param;
>  			break;
>  		case NPU_SET_OFM_REGION:
> @@ -599,6 +608,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  			st.ifm2.broadcast = param;
>  			break;
>  		case NPU_SET_IFM2_PRECISION:
> +			if (((param >> 6) & 0x3) > 1)
> +				return -EINVAL;
>  			st.ifm2.precision = param;
>  			break;
>  		case NPU_SET_IFM2_REGION:
> @@ -673,13 +684,19 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
>  			break;
>
>  		case NPU_SET_DMA0_SRC_REGION:
> +			if (param & NPU_DMA_REGION_INDEX_MODE)
> +				return -EINVAL;
>  			if (param & 0x100)
>  				st.dma.src.region = -1;
>  			else
>  				st.dma.src.region = param & 0x7;
>  			st.dma.mode = (param >> 9) & 0x3;
> +			if (st.dma.mode == 3)
> +				return -EINVAL;
>  			break;
>  		case NPU_SET_DMA0_DST_REGION:
> +			if (param & NPU_DMA_REGION_INDEX_MODE)
> +				return -EINVAL;
>  			if (param & 0x100)
>  				st.dma.dst.region = -1;
>  			else
>
> --
> 2.53.0
>

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

end of thread, other threads:[~2026-08-27 21:17 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-27 20:32 [PATCH 00/11] accel: ethosu: Another batch of fixes Rob Herring (Arm)
2026-08-27 20:33 ` [PATCH 01/11] accel: ethosu: Fix ethosu_job_open() return value Rob Herring (Arm)
2026-08-27 20:48   ` Frank Li
2026-08-27 20:33 ` [PATCH 02/11] accel: ethosu: Drop IRQF_SHARED flag Rob Herring (Arm)
2026-08-27 20:49   ` Frank Li
2026-08-27 20:33 ` [PATCH 03/11] accel: ethosu: Ensure cmd stream ends with a stop op Rob Herring (Arm)
2026-08-27 20:52   ` Frank Li
2026-08-27 20:33 ` [PATCH 04/11] accel: ethosu: Ensure SRAM size is 0 on mapping failure Rob Herring (Arm)
2026-08-27 20:55   ` Frank Li
2026-08-27 20:33 ` [PATCH 05/11] accel: ethosu: Ensure SRAM region size matches job Rob Herring (Arm)
2026-08-27 20:57   ` Frank Li
2026-08-27 20:33 ` [PATCH 06/11] accel: ethosu: Fix probe error cleanup Rob Herring (Arm)
2026-08-27 21:08   ` Frank Li
2026-08-27 20:33 ` [PATCH 07/11] accel: ethosu: Factor buffer bounds checks Rob Herring (Arm)
2026-08-27 21:10   ` Frank Li
2026-08-27 20:33 ` [PATCH 08/11] accel: ethosu: Validate secondary streams Rob Herring (Arm)
2026-08-27 21:14   ` Frank Li
2026-08-27 20:33 ` [PATCH 09/11] accel: ethosu: Reject unsupported commands Rob Herring (Arm)
2026-08-27 21:16   ` Frank Li
2026-08-27 20:33 ` [PATCH 10/11] accel: ethosu: Validate all feature map tiles Rob Herring (Arm)
2026-08-27 20:33 ` [PATCH 11/11] accel: ethosu: Validate OFM transpose Rob Herring (Arm)

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®