vfio/pci: Have all VFIO PCI drivers store the vfio_pci_core_device in drvdata
authorJason Gunthorpe <jgg@nvidia.com>
Wed, 11 May 2022 19:19:07 +0000 (13:19 -0600)
committerAlex Williamson <alex.williamson@redhat.com>
Wed, 11 May 2022 19:32:56 +0000 (13:32 -0600)
Having a consistent pointer in the drvdata will allow the next patch to
make use of the drvdata from some of the core code helpers.

Use a WARN_ON inside vfio_pci_core_register_device() to detect drivers
that miss this.

Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/1-v4-c841817a0349+8f-vfio_get_from_dev_jgg@nvidia.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
drivers/vfio/pci/mlx5/main.c
drivers/vfio/pci/vfio_pci.c
drivers/vfio/pci/vfio_pci_core.c

index 767b5d47631a49e4dd90b023276836cacab57340..e92376837b29e606edf6bfe43b21c70f576f94ae 100644 (file)
@@ -337,6 +337,14 @@ static int vf_qm_cache_wb(struct hisi_qm *qm)
        return 0;
 }
 
+static struct hisi_acc_vf_core_device *hssi_acc_drvdata(struct pci_dev *pdev)
+{
+       struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
+
+       return container_of(core_device, struct hisi_acc_vf_core_device,
+                           core_device);
+}
+
 static void vf_qm_fun_reset(struct hisi_acc_vf_core_device *hisi_acc_vdev,
                            struct hisi_qm *qm)
 {
@@ -962,7 +970,7 @@ hisi_acc_vfio_pci_get_device_state(struct vfio_device *vdev,
 
 static void hisi_acc_vf_pci_aer_reset_done(struct pci_dev *pdev)
 {
-       struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev);
+       struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev);
 
        if (hisi_acc_vdev->core_device.vdev.migration_flags !=
                                VFIO_MIGRATION_STOP_COPY)
@@ -1274,11 +1282,10 @@ static int hisi_acc_vfio_pci_probe(struct pci_dev *pdev, const struct pci_device
                                          &hisi_acc_vfio_pci_ops);
        }
 
+       dev_set_drvdata(&pdev->dev, &hisi_acc_vdev->core_device);
        ret = vfio_pci_core_register_device(&hisi_acc_vdev->core_device);
        if (ret)
                goto out_free;
-
-       dev_set_drvdata(&pdev->dev, hisi_acc_vdev);
        return 0;
 
 out_free:
@@ -1289,7 +1296,7 @@ out_free:
 
 static void hisi_acc_vfio_pci_remove(struct pci_dev *pdev)
 {
-       struct hisi_acc_vf_core_device *hisi_acc_vdev = dev_get_drvdata(&pdev->dev);
+       struct hisi_acc_vf_core_device *hisi_acc_vdev = hssi_acc_drvdata(pdev);
 
        vfio_pci_core_unregister_device(&hisi_acc_vdev->core_device);
        vfio_pci_core_uninit_device(&hisi_acc_vdev->core_device);
index df8b572977da73125e910e8d3668610fd00c5fba..dd1009b5ff9c825ff74a4849abfe218123c13f7f 100644 (file)
 /* Arbitrary to prevent userspace from consuming endless memory */
 #define MAX_MIGRATION_SIZE (512*1024*1024)
 
+static struct mlx5vf_pci_core_device *mlx5vf_drvdata(struct pci_dev *pdev)
+{
+       struct vfio_pci_core_device *core_device = dev_get_drvdata(&pdev->dev);
+
+       return container_of(core_device, struct mlx5vf_pci_core_device,
+                           core_device);
+}
+
 static struct page *
 mlx5vf_get_migration_page(struct mlx5_vf_migration_file *migf,
                          unsigned long offset)
@@ -518,7 +526,7 @@ static int mlx5vf_pci_get_device_state(struct vfio_device *vdev,
 
 static void mlx5vf_pci_aer_reset_done(struct pci_dev *pdev)
 {
-       struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev);
+       struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev);
 
        if (!mvdev->migrate_cap)
                return;
@@ -592,11 +600,10 @@ static int mlx5vf_pci_probe(struct pci_dev *pdev,
                return -ENOMEM;
        vfio_pci_core_init_device(&mvdev->core_device, pdev, &mlx5vf_pci_ops);
        mlx5vf_cmd_set_migratable(mvdev);
+       dev_set_drvdata(&pdev->dev, &mvdev->core_device);
        ret = vfio_pci_core_register_device(&mvdev->core_device);
        if (ret)
                goto out_free;
-
-       dev_set_drvdata(&pdev->dev, mvdev);
        return 0;
 
 out_free:
@@ -608,7 +615,7 @@ out_free:
 
 static void mlx5vf_pci_remove(struct pci_dev *pdev)
 {
-       struct mlx5vf_pci_core_device *mvdev = dev_get_drvdata(&pdev->dev);
+       struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev);
 
        vfio_pci_core_unregister_device(&mvdev->core_device);
        mlx5vf_cmd_remove_migratable(mvdev);
index 2b047469e02feea48b0bbea808fd119d1eeefcfe..8c990a1a7def9e8a131040137ad0cd2cb983354f 100644 (file)
@@ -151,10 +151,10 @@ static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
                return -ENOMEM;
        vfio_pci_core_init_device(vdev, pdev, &vfio_pci_ops);
 
+       dev_set_drvdata(&pdev->dev, vdev);
        ret = vfio_pci_core_register_device(vdev);
        if (ret)
                goto out_free;
-       dev_set_drvdata(&pdev->dev, vdev);
        return 0;
 
 out_free:
index 06b6f3594a1316e020dc294a8ac102d009504e31..65587fd5c021bb090991704a42456b0ce0c5dd67 100644 (file)
@@ -1821,6 +1821,10 @@ int vfio_pci_core_register_device(struct vfio_pci_core_device *vdev)
        struct pci_dev *pdev = vdev->pdev;
        int ret;
 
+       /* Drivers must set the vfio_pci_core_device to their drvdata */
+       if (WARN_ON(vdev != dev_get_drvdata(&vdev->pdev->dev)))
+               return -EINVAL;
+
        if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
                return -EINVAL;