All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rob Herring (Arm)" <robh@kernel.org>
To: Tomeu Vizoso <tomeu@tomeuvizoso.net>,
	Oded Gabbay <ogabbay@kernel.org>,  Frank Li <Frank.Li@nxp.com>,
	Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org
Subject: [PATCH 10/11] accel: ethosu: Validate all feature map tiles
Date: Thu, 27 Aug 2026 15:33:09 -0500	[thread overview]
Message-ID: <20260827-ethosu-fixes-v1-10-346f9ea8791c@kernel.org> (raw)
In-Reply-To: <20260827-ethosu-fixes-v1-0-346f9ea8791c@kernel.org>

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


  parent reply	other threads:[~2026-08-27 20:33 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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:46   ` sashiko-bot
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:48   ` sashiko-bot
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:48   ` sashiko-bot
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:47   ` sashiko-bot
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 20:45   ` sashiko-bot
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 20:48   ` sashiko-bot
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 20:48   ` sashiko-bot
2026-08-27 21:16   ` Frank Li
2026-08-27 20:33 ` Rob Herring (Arm) [this message]
2026-08-27 20:45   ` [PATCH 10/11] accel: ethosu: Validate all feature map tiles sashiko-bot
2026-08-27 20:33 ` [PATCH 11/11] accel: ethosu: Validate OFM transpose Rob Herring (Arm)
2026-08-27 20:56   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260827-ethosu-fixes-v1-10-346f9ea8791c@kernel.org \
    --to=robh@kernel.org \
    --cc=Frank.Li@nxp.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ogabbay@kernel.org \
    --cc=tomeu@tomeuvizoso.net \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.