[v9,3/3] crypto: hisilicon/qm - add the device isolation feature for acc

Message ID 20221025123931.42161-4-yekai13@huawei.com
State New
Headers
Series crypto: hisilicon - supports device isolation feature |

Commit Message

yekai (A) Oct. 25, 2022, 12:39 p.m. UTC
  Record every AER error by uacce api. And isolate the device directly
when the controller reset fail. The VF device use the PF device
isolation strategy. Once the PF device is isolated, its VF device will
also be isolated.

Signed-off-by: Kai Ye <yekai13@huawei.com>
---
 drivers/crypto/hisilicon/qm.c | 66 ++++++++++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 9 deletions(-)
  

Patch

diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
index 363a02810a16..aa953ce86f70 100644
--- a/drivers/crypto/hisilicon/qm.c
+++ b/drivers/crypto/hisilicon/qm.c
@@ -3397,6 +3397,29 @@  static void qm_set_sqctype(struct uacce_queue *q, u16 type)
 	up_write(&qm->qps_lock);
 }
 
+static int qm_uacce_isolate_init(struct hisi_qm *qm)
+{
+	struct pci_dev *pdev = qm->pdev;
+	struct uacce_device *pf_uacce, *uacce;
+	struct device *pf_dev = &(pci_physfn(pdev)->dev);
+
+	uacce = qm->uacce;
+	if (uacce->is_vf) {
+		/* VF uses PF's isoalte data */
+		pf_uacce = dev_to_uacce(pf_dev);
+		if (!pf_uacce) {
+			pci_err(pdev, "fail to PF device!\n");
+			return -ENODEV;
+		}
+
+		uacce->isolate_ctx = &pf_uacce->isolate_data;
+	} else {
+		uacce->isolate_ctx = &uacce->isolate_data;
+	}
+
+	return 0;
+}
+
 static long hisi_qm_uacce_ioctl(struct uacce_queue *q, unsigned int cmd,
 				unsigned long arg)
 {
@@ -3450,6 +3473,14 @@  static const struct uacce_ops uacce_qm_ops = {
 	.is_q_updated = hisi_qm_is_q_updated,
 };
 
+static void qm_remove_uacce(struct hisi_qm *qm)
+{
+	if (qm->use_sva) {
+		uacce_remove(qm->uacce);
+		qm->uacce = NULL;
+	}
+}
+
 static int qm_alloc_uacce(struct hisi_qm *qm)
 {
 	struct pci_dev *pdev = qm->pdev;
@@ -3511,7 +3542,14 @@  static int qm_alloc_uacce(struct hisi_qm *qm)
 
 	qm->uacce = uacce;
 
+	ret = qm_uacce_isolate_init(qm);
+	if (ret)
+		goto err_rm_uacce;
+
 	return 0;
+err_rm_uacce:
+	qm_remove_uacce(qm);
+	return ret;
 }
 
 /**
@@ -5133,6 +5171,12 @@  static int qm_controller_reset_prepare(struct hisi_qm *qm)
 		return ret;
 	}
 
+	if (qm->use_sva) {
+		ret = uacce_hw_err_isolate(qm->uacce);
+		if (ret)
+			pci_err(pdev, "failed to isolate hw err!\n");
+	}
+
 	ret = qm_wait_vf_prepare_finish(qm);
 	if (ret)
 		pci_err(pdev, "failed to stop by vfs in soft reset!\n");
@@ -5458,21 +5502,25 @@  static int qm_controller_reset(struct hisi_qm *qm)
 		qm->err_ini->show_last_dfx_regs(qm);
 
 	ret = qm_soft_reset(qm);
-	if (ret) {
-		pci_err(pdev, "Controller reset failed (%d)\n", ret);
-		qm_reset_bit_clear(qm);
-		return ret;
-	}
+	if (ret)
+		goto err_reset;
 
 	ret = qm_controller_reset_done(qm);
-	if (ret) {
-		qm_reset_bit_clear(qm);
-		return ret;
-	}
+	if (ret)
+		goto err_reset;
 
 	pci_info(pdev, "Controller reset complete\n");
 
 	return 0;
+err_reset:
+	pci_info(pdev, "Controller reset failed (%d)\n", ret);
+	qm_reset_bit_clear(qm);
+
+	/* if resetting fails, isolate the device */
+	if (qm->use_sva && !qm->uacce->is_vf)
+		qm->uacce->isolate_ctx->is_isolate = true;
+
+	return ret;
 }
 
 /**