From: Yi Liu <yi.l....@intel.com>

Also add a comment to mark that vfio core releases device_set if @init
fails.

Signed-off-by: Yi Liu <yi.l....@intel.com>
Signed-off-by: Kevin Tian <kevin.t...@intel.com>
Reviewed-by: Jason Gunthorpe <j...@nvidia.com>
---
 drivers/vfio/fsl-mc/vfio_fsl_mc.c | 85 ++++++++++++++++++-------------
 1 file changed, 49 insertions(+), 36 deletions(-)

diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c 
b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
index 42b344bd7cd5..b16874e913e4 100644
--- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c
+++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c
@@ -418,16 +418,7 @@ static int vfio_fsl_mc_mmap(struct vfio_device *core_vdev,
        return vfio_fsl_mc_mmap_mmio(vdev->regions[index], vma);
 }
 
-static const struct vfio_device_ops vfio_fsl_mc_ops = {
-       .name           = "vfio-fsl-mc",
-       .open_device    = vfio_fsl_mc_open_device,
-       .close_device   = vfio_fsl_mc_close_device,
-       .ioctl          = vfio_fsl_mc_ioctl,
-       .read           = vfio_fsl_mc_read,
-       .write          = vfio_fsl_mc_write,
-       .mmap           = vfio_fsl_mc_mmap,
-};
-
+static const struct vfio_device_ops vfio_fsl_mc_ops;
 static int vfio_fsl_mc_bus_notifier(struct notifier_block *nb,
                                    unsigned long action, void *data)
 {
@@ -518,35 +509,43 @@ static void vfio_fsl_uninit_device(struct 
vfio_fsl_mc_device *vdev)
        bus_unregister_notifier(&fsl_mc_bus_type, &vdev->nb);
 }
 
-static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
+static int vfio_fsl_mc_init_dev(struct vfio_device *core_vdev)
 {
-       struct vfio_fsl_mc_device *vdev;
-       struct device *dev = &mc_dev->dev;
+       struct vfio_fsl_mc_device *vdev =
+               container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
+       struct fsl_mc_device *mc_dev = to_fsl_mc_device(core_vdev->dev);
        int ret;
 
-       vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
-       if (!vdev)
-               return -ENOMEM;
-
-       vfio_init_group_dev(&vdev->vdev, dev, &vfio_fsl_mc_ops);
        vdev->mc_dev = mc_dev;
        mutex_init(&vdev->igate);
 
        if (is_fsl_mc_bus_dprc(mc_dev))
-               ret = vfio_assign_device_set(&vdev->vdev, &mc_dev->dev);
+               ret = vfio_assign_device_set(core_vdev, &mc_dev->dev);
        else
-               ret = vfio_assign_device_set(&vdev->vdev, mc_dev->dev.parent);
-       if (ret)
-               goto out_uninit;
+               ret = vfio_assign_device_set(core_vdev, mc_dev->dev.parent);
 
-       ret = vfio_fsl_mc_init_device(vdev);
        if (ret)
-               goto out_uninit;
+               return ret;
+
+       /* device_set is released by vfio core if @init fails */
+       return vfio_fsl_mc_init_device(vdev);
+}
+
+static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
+{
+       struct vfio_fsl_mc_device *vdev;
+       struct device *dev = &mc_dev->dev;
+       int ret;
+
+       vdev = vfio_alloc_device(vfio_fsl_mc_device, vdev, dev,
+                                &vfio_fsl_mc_ops);
+       if (IS_ERR(vdev))
+               return PTR_ERR(vdev);
 
        ret = vfio_register_group_dev(&vdev->vdev);
        if (ret) {
                dev_err(dev, "VFIO_FSL_MC: Failed to add to vfio group\n");
-               goto out_device;
+               goto out_put_vdev;
        }
 
        ret = vfio_fsl_mc_scan_container(mc_dev);
@@ -557,30 +556,44 @@ static int vfio_fsl_mc_probe(struct fsl_mc_device *mc_dev)
 
 out_group_dev:
        vfio_unregister_group_dev(&vdev->vdev);
-out_device:
-       vfio_fsl_uninit_device(vdev);
-out_uninit:
-       vfio_uninit_group_dev(&vdev->vdev);
-       kfree(vdev);
+out_put_vdev:
+       vfio_put_device(&vdev->vdev);
        return ret;
 }
 
+static void vfio_fsl_mc_release_dev(struct vfio_device *core_vdev)
+{
+       struct vfio_fsl_mc_device *vdev =
+               container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
+
+       vfio_fsl_uninit_device(vdev);
+       mutex_destroy(&vdev->igate);
+       vfio_free_device(core_vdev);
+}
+
 static int vfio_fsl_mc_remove(struct fsl_mc_device *mc_dev)
 {
        struct device *dev = &mc_dev->dev;
        struct vfio_fsl_mc_device *vdev = dev_get_drvdata(dev);
 
        vfio_unregister_group_dev(&vdev->vdev);
-       mutex_destroy(&vdev->igate);
-
        dprc_remove_devices(mc_dev, NULL, 0);
-       vfio_fsl_uninit_device(vdev);
-
-       vfio_uninit_group_dev(&vdev->vdev);
-       kfree(vdev);
+       vfio_put_device(&vdev->vdev);
        return 0;
 }
 
+static const struct vfio_device_ops vfio_fsl_mc_ops = {
+       .name           = "vfio-fsl-mc",
+       .init           = vfio_fsl_mc_init_dev,
+       .release        = vfio_fsl_mc_release_dev,
+       .open_device    = vfio_fsl_mc_open_device,
+       .close_device   = vfio_fsl_mc_close_device,
+       .ioctl          = vfio_fsl_mc_ioctl,
+       .read           = vfio_fsl_mc_read,
+       .write          = vfio_fsl_mc_write,
+       .mmap           = vfio_fsl_mc_mmap,
+};
+
 static struct fsl_mc_driver vfio_fsl_mc_driver = {
        .probe          = vfio_fsl_mc_probe,
        .remove         = vfio_fsl_mc_remove,
-- 
2.21.3

Reply via email to