]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
accel/amdxdna: Fill invalid payload for failed command
authorLizhi Hou <lizhi.hou@amd.com>
Fri, 27 Feb 2026 00:48:41 +0000 (16:48 -0800)
committerLizhi Hou <lizhi.hou@amd.com>
Sat, 28 Feb 2026 07:01:36 +0000 (23:01 -0800)
Newer userspace applications may read the payload of a failed command
to obtain detailed error information. However, the driver and old firmware
versions may not support returning advanced error information.
In this case, initialize the command payload with an invalid value so
userspace can detect that no detailed error information is available.

Fixes: aac243092b70 ("accel/amdxdna: Add command execution")
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260227004841.3080241-1-lizhi.hou@amd.com
drivers/accel/amdxdna/aie2_ctx.c
drivers/accel/amdxdna/amdxdna_ctx.c
drivers/accel/amdxdna/amdxdna_ctx.h

index 25845bd5e5078c0e8c23d28971142d9380739eb7..afee5e667f775a5a0c8d757e9e9820e55d9228c2 100644 (file)
@@ -186,13 +186,13 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size)
        cmd_abo = job->cmd_bo;
 
        if (unlikely(job->job_timeout)) {
-               amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT);
+               amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_TIMEOUT);
                ret = -EINVAL;
                goto out;
        }
 
        if (unlikely(!data) || unlikely(size != sizeof(u32))) {
-               amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT);
+               amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ABORT);
                ret = -EINVAL;
                goto out;
        }
@@ -202,7 +202,7 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size)
        if (status == AIE2_STATUS_SUCCESS)
                amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_COMPLETED);
        else
-               amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR);
+               amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ERROR);
 
 out:
        aie2_sched_notify(job);
@@ -244,13 +244,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size)
        cmd_abo = job->cmd_bo;
 
        if (unlikely(job->job_timeout)) {
-               amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT);
+               amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_TIMEOUT);
                ret = -EINVAL;
                goto out;
        }
 
        if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) {
-               amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT);
+               amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ABORT);
                ret = -EINVAL;
                goto out;
        }
@@ -270,19 +270,12 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size)
                 fail_cmd_idx, fail_cmd_status);
 
        if (fail_cmd_status == AIE2_STATUS_SUCCESS) {
-               amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT);
+               amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ABORT);
                ret = -EINVAL;
-               goto out;
+       } else {
+               amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ERROR);
        }
-       amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR);
 
-       if (amdxdna_cmd_get_op(cmd_abo) == ERT_CMD_CHAIN) {
-               struct amdxdna_cmd_chain *cc = amdxdna_cmd_get_payload(cmd_abo, NULL);
-
-               cc->error_index = fail_cmd_idx;
-               if (cc->error_index >= cc->command_count)
-                       cc->error_index = 0;
-       }
 out:
        aie2_sched_notify(job);
        return ret;
index 263d36072540451549c46184dd35e183c7c43862..666dfd7b2a805d776aa0b30e7b670366d58ef9fc 100644 (file)
@@ -135,6 +135,33 @@ u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo)
        return INVALID_CU_IDX;
 }
 
+int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
+                         struct amdxdna_sched_job *job, u32 cmd_idx,
+                         enum ert_cmd_state error_state)
+{
+       struct amdxdna_client *client = job->hwctx->client;
+       struct amdxdna_cmd *cmd = abo->mem.kva;
+       struct amdxdna_cmd_chain *cc = NULL;
+
+       cmd->header &= ~AMDXDNA_CMD_STATE;
+       cmd->header |= FIELD_PREP(AMDXDNA_CMD_STATE, error_state);
+
+       if (amdxdna_cmd_get_op(abo) == ERT_CMD_CHAIN) {
+               cc = amdxdna_cmd_get_payload(abo, NULL);
+               cc->error_index = (cmd_idx < cc->command_count) ? cmd_idx : 0;
+               abo = amdxdna_gem_get_obj(client, cc->data[0], AMDXDNA_BO_CMD);
+               if (!abo)
+                       return -EINVAL;
+               cmd = abo->mem.kva;
+       }
+
+       memset(cmd->data, 0xff, abo->mem.size - sizeof(*cmd));
+       if (cc)
+               amdxdna_gem_put_obj(abo);
+
+       return 0;
+}
+
 /*
  * This should be called in close() and remove(). DO NOT call in other syscalls.
  * This guarantee that when hwctx and resources will be released, if user
index 16c85f08f03c6edb0de9f9914d409b275ef66239..fbdf9d00087136966b2ad593af5405e35fc194ba 100644 (file)
@@ -167,6 +167,9 @@ amdxdna_cmd_get_state(struct amdxdna_gem_obj *abo)
 
 void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size);
 u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo);
+int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
+                         struct amdxdna_sched_job *job, u32 cmd_idx,
+                         enum ert_cmd_state error_state);
 
 void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job);
 void amdxdna_hwctx_remove_all(struct amdxdna_client *client);