--- /dev/null
+From b04f06fc0243600665b3b50253869533b7938468 Mon Sep 17 00:00:00 2001
+From: Weili Qian <qianweili@huawei.com>
+Date: Sat, 31 Aug 2024 19:48:31 +0800
+Subject: crypto: hisilicon/qm - inject error before stopping queue
+
+From: Weili Qian <qianweili@huawei.com>
+
+commit b04f06fc0243600665b3b50253869533b7938468 upstream.
+
+The master ooo cannot be completely closed when the
+accelerator core reports memory error. Therefore, the driver
+needs to inject the qm error to close the master ooo. Currently,
+the qm error is injected after stopping queue, memory may be
+released immediately after stopping queue, causing the device to
+access the released memory. Therefore, error is injected to close master
+ooo before stopping queue to ensure that the device does not access
+the released memory.
+
+Fixes: 6c6dd5802c2d ("crypto: hisilicon/qm - add controller reset interface")
+Signed-off-by: Weili Qian <qianweili@huawei.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
+Signed-off-by: He Zhe <zhe.he@windriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/hisilicon/qm.c | 46 +++++++++++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 23 deletions(-)
+
+--- a/drivers/crypto/hisilicon/qm.c
++++ b/drivers/crypto/hisilicon/qm.c
+@@ -3354,6 +3354,27 @@ static int qm_set_vf_mse(struct hisi_qm
+ return -ETIMEDOUT;
+ }
+
++static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
++{
++ u32 nfe_enb = 0;
++
++ if (!qm->err_status.is_dev_ecc_mbit &&
++ qm->err_status.is_qm_ecc_mbit &&
++ qm->err_ini->close_axi_master_ooo) {
++
++ qm->err_ini->close_axi_master_ooo(qm);
++
++ } else if (qm->err_status.is_dev_ecc_mbit &&
++ !qm->err_status.is_qm_ecc_mbit &&
++ !qm->err_ini->close_axi_master_ooo) {
++
++ nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
++ writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
++ qm->io_base + QM_RAS_NFE_ENABLE);
++ writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
++ }
++}
++
+ static int qm_set_msi(struct hisi_qm *qm, bool set)
+ {
+ struct pci_dev *pdev = qm->pdev;
+@@ -3433,6 +3454,8 @@ static int qm_controller_reset_prepare(s
+ return ret;
+ }
+
++ qm_dev_ecc_mbit_handle(qm);
++
+ if (qm->vfs_num) {
+ ret = qm_vf_reset_prepare(qm, QM_SOFT_RESET);
+ if (ret) {
+@@ -3450,27 +3473,6 @@ static int qm_controller_reset_prepare(s
+ return 0;
+ }
+
+-static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
+-{
+- u32 nfe_enb = 0;
+-
+- if (!qm->err_status.is_dev_ecc_mbit &&
+- qm->err_status.is_qm_ecc_mbit &&
+- qm->err_ini->close_axi_master_ooo) {
+-
+- qm->err_ini->close_axi_master_ooo(qm);
+-
+- } else if (qm->err_status.is_dev_ecc_mbit &&
+- !qm->err_status.is_qm_ecc_mbit &&
+- !qm->err_ini->close_axi_master_ooo) {
+-
+- nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
+- writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
+- qm->io_base + QM_RAS_NFE_ENABLE);
+- writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
+- }
+-}
+-
+ static int qm_soft_reset(struct hisi_qm *qm)
+ {
+ struct pci_dev *pdev = qm->pdev;
+@@ -3496,8 +3498,6 @@ static int qm_soft_reset(struct hisi_qm
+ return ret;
+ }
+
+- qm_dev_ecc_mbit_handle(qm);
+-
+ /* OOO register set and check */
+ writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
+ qm->io_base + ACC_MASTER_GLOBAL_CTRL);