[PATCH v2 14/19] accel: ethosu: Reject reserved command encodings

From: Rob Herring (Arm)

Date: Fri Sep 04 2026 - 20:49:54 EST


The command stream contains a 10-bit opcode and a two-bit command
control field. Reject reserved opcode and control encodings in the
switch default case so they cannot be interpreted differently by the
validator and hardware.

Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@xxxxxxxxxxxxxxx
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <robh@xxxxxxxxxx>
---
v2:
- new patch
---
drivers/accel/ethosu/ethosu_device.h | 3 +++
drivers/accel/ethosu/ethosu_gem.c | 12 +++++++-----
2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/accel/ethosu/ethosu_device.h b/drivers/accel/ethosu/ethosu_device.h
index 8e23fdbf7f8a..68e2969b6f79 100644
--- a/drivers/accel/ethosu/ethosu_device.h
+++ b/drivers/accel/ethosu/ethosu_device.h
@@ -91,6 +91,9 @@ struct gen_pool;
#define NPU_KERNEL_DILATION_X BIT(3)
#define NPU_KERNEL_DILATION_Y BIT(4)

+#define NPU_CMD_CTRL_CMD1 BIT(14)
+#define NPU_CMD_RESERVED_MASK (BIT(15) | GENMASK(13, 10))
+
enum ethosu_cmds {
NPU_OP_STOP = 0x0,
NPU_OP_IRQ = 0x1,
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index 63dd07791f31..d5c3a2c530dc 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -160,9 +160,9 @@ static void cmd_state_init(struct cmd_state *st)

static void cmd_state_set_reg(struct cmd_state *st, u16 cmd)
{
- u16 reg = cmd & ~BIT(14);
+ u16 reg = cmd & ~NPU_CMD_CTRL_CMD1;

- if (cmd & BIT(14)) {
+ if (cmd & NPU_CMD_CTRL_CMD1) {
if (reg < NPU_CMD1_REGS)
__set_bit(reg, st->cmd1);
} else if (reg < NPU_CMD0_REGS) {
@@ -172,9 +172,9 @@ static void cmd_state_set_reg(struct cmd_state *st, u16 cmd)

static bool cmd_state_reg_is_set(struct cmd_state *st, u16 cmd)
{
- u16 reg = cmd & ~BIT(14);
+ u16 reg = cmd & ~NPU_CMD_CTRL_CMD1;

- if (cmd & BIT(14))
+ if (cmd & NPU_CMD_CTRL_CMD1)
return reg < NPU_CMD1_REGS && test_bit(reg, st->cmd1);

return reg < NPU_CMD0_REGS && test_bit(reg, st->cmd0);
@@ -702,7 +702,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
cmd = cmds[0];
param = cmds[0] >> 16;

- if (cmd & 0x4000) {
+ if (cmd & NPU_CMD_CTRL_CMD1) {
if (get_user(cmds[1], ucmds++))
return -EFAULT;

@@ -1023,6 +1023,8 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev,
st.dma.src.len = st.dma.dst.len = addr;
break;
default:
+ if (cmd & NPU_CMD_RESERVED_MASK)
+ return -EINVAL;
break;
}
}

--
2.53.0