From: Yu'an Wang wangyuan46@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
In this patch, we try to fixup the problem of wrong judgement of used parameter. When the accelerator driver registers to crypto, the self-test program will send task to hardware, the used para will decrease in interrupt thread, but exit flow of crypto will call hisi_qm_stop_qp_nolock function to stop queue, which try to get value of used. In the above scene, it will appear to get the value first and then decrease, which causes null pointer. So we should distinguish fault handling process from normal stop process.
Signed-off-by: Yu'an Wang wangyuan46@huawei.com Reviewed-by: Cheng Hu hucheng.hu@huawei.com Reviewed-by: Guangwei Zhou zhouguangwei5@huawei.com Reviewed-by: Junxian Liu liujunxian3@huawei.com Reviewed-by: Shukun Tan tanshukun1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/crypto/hisilicon/qm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index e89a770..86f4a12 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -1591,10 +1591,12 @@ static int hisi_qm_stop_qp_nolock(struct hisi_qp *qp)
if (qp->qm->wq) flush_workqueue(qp->qm->wq); + else + flush_work(&qp->qm->work);
/* wait for increase used count in qp send and last poll qp finish */ udelay(WAIT_PERIOD); - if (atomic_read(&qp->qp_status.used)) + if (unlikely(qp->is_resetting && atomic_read(&qp->qp_status.used))) qp_stop_fail_cb(qp);
dev_dbg(dev, "stop queue %u!", qp->qp_id);
From: Yu'an Wang wangyuan46@huawei.com
driver inclusion category: bugfix bugzilla: NA CVE: NA
In this patch, we try to optimize logic of hw_reset flag setting for user. Add tx stop flag before qm_stop_started_qp and add rx stop flag after this function seem to be more reasonable, which can help us to stop sending immediately in case of hardware error, mark correctly and return error IO to upper layer.
Signed-off-by: Yu'an Wang wangyuan46@huawei.com Reviewed-by: Cheng Hu hucheng.hu@huawei.com Reviewed-by: Guangwei Zhou zhouguangwei5@huawei.com Reviewed-by: Shukun Tan tanshukun1@huawei.com Reviewed-by: Zaibo Xu xuzaibo@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/crypto/hisilicon/qm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 86f4a12..6a5337a 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -189,6 +189,9 @@ #define AM_ROB_ECC_INT_STS 0x300104 #define ROB_ECC_ERR_MULTPL BIT(1)
+#define QM_RESET_STOP_TX_OFFSET 1 +#define QM_RESET_STOP_RX_OFFSET 2 + #define QM_DBG_READ_LEN 256 #define QM_DBG_WRITE_LEN 1024 #define QM_DBG_SHOW_SHIFT 16 @@ -1725,7 +1728,7 @@ static int hisi_qm_get_available_instances(struct uacce *uacce) return hisi_qm_get_free_qp_num(uacce->priv); }
-static void hisi_qm_set_hw_reset(struct hisi_qm *qm) +static void hisi_qm_set_hw_reset(struct hisi_qm *qm, int offset) { struct hisi_qp *qp; u32 *addr; @@ -1735,7 +1738,7 @@ static void hisi_qm_set_hw_reset(struct hisi_qm *qm) qp = qm->qp_array[i]; if (qp) { /* Use last 32 bits of DUS to save reset status. */ - addr = (u32 *)(qp->qdma.va + qp->qdma.size) - 1; + addr = (u32 *)(qp->qdma.va + qp->qdma.size) - offset; *addr = 1;
/* make sure setup is completed */ @@ -2609,11 +2612,14 @@ int hisi_qm_stop(struct hisi_qm *qm, enum qm_stop_reason r)
if (qm->status.stop_reason == QM_SOFT_RESET || qm->status.stop_reason == QM_FLR) { +#ifdef CONFIG_CRYPTO_QM_UACCE + hisi_qm_set_hw_reset(qm, QM_RESET_STOP_TX_OFFSET); +#endif ret = qm_stop_started_qp(qm); if (ret < 0) goto err_unlock; #ifdef CONFIG_CRYPTO_QM_UACCE - hisi_qm_set_hw_reset(qm); + hisi_qm_set_hw_reset(qm, QM_RESET_STOP_RX_OFFSET); #endif }