.log_read_and_clear = mlx5vf_tracker_read_and_clear,
 };
 
+static int mlx5vf_pci_init_dev(struct vfio_device *core_vdev)
+{
+       struct mlx5vf_pci_core_device *mvdev = container_of(core_vdev,
+                       struct mlx5vf_pci_core_device, core_device.vdev);
+       int ret;
+
+       ret = vfio_pci_core_init_dev(core_vdev);
+       if (ret)
+               return ret;
+
+       mlx5vf_cmd_set_migratable(mvdev, &mlx5vf_pci_mig_ops,
+                                 &mlx5vf_pci_log_ops);
+
+       return 0;
+}
+
+static void mlx5vf_pci_release_dev(struct vfio_device *core_vdev)
+{
+       struct mlx5vf_pci_core_device *mvdev = container_of(core_vdev,
+                       struct mlx5vf_pci_core_device, core_device.vdev);
+
+       mlx5vf_cmd_remove_migratable(mvdev);
+       vfio_pci_core_release_dev(core_vdev);
+}
+
 static const struct vfio_device_ops mlx5vf_pci_ops = {
        .name = "mlx5-vfio-pci",
+       .init = mlx5vf_pci_init_dev,
+       .release = mlx5vf_pci_release_dev,
        .open_device = mlx5vf_pci_open_device,
        .close_device = mlx5vf_pci_close_device,
        .ioctl = vfio_pci_core_ioctl,
        struct mlx5vf_pci_core_device *mvdev;
        int ret;
 
-       mvdev = kzalloc(sizeof(*mvdev), GFP_KERNEL);
-       if (!mvdev)
-               return -ENOMEM;
-       vfio_pci_core_init_device(&mvdev->core_device, pdev, &mlx5vf_pci_ops);
-       mlx5vf_cmd_set_migratable(mvdev, &mlx5vf_pci_mig_ops,
-                                 &mlx5vf_pci_log_ops);
+       mvdev = vfio_alloc_device(mlx5vf_pci_core_device, core_device.vdev,
+                                 &pdev->dev, &mlx5vf_pci_ops);
+       if (IS_ERR(mvdev))
+               return PTR_ERR(mvdev);
+
        dev_set_drvdata(&pdev->dev, &mvdev->core_device);
        ret = vfio_pci_core_register_device(&mvdev->core_device);
        if (ret)
-               goto out_free;
+               goto out_put_vdev;
        return 0;
 
-out_free:
-       mlx5vf_cmd_remove_migratable(mvdev);
-       vfio_pci_core_uninit_device(&mvdev->core_device);
-       kfree(mvdev);
+out_put_vdev:
+       vfio_put_device(&mvdev->core_device.vdev);
        return ret;
 }
 
        struct mlx5vf_pci_core_device *mvdev = mlx5vf_drvdata(pdev);
 
        vfio_pci_core_unregister_device(&mvdev->core_device);
-       mlx5vf_cmd_remove_migratable(mvdev);
-       vfio_pci_core_uninit_device(&mvdev->core_device);
-       kfree(mvdev);
+       vfio_put_device(&mvdev->core_device.vdev);
 }
 
 static const struct pci_device_id mlx5vf_pci_table[] = {