mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] crypto: hisilicon/qm - fix bugs and harden against abnormal hardware
@ 2026-09-24 11:38 Weili Qian
  2026-09-24 11:38 ` [PATCH 1/4] crypto: hisilicon/qm - clear runtime PM flag for non-power-manageable device Weili Qian
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Weili Qian @ 2026-09-24 11:38 UTC (permalink / raw)
  To: herbert; +Cc: linux-kernel, linux-crypto, liulongfang

This series fixes bugs in the hisilicon/qm driver and adds
checks for abnormal hardware.

Weili Qian (4):
  crypto: hisilicon/qm - clear runtime PM flag for non-power-manageable
    device
  crypto: hisilicon/qm - return error for abnormal device capability
    version
  crypto: hisilicon/qm - check queue depth read from hardware
  crypto: hisilicon/qm - fix uacce leak when SVA is not supported

 drivers/crypto/hisilicon/qm.c | 64 +++++++++++++++++++++++++++++------
 1 file changed, 53 insertions(+), 11 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] crypto: hisilicon/qm - clear runtime PM flag for non-power-manageable device
  2026-09-24 11:38 [PATCH 0/4] crypto: hisilicon/qm - fix bugs and harden against abnormal hardware Weili Qian
@ 2026-09-24 11:38 ` Weili Qian
  2026-09-24 11:38 ` [PATCH 2/4] crypto: hisilicon/qm - return error for abnormal device capability version Weili Qian
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Weili Qian @ 2026-09-24 11:38 UTC (permalink / raw)
  To: herbert; +Cc: linux-kernel, linux-crypto, liulongfang

ACPI_COMPANION() may return NULL on firmware without ACPI support.
Passing it directly to acpi_device_power_manageable() causes a NULL
pointer dereference.

Store the companion in a local variable and check it before use.
When the device is not power manageable, clear QM_SUPPORT_RPM so the
driver skips the suspend/resume path.

Fixes: 3e1d2c52b2045 ("crypto: hisilicon - check _PS0 and _PR0 method")
Signed-off-by: Weili Qian <qianweili@huawei.com>
---
 drivers/crypto/hisilicon/qm.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index c01966a4a33f..4f555912f5fc 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -3158,6 +3158,7 @@ static int hisi_qp_memory_init(struct hisi_qm *qm, size_t dma_size, int id,
 static void hisi_qm_pre_init(struct hisi_qm *qm)
 {
 	struct pci_dev *pdev = qm->pdev;
+	struct acpi_device *adev;
 
 	if (qm->ver == QM_HW_V1)
 		qm->ops = &qm_hw_ops_v1;
@@ -3173,9 +3174,16 @@ static void hisi_qm_pre_init(struct hisi_qm *qm)
 	mutex_init(&qm->ifc_lock);
 	init_rwsem(&qm->qps_lock);
 	qm->qp_in_used = 0;
+	/*
+	 * If the device is not power manageable, clear the flag to
+	 * avoid entering the suspend and resume process later.
+	 */
 	if (test_bit(QM_SUPPORT_RPM, &qm->caps)) {
-		if (!acpi_device_power_manageable(ACPI_COMPANION(&pdev->dev)))
-			dev_info(&pdev->dev, "_PS0 and _PR0 are not defined");
+		adev = ACPI_COMPANION(&pdev->dev);
+		if (!adev || !acpi_device_power_manageable(adev)) {
+			dev_warn(&pdev->dev, "device does not support runtime power gating\n");
+			clear_bit(QM_SUPPORT_RPM, &qm->caps);
+		}
 	}
 }
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 2/4] crypto: hisilicon/qm - return error for abnormal device capability version
  2026-09-24 11:38 [PATCH 0/4] crypto: hisilicon/qm - fix bugs and harden against abnormal hardware Weili Qian
  2026-09-24 11:38 ` [PATCH 1/4] crypto: hisilicon/qm - clear runtime PM flag for non-power-manageable device Weili Qian
