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: [email protected]
Assisted-by: LLM
Signed-off-by: Rob Herring (Arm) <[email protected]>
---
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 578d1b5b955c..f4bd31018e56 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -170,9 +170,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) {
@@ -182,9 +182,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);
@@ -733,7 +733,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;
 
@@ -1054,6 +1054,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

Reply via email to