driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9CB6L CVE: NA
----------------------------------------------------------------------
If there is a hardware error when driver and device bind/unbind, resetting the device may cause the reset thread to access released memory. Therefore, reset is not performed in this scenario. When the driver is re-bound to the device, the driver will reset the device.
Signed-off-by: Weili Qian qianweili@huawei.com Signed-off-by: JiangShui Yang yangjiangshui@h-partners.com --- drivers/crypto/hisilicon/hpre/hpre_main.c | 5 +++++ drivers/crypto/hisilicon/qm.c | 17 ++++++++++------- drivers/crypto/hisilicon/sec2/sec_main.c | 5 +++++ drivers/crypto/hisilicon/zip/zip_main.c | 6 +++++- include/linux/hisi_acc_qm.h | 2 +- 5 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index 16fa09aba2d1..27ae8d10ad9d 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -1408,6 +1408,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM;
qm = &hpre->qm; + set_bit(QM_DRIVER_DOWN, &qm->misc_ctl); ret = hpre_qm_init(qm, pdev); if (ret) { pci_err(pdev, "Failed to init HPRE QM (%d)!\n", ret); @@ -1424,6 +1425,9 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto err_with_err_init;
+ /* Device is enabled, clear the flag. */ + clear_bit(QM_DRIVER_DOWN, &qm->misc_ctl); + ret = hpre_debugfs_init(qm); if (ret) dev_warn(&pdev->dev, "init debugfs fail!\n"); @@ -1458,6 +1462,7 @@ static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
err_qm_del_list: hisi_qm_del_list(qm, &hpre_devices); + hisi_qm_wait_task_finish(qm, &hpre_devices); hpre_debugfs_exit(qm); hisi_qm_stop(qm, QM_NORMAL);
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index a53c5b031c2b..6be0506ac419 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -1070,7 +1070,7 @@ static irqreturn_t qm_mb_cmd_irq(int irq, void *data) if (!val) return IRQ_NONE;
- if (test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl)) { + if (test_bit(QM_DRIVER_DOWN, &qm->misc_ctl)) { dev_warn(&qm->pdev->dev, "Driver is down, message cannot be processed!\n"); return IRQ_HANDLED; } @@ -2784,7 +2784,7 @@ EXPORT_SYMBOL_GPL(qm_register_uacce); */ static int qm_frozen(struct hisi_qm *qm) { - if (test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl)) + if (test_bit(QM_DRIVER_DOWN, &qm->misc_ctl)) return 0;
down_write(&qm->qps_lock); @@ -2792,7 +2792,7 @@ static int qm_frozen(struct hisi_qm *qm) if (!qm->qp_in_used) { qm->qp_in_used = qm->qp_num; up_write(&qm->qps_lock); - set_bit(QM_DRIVER_REMOVING, &qm->misc_ctl); + set_bit(QM_DRIVER_DOWN, &qm->misc_ctl); return 0; }
@@ -4751,10 +4751,13 @@ static irqreturn_t qm_abnormal_irq(int irq, void *data)
atomic64_inc(&qm->debug.dfx.abnormal_irq_cnt); ret = qm_process_dev_error(qm); - if (ret == ACC_ERR_NEED_RESET && - !test_bit(QM_DRIVER_REMOVING, &qm->misc_ctl) && - !test_and_set_bit(QM_RST_SCHED, &qm->misc_ctl)) - schedule_work(&qm->rst_work); + if (ret == ACC_ERR_NEED_RESET) { + if (!test_bit(QM_DRIVER_DOWN, &qm->misc_ctl) && + !test_and_set_bit(QM_RST_SCHED, &qm->misc_ctl)) + schedule_work(&qm->rst_work); + else if (test_bit(QM_DRIVER_DOWN, &qm->misc_ctl)) + pci_warn(qm->pdev, "Driver is down, need reload driver!\n"); + }
return IRQ_HANDLED; } diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 566581039c87..43f9bd0b6dbd 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -1218,6 +1218,7 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM;
qm = &sec->qm; + set_bit(QM_DRIVER_DOWN, &qm->misc_ctl); ret = sec_qm_init(qm, pdev); if (ret) { pci_err(pdev, "Failed to init SEC QM (%d)!\n", ret); @@ -1238,6 +1239,9 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_probe_uninit; }
+ /* Device is enabled, clear the flag. */ + clear_bit(QM_DRIVER_DOWN, &qm->misc_ctl); + ret = sec_debugfs_init(qm); if (ret) pci_warn(pdev, "Failed to init debugfs!\n"); @@ -1269,6 +1273,7 @@ static int sec_probe(struct pci_dev *pdev, const struct pci_device_id *id) hisi_qm_alg_unregister(qm, &sec_devices, ctx_q_num); err_qm_del_list: hisi_qm_del_list(qm, &sec_devices); + hisi_qm_wait_task_finish(qm, &sec_devices); sec_debugfs_exit(qm); hisi_qm_stop(qm, QM_NORMAL); err_probe_uninit: diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 59f7b9fdb816..6e9dbfc059a8 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c @@ -1312,7 +1312,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM;
qm = &hisi_zip->qm; - + set_bit(QM_DRIVER_DOWN, &qm->misc_ctl); ret = hisi_zip_qm_init(qm, pdev); if (ret) { pci_err(pdev, "Failed to init ZIP QM (%d)!\n", ret); @@ -1329,6 +1329,9 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto err_dev_err_uninit;
+ /* Device is enabled, clear the flag. */ + clear_bit(QM_DRIVER_DOWN, &qm->misc_ctl); + ret = hisi_zip_debugfs_init(qm); if (ret) pci_err(pdev, "failed to init debugfs (%d)!\n", ret); @@ -1360,6 +1363,7 @@ static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id) hisi_qm_alg_unregister(qm, &zip_devices, HZIP_CTX_Q_NUM_DEF);
err_qm_del_list: + hisi_qm_wait_task_finish(qm, &zip_devices); hisi_qm_del_list(qm, &zip_devices); hisi_zip_debugfs_exit(qm); hisi_qm_stop(qm, QM_NORMAL); diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h index 7116932e83c0..c7ce373ec09a 100644 --- a/include/linux/hisi_acc_qm.h +++ b/include/linux/hisi_acc_qm.h @@ -142,7 +142,7 @@ enum qm_vf_state { };
enum qm_misc_ctl_bits { - QM_DRIVER_REMOVING = 0x0, + QM_DRIVER_DOWN = 0x0, QM_RST_SCHED, QM_RESETTING, QM_MODULE_PARAM,