@ 2026-09-24 11:38 ` Weili Qian
  2026-09-24 11:38 ` [PATCH 3/4] crypto: hisilicon/qm - check queue depth read from hardware Weili Qian
  2026-09-24 11:38 ` [PATCH 4/4] crypto: hisilicon/qm - fix uacce leak when SVA is not supported Weili Qian
  3 siblings, 0 replies; 6+ messages in thread
From: Weili Qian @ 2026-09-24 11:38 UTC (permalink / raw)
  To: herbert; +Cc: linux-kernel, linux-crypto, liulongfang

When the device is abnormal, QM_FUNC_CAPS_REG returns 0xffffffff and
cap_ver becomes 0xff, but the driver continues with an invalid version.

Read the register unconditionally and return -EIO when cap_ver equals
QM_CAPBILITY_VERSION, indicating an abnormal device.

Fixes: 82f00b24f532 ("crypto: hisilicon/qm - get hardware features from hardware registers")
Signed-off-by: Weili Qian <qianweili@huawei.com>
---
 drivers/crypto/hisilicon/qm.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 4f555912f5fc..bde44401ddb6 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -5770,9 +5770,19 @@ static int qm_get_hw_caps(struct hisi_qm *qm)
 	if (val)
 		set_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps);
 
-	if (qm->ver >= QM_HW_V3) {
-		val = readl(qm->io_base + QM_FUNC_CAPS_REG);
-		qm->cap_ver = val & QM_CAPBILITY_VERSION;
+	/*
+	 * Read capability version from hardware register unconditionally.
+	 * For V1/V2 hardware, this register is not implemented and returns 0
+	 * in normal condition, but returns 0xffffffff when the device is
+	 * abnormal, same as V3+ abnormal devices.
+	 * When cap_ver equals QM_CAPBILITY_VERSION (0xff), the device is
+	 * abnormal and probe should fail early.
+	 */
+	val = readl(qm->io_base + QM_FUNC_CAPS_REG);
+	qm->cap_ver = val & QM_CAPBILITY_VERSION;
+	if (qm->cap_ver == QM_CAPBILITY_VERSION) {
+		dev_err(&qm->pdev->dev, "abnormal device detected\n");
+		return -EIO;
 	}
 
 	/* Get PF/VF common capbility */
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 3/4] crypto: hisilicon/qm - check queue depth read from hardware
  2026-09-24 11:38 [PATCH 0/4] crypto: hisilicon/qm - fix bugs and harden against abnormal hardware Weili Qian
  2026-09-24 11:38 ` [PATCH 1/4] crypto: hisilicon/qm - clear runtime PM flag for non-power-manageable device Weili Qian
  2026-09-24 11:38 ` [PATCH 2/4] crypto: hisilicon/qm - return error for abnormal device capability version Weili Qian
@ 2026-09-24 11:38 ` Weili Qian
  2026-10-02  7:51   ` Herbert Xu
  2026-09-24 11:38 ` [PATCH 4/4] crypto: hisilicon/qm - fix uacce leak when SVA is not supported Weili Qian
  3 siblings, 1 reply; 6+ messages in thread
From: Weili Qian @ 2026-09-24 11:38 UTC (permalink / raw)
  To: herbert; +Cc: linux-kernel, linux-crypto, liulongfang

When hardware is abnormal, queue depth values read from registers may
be invalid, causing array out of bounds or division by zero.

Add a QM_XQC_MIN_DEPTH check in qm_get_xqc_depth() so all callers are
covered. The check only applies to QM_HW_V3 and later, where depth is
read from registers.

Fixes: 129a9f340172 ("crypto: hisilicon/qm - get qp num and depth from hardware registers")
Signed-off-by: Weili Qian <qianweili@huawei.com>
---
 drivers/crypto/hisilicon/qm.c | 34 +++++++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index bde44401ddb6..f310edfc16cf 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -77,6 +77,7 @@
 #define QM_CQ_OVERFLOW			0
 #define QM_EQ_OVERFLOW			1
 #define QM_CQE_ERROR			2
