[PATCH 07/11] accel: ethosu: Factor buffer bounds checks
From: Rob Herring (Arm)
Date: Thu Aug 27 2026 - 16:34:49 EST
Move the repeated command-stream buffer range validation into a
helper in preparation for validating all weight and scale streams.
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@xxxxxxxxxx>
---
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