Commit dd4603cb authored by Weili Qian's avatar Weili Qian Committed by JangShui Yang
Browse files

crypto: hisilicon/qm - hardware error does not reset during binding/unbinding

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: default avatarWeili Qian <qianweili@huawei.com>
Signed-off-by: default avatarJiangShui Yang <yangjiangshui@h-partners.com>
parent 96db7c15
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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);

+10 −7
Original line number Diff line number Diff line
@@ -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) &&
	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;
}
+5 −0
Original line number Diff line number Diff line
@@ -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:
+5 −1
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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,