+#define QM_XQC_MIN_DEPTH		1024
 
 #define QM_XQ_DEPTH_SHIFT		16
 #define QM_XQ_DEPTH_MASK		GENMASK(15, 0)
@@ -963,14 +964,24 @@ u32 hisi_qm_get_cap_value(struct hisi_qm *qm,
 }
 EXPORT_SYMBOL_GPL(hisi_qm_get_cap_value);
 
-static void qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits,
-			     u16 *high_bits, enum qm_basic_type type)
+static int qm_get_xqc_depth(struct hisi_qm *qm, u16 *low_bits,
+			    u16 *high_bits, enum qm_basic_type type)
 {
 	u32 depth;
 
 	depth = hisi_qm_get_hw_info(qm, qm_basic_info, type, qm->cap_ver);
 	*low_bits = depth & QM_XQ_DEPTH_MASK;
 	*high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK;
+
+	if (qm->ver >= QM_HW_V3 &&
+	    (*low_bits < QM_XQC_MIN_DEPTH || *high_bits < QM_XQC_MIN_DEPTH)) {
+		dev_err(&qm->pdev->dev,
+			"invalid depth type %d, low %u, high %u, min %u\n",
+			type, *low_bits, *high_bits, QM_XQC_MIN_DEPTH);
+		return -EIO;
+	}
+
+	return 0;
 }
 
 int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs,
@@ -2940,6 +2951,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
 	unsigned long mmio_page_nr;
 	unsigned long dus_page_nr;
 	u16 sq_depth, cq_depth;
+	int ret;
 	struct uacce_interface interface = {
 		.flags = UACCE_DEV_SVA,
 		.ops = &uacce_qm_ops,
@@ -2974,7 +2986,12 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
 	else
 		mmio_page_nr = qm->db_interval / PAGE_SIZE;
 
-	qm_get_xqc_depth(qm, &sq_depth, &cq_depth, QM_QP_DEPTH_CAP);
+	ret = qm_get_xqc_depth(qm, &sq_depth, &cq_depth, QM_QP_DEPTH_CAP);
+	if (ret) {
+		uacce_remove(uacce);
+		qm->use_sva = false;
+		return ret;
+	}
 
 	/* Add one more page for device or qp status */
 	dus_page_nr = (PAGE_SIZE - 1 + qm->sqe_size * sq_depth +
@@ -6002,7 +6019,12 @@ static int hisi_qp_alloc_memory(struct hisi_qm *qm)
 		return -ENOMEM;
 	}
 
-	qm_get_xqc_depth(qm, &sq_depth, &cq_depth, QM_QP_DEPTH_CAP);
+	ret = qm_get_xqc_depth(qm, &sq_depth, &cq_depth, QM_QP_DEPTH_CAP);
+	if (ret) {
+		kfree(qm->poll_data);
+		kfree(qm->qp_array);
+		return ret;
+	}
 
 	/* one more page for device or qp statuses */
 	qp_dma_size = qm->sqe_size * sq_depth + sizeof(struct qm_cqe) * cq_depth;
@@ -6076,7 +6098,9 @@ static int hisi_qm_memory_init(struct hisi_qm *qm)
 } while (0)
 
 	idr_init(&qm->qp_idr);
