* [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®