From 704e3a49c40fe08705cd4737c67502fb3924bd4d Mon Sep 17 00:00:00 2001 From: Zhou Wang Date: Fri, 27 Sep 2019 14:06:07 +0800 Subject: [PATCH] crypto/hisilicon/qm:fix qp resource leak problem driver inclusion category: bugfix bugzilla: NA CVE: NA This patch fixes qp resource leak in wd when doing resetting and qp allocation/free at the same time. - When doing resetting, all started qp including qp in user space will be set to stop state. qp in kernel will be restarted after hardware reset. However, qp in user space will not, we infor user there is an error and let user to handle this. - Modify to allow qp in init state to stop state. Feature or Bugfix:Bugfix Signed-off-by: Zhou Wang Reviewed-by: xuzaibo Reviewed-by: Ling Mingqiang Reviewed-by: Yang Yingliang Signed-off-by: Yang Yingliang --- drivers/crypto/hisilicon/qm.c | 7 +++++-- drivers/crypto/hisilicon/qm.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 2e3fb14d9f1a..60695371fa1a 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -304,7 +304,8 @@ static bool qm_qp_avail_state(struct hisi_qm *qm, struct hisi_qp *qp, avail = true; break; case QP_STOP: - if (qm_curr == QM_START && qp_curr == QP_START) + if ((qm_curr == QM_START && qp_curr == QP_START) || + (qp_curr == QP_INIT)) avail = true; break; case QP_CLOSE: @@ -1200,6 +1201,7 @@ static struct hisi_qp *hisi_qm_create_qp_nolock(struct hisi_qm *qm, qp->qp_id = qp_id; qp->alg_type = alg_type; qp->c_flag = 1; + qp->is_in_kernel = true; init_completion(&qp->completion); atomic_set(&qp->qp_status.flags, QP_INIT); @@ -1638,6 +1640,7 @@ static int hisi_qm_uacce_get_queue(struct uacce *uacce, unsigned long arg, qp->uacce_q = wd_q; qp->event_cb = qm_qp_event_notifier; qp->pasid = arg; + qp->is_in_kernel = false; init_waitqueue_head(&wd_q->wait); up_write(&qm->qps_lock); @@ -2327,7 +2330,7 @@ int hisi_qm_restart(struct hisi_qm *qm) qp = qm->qp_array[i]; if (qp && atomic_read(&qp->qp_status.flags) == QP_STOP && - qp->is_resetting) { + qp->is_resetting && qp->is_in_kernel) { ret = hisi_qm_start_qp_nolock(qp, 0); if (ret < 0) { dev_err(dev, "Failed to start qp%d!\n", i); diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h index ae5c3e6d591f..1a04ad80e1f0 100644 --- a/drivers/crypto/hisilicon/qm.h +++ b/drivers/crypto/hisilicon/qm.h @@ -320,6 +320,7 @@ struct hisi_qp { struct hisi_qm *qm; bool is_resetting; + bool is_in_kernel; #ifdef CONFIG_CRYPTO_QM_UACCE u16 pasid; -- GitLab