[v9,3/3] crypto: hisilicon/qm - add the device isolation feature for acc
Commit Message
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(-)
@@ -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;
}
/**