From 3bb76d0ec446139e128d8ca46bf7d5b16b61601f Mon Sep 17 00:00:00 2001 From: lizhi Date: Wed, 6 Aug 2025 17:09:25 +0800 Subject: [PATCH] crypto: hisilicon/qm - clear the memory before enabling the device driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/ICRCS6 CVE: NA ---------------------------------------------------------------------- When the driver enables the device, memory will be allocated and configured for the device via the mailbox. As the device executes tasks, it modifies the memory to notify the software of the task status. When the device is re-enabled, the memory must be cleared before being configured for the device again. Otherwise, when the device executes new operations, the software may read incorrect task status from the memory, leading to operational failures. Currently, memory clearing is implemented in the qm_invalid_queues(). However, The qm_invalid_queues() is not called during device suspension and resumption, which results in operational failures after resuming. To address this issue, the memory clearing process should be moved to the hisi_qm_start(). Fixes: 25eef041f26c ("crypto: hisilicon/qm - invalidate queues in use") Signed-off-by: lizhi Signed-off-by: JiangShui Yang --- drivers/crypto/hisilicon/qm.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 4ebf38cf1af7..a8fb2d8c774e 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -3357,6 +3357,9 @@ static int qm_eq_aeq_ctx_cfg(struct hisi_qm *qm) qm_init_eq_aeq_status(qm); + /* Before starting the dev, clear previous task info in dma memory */ + memset(qm->qdma.va, 0, qm->qdma.size); + ret = qm_eq_ctx_cfg(qm); if (ret) { dev_err(dev, "Set eqc failed!\n"); @@ -3368,9 +3371,13 @@ static int qm_eq_aeq_ctx_cfg(struct hisi_qm *qm) static int __hisi_qm_start(struct hisi_qm *qm) { + struct device *dev = &qm->pdev->dev; int ret; - WARN_ON(!qm->qdma.va); + if (unlikely(!qm->qdma.va)) { + dev_err(dev, "dma virtual address should not be NULL\n"); + return -EINVAL; + } if (qm->fun_type == QM_HW_PF) { ret = hisi_qm_set_vft(qm, 0, qm->qp_base, qm->qp_num); @@ -3500,7 +3507,6 @@ static void qm_invalid_queues(struct hisi_qm *qm) if (qm->status.stop_reason == QM_DOWN) hisi_qm_cache_wb(qm); - memset(qm->qdma.va, 0, qm->qdma.size); for (i = 0; i < qm->qp_num; i++) { qp = &qm->qp_array[i]; if (!qp->is_resetting) -- Gitee