]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
hisi_acc_vfio_pci: bugfix live migration function without VF device driver
authorLongfang Liu <liulongfang@huawei.com>
Sat, 10 May 2025 08:11:54 +0000 (16:11 +0800)
committerAlex Williamson <alex.williamson@redhat.com>
Mon, 19 May 2025 18:41:31 +0000 (12:41 -0600)
If the VF device driver is not loaded in the Guest OS and we attempt to
perform device data migration, the address of the migrated data will
be NULL.
The live migration recovery operation on the destination side will
access a null address value, which will cause access errors.

Therefore, live migration of VMs without added VF device drivers
does not require device data migration.
In addition, when the queue address data obtained by the destination
is empty, device queue recovery processing will not be performed.

Fixes: b0eed085903e ("hisi_acc_vfio_pci: Add support for VFIO live migration")
Signed-off-by: Longfang Liu <liulongfang@huawei.com>
Reviewed-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Link: https://lore.kernel.org/r/20250510081155.55840-6-liulongfang@huawei.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c

index cadc82419dca298d281fb429cd6c5bd2fba185a3..d12a350440d3ca9dc61f0435a0f055ce891ca7e1 100644 (file)
@@ -426,13 +426,6 @@ static int vf_qm_check_match(struct hisi_acc_vf_core_device *hisi_acc_vdev,
                return -EINVAL;
        }
 
-       ret = qm_write_regs(vf_qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
-       if (ret) {
-               dev_err(dev, "failed to write QM_VF_STATE\n");
-               return ret;
-       }
-
-       hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
        hisi_acc_vdev->match_done = true;
        return 0;
 }
@@ -498,6 +491,20 @@ static int vf_qm_load_data(struct hisi_acc_vf_core_device *hisi_acc_vdev,
        if (migf->total_length < sizeof(struct acc_vf_data))
                return -EINVAL;
 
+       if (!vf_data->eqe_dma || !vf_data->aeqe_dma ||
+           !vf_data->sqc_dma || !vf_data->cqc_dma) {
+               dev_info(dev, "resume dma addr is NULL!\n");
+               hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
+               return 0;
+       }
+
+       ret = qm_write_regs(qm, QM_VF_STATE, &vf_data->vf_qm_state, 1);
+       if (ret) {
+               dev_err(dev, "failed to write QM_VF_STATE\n");
+               return -EINVAL;
+       }
+       hisi_acc_vdev->vf_qm_state = vf_data->vf_qm_state;
+
        qm->eqe_dma = vf_data->eqe_dma;
        qm->aeqe_dma = vf_data->aeqe_dma;
        qm->sqc_dma = vf_data->sqc_dma;
@@ -1531,6 +1538,7 @@ static int hisi_acc_vfio_pci_migrn_init_dev(struct vfio_device *core_vdev)
        hisi_acc_vdev->vf_id = pci_iov_vf_id(pdev) + 1;
        hisi_acc_vdev->pf_qm = pf_qm;
        hisi_acc_vdev->vf_dev = pdev;
+       hisi_acc_vdev->vf_qm_state = QM_NOT_READY;
        mutex_init(&hisi_acc_vdev->state_mutex);
        mutex_init(&hisi_acc_vdev->open_mutex);