From 2c2e951258c620e30dddcca34ff6b748338922bf Mon Sep 17 00:00:00 2001 From: Hao Fang Date: Thu, 11 Jul 2019 14:41:26 +0800 Subject: [PATCH] ACC: crypto/hisilicon/qm: bugfix for clear the qp full status for async interface driver inclusion category: bugfix bugzilla: NA CVE: NA crypto/hisilicon/qm: bugfix for clear the qp full status for async interface. 1.qp_full flags should clear if sqe/cqe deal with. 2.cqe head point should update otherwise cq overflow. Signed-off-by: Hao Fang Reviewed-by: lingmingqiang Reviewed-by: wangzhou Signed-off-by: lingmingqiang Signed-off-by: Yang Yingliang --- drivers/crypto/hisilicon/qm.c | 25 +++++++++++++++++++---- drivers/crypto/hisilicon/zip/zip_crypto.c | 10 --------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 4a3c54950559..2865dd6ad59b 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -384,6 +384,17 @@ static struct hisi_qp *qm_to_hisi_qp(struct hisi_qm *qm, struct qm_eqe *eqe) return qp; } +static void qm_sq_head_update(struct hisi_qp *qp) +{ + if (qp->qp_status.sq_head == QM_Q_DEPTH - 1) + qp->qp_status.sq_head = 0; + else + qp->qp_status.sq_head++; + + if (unlikely(test_bit(QP_FULL, &qp->qp_status.flags))) + clear_bit(QP_FULL, &qp->qp_status.flags); +} + static void qm_cq_head_update(struct hisi_qp *qp) { if (qp->qp_status.cq_head == QM_Q_DEPTH - 1) { @@ -397,6 +408,7 @@ static void qm_cq_head_update(struct hisi_qp *qp) static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) { struct qm_cqe *cqe; + int cqe_num = 0; if (qp->event_cb) qp->event_cb(qp); @@ -405,16 +417,21 @@ static void qm_poll_qp(struct hisi_qp *qp, struct hisi_qm *qm) if (qp->req_cb) { while (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { + cqe_num++; dma_rmb(); qp->req_cb(qp, qp->sqe + qm->sqe_size * cqe->sq_head); + qm_sq_head_update(qp); qm_cq_head_update(qp); cqe = qp->cqe + qp->qp_status.cq_head; atomic_dec(&qp->qp_status.used); + if (cqe_num >= QM_Q_DEPTH / 2 - 1) + break; } } else { if (QM_CQE_PHASE(cqe) == qp->qp_status.cqc_phase) { dma_rmb(); + qm_sq_head_update(qp); complete(&qp->completion); qm_cq_head_update(qp); cqe = qp->cqe + qp->qp_status.cq_head; @@ -436,10 +453,10 @@ static irqreturn_t qm_irq_thread(int irq, void *data) struct hisi_qm *qm = data; struct qm_eqe *eqe = qm->eqe + qm->status.eq_head; struct hisi_qp *qp; - int num = 0; + int eqe_num = 0; while (QM_EQE_PHASE(eqe) == qm->status.eqc_phase) { - num++; + eqe_num++; qp = qm_to_hisi_qp(qm, eqe); if (qp) qm_poll_qp(qp, qm); @@ -453,9 +470,9 @@ static irqreturn_t qm_irq_thread(int irq, void *data) qm->status.eq_head++; } - if (num == QM_Q_DEPTH / 2 - 1) { + if (eqe_num == QM_Q_DEPTH / 2 - 1) { + eqe_num = 0; qm_db(qm, 0, QM_DOORBELL_CMD_EQ, qm->status.eq_head, 0); - return IRQ_HANDLED; } } diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c index bf2b076c0c73..40151b829567 100644 --- a/drivers/crypto/hisilicon/zip/zip_crypto.c +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c @@ -236,18 +236,8 @@ static void hisi_zip_copy_data_from_buffer(struct hisi_zip_qp_ctx *qp_ctx, struct hisi_zip_buffer *buffer = &qp_ctx->buffer; struct hisi_qp *qp = qp_ctx->qp; struct hisi_zip_sqe *zip_sqe = hisi_zip_get_writeback_sqe(qp); - u16 sq_head; memcpy(dst, buffer->output, zip_sqe->produced); - - sq_head = qp->qp_status.sq_head; - if (sq_head == QM_Q_DEPTH - 1) - qp->qp_status.sq_head = 0; - else - qp->qp_status.sq_head++; - - if (unlikely(test_bit(QP_FULL, &qp->qp_status.flags))) - clear_bit(QP_FULL, &qp->qp_status.flags); } static int hisi_zip_compress_data_output(struct hisi_zip_qp_ctx *qp_ctx, -- GitLab