-	qm_get_xqc_depth(qm, &qm->eq_depth, &qm->aeq_depth, QM_XEQ_DEPTH_CAP);
+	ret = qm_get_xqc_depth(qm, &qm->eq_depth, &qm->aeq_depth, QM_XEQ_DEPTH_CAP);
+	if (ret)
+		goto err_destroy_idr;
 	qm->qdma.size = QMC_ALIGN(sizeof(struct qm_eqe) * qm->eq_depth) +
 			QMC_ALIGN(sizeof(struct qm_aeqe) * qm->aeq_depth) +
 			QMC_ALIGN(sizeof(struct qm_sqc) * qm->qp_num) +
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 4/4] crypto: hisilicon/qm - fix uacce leak when SVA is not supported
  2026-09-24 11:38 [PATCH 0/4] crypto: hisilicon/qm - fix bugs and harden against abnormal hardware Weili Qian
                   ` (2 preceding siblings ...)
  2026-09-24 11:38 ` [PATCH 3/4] crypto: hisilicon/qm - check queue depth read from hardware Weili Qian
@ 2026-09-24 11:38 ` Weili Qian
  3 siblings, 0 replies; 6+ messages in thread
From: Weili Qian @ 2026-09-24 11:38 UTC (permalink / raw)
  To: herbert; +Cc: linux-kernel, linux-crypto, liulongfang

In qm_alloc_uacce(), when SVA is not supported, the error path calls
qm_remove_uacce(qm). But qm->uacce is not yet assigned and qm->use_sva
is still false, so qm_remove_uacce() returns without releasing the
uacce device, causing a memory leak.

Call uacce_remove(uacce) on the local variable instead.

Fixes: cd0ac51c5760 ("crypto: hisilicon/qm - define the device isolation strategy")
Signed-off-by: Weili Qian <qianweili@huawei.com>
---
 drivers/crypto/hisilicon/qm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index f310edfc16cf..096f0b40b82a 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -2968,7 +2968,7 @@ static int qm_alloc_uacce(struct hisi_qm *qm)
 		qm->use_sva = true;
 	} else {
 		/* only consider sva case */
-		qm_remove_uacce(qm);
+		uacce_remove(uacce);
 		return -EINVAL;
 	}
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 3/4] crypto: hisilicon/qm - check queue depth read from hardware
  2026-09-24 11:38 ` [PATCH 3/4] crypto: hisilicon/qm - check queue depth read from hardware Weili Qian
@ 2026-10-02  7:51   ` Herbert Xu
  0 siblings, 0 replies; 6+ messages in thread
From: Herbert Xu @ 2026-10-02  7:51 UTC (permalink / raw)
  To: Weili Qian; +Cc: linux-kernel, linux-crypto, liulongfang

On Thu, Sep 24, 2026 at 07:38:11PM +0800, Weili Qian wrote:
> When hardware is abnormal, queue depth values read from registers may
> be invalid, causing array out of bounds or division by zero.
> 
> Add a QM_XQC_MIN_DEPTH check in qm_get_xqc_depth() so all callers are
> covered. The check only applies to QM_HW_V3 and later, where depth is
> read from registers.
> 
> Fixes: 129a9f340172 ("crypto: hisilicon/qm - get qp num and depth from hardware registers")
> Signed-off-by: Weili Qian <qianweili@huawei.com>
> ---
>  drivers/crypto/hisilicon/qm.c | 34 +++++++++++++++++++++++++++++-----
>  1 file changed, 29 insertions(+), 5 deletions(-)

Please check

https://sashiko.dev/#/patchset/20260924113812.1110302-1-qianweili%40huawei.com

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-10-02  7:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-24 11:38 [PATCH 0/4] crypto: hisilicon/qm - fix bugs and harden against abnormal hardware Weili Qian
2026-09-24 11:38 ` [PATCH 1/4] crypto: hisilicon/qm - clear runtime PM flag for non-power-manageable device Weili Qian
2026-09-24 11:38 ` [PATCH 2/4] crypto: hisilicon/qm - return error for abnormal device capability version Weili Qian
2026-09-24 11:38 ` [PATCH 3/4] crypto: hisilicon/qm - check queue depth read from hardware Weili Qian
2026-10-02  7:51   ` Herbert Xu
2026-09-24 11:38 ` [PATCH 4/4] crypto: hisilicon/qm - fix uacce leak when SVA is not supported Weili Qian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®