From 216108acda7431ddb793c352c16fcf824621fdf0 Mon Sep 17 00:00:00 2001 From: Chengwen Feng Date: Fri, 27 May 2022 11:40:54 +0800 Subject: [PATCH] dma/hisilicon: enhance CQ scan robustness [ upstream commit e03c601acb4d483a7305fb9ad15e13f6645b02e2 ] The CQ (completion queue) descriptors were updated by hardware, and then scanned by driver to retrieve hardware completion status. This patch enhances robustness by following: 1. replace while (true) with a finite loop to avoid potential dead loop. 2. check the csq_head field in CQ descriptor to avoid status array overflows. Fixes: 2db4f0b82360 ("dma/hisilicon: add data path") Signed-off-by: Chengwen Feng --- drivers/dma/hisilicon/hisi_dmadev.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/dma/hisilicon/hisi_dmadev.c b/drivers/dma/hisilicon/hisi_dmadev.c index ef4c7b18f7..ec687ef67e 100644 --- a/drivers/dma/hisilicon/hisi_dmadev.c +++ b/drivers/dma/hisilicon/hisi_dmadev.c @@ -581,7 +581,7 @@ hisi_dma_scan_cq(struct hisi_dma_dev *hw) uint16_t count = 0; uint64_t misc; - while (true) { + while (count < hw->cq_depth) { cqe = &hw->cqe[cq_head]; misc = cqe->misc; misc = rte_le_to_cpu_64(misc); @@ -589,6 +589,16 @@ hisi_dma_scan_cq(struct hisi_dma_dev *hw) break; csq_head = FIELD_GET(CQE_SQ_HEAD_MASK, misc); + if (unlikely(csq_head > hw->sq_depth_mask)) { + /** + * Defensive programming to prevent overflow of the + * status array indexed by csq_head. Only error logs + * are used for prompting. + */ + HISI_DMA_ERR(hw, "invalid csq_head:%u!\n", csq_head); + count = 0; + break; + } if (unlikely(misc & CQE_STATUS_MASK)) hw->status[csq_head] = FIELD_GET(CQE_STATUS_MASK, misc);