vfio: Remove iommu group notifier
authorLu Baolu <baolu.lu@linux.intel.com>
Mon, 18 Apr 2022 00:49:59 +0000 (08:49 +0800)
committerJoerg Roedel <jroedel@suse.de>
Thu, 28 Apr 2022 13:32:20 +0000 (15:32 +0200)
The iommu core and driver core have been enhanced to avoid unsafe driver
binding to a live group after iommu_group_set_dma_owner(PRIVATE_USER)
has been called. There's no need to register iommu group notifier. This
removes the iommu group notifer which contains BUG_ON() and WARN().

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Link: https://lore.kernel.org/r/20220418005000.897664-11-baolu.lu@linux.intel.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
drivers/vfio/vfio.c

index b2f19d1..0c76638 100644 (file)
@@ -71,7 +71,6 @@ struct vfio_group {
        struct vfio_container           *container;
        struct list_head                device_list;
        struct mutex                    device_lock;
-       struct notifier_block           nb;
        struct list_head                vfio_next;
        struct list_head                container_next;
        atomic_t                        opened;
@@ -274,8 +273,6 @@ void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops)
 }
 EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver);
 
-static int vfio_iommu_group_notifier(struct notifier_block *nb,
-                                    unsigned long action, void *data);
 static void vfio_group_get(struct vfio_group *group);
 
 /*
@@ -395,13 +392,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
                goto err_put;
        }
 
-       group->nb.notifier_call = vfio_iommu_group_notifier;
-       err = iommu_group_register_notifier(iommu_group, &group->nb);
-       if (err) {
-               ret = ERR_PTR(err);
-               goto err_put;
-       }
-
        mutex_lock(&vfio.group_lock);
 
        /* Did we race creating this group? */
@@ -422,7 +412,6 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group,
 
 err_unlock:
        mutex_unlock(&vfio.group_lock);
-       iommu_group_unregister_notifier(group->iommu_group, &group->nb);
 err_put:
        put_device(&group->dev);
        return ret;
@@ -447,7 +436,6 @@ static void vfio_group_put(struct vfio_group *group)
        cdev_device_del(&group->cdev, &group->dev);
        mutex_unlock(&vfio.group_lock);
 
-       iommu_group_unregister_notifier(group->iommu_group, &group->nb);
        put_device(&group->dev);
 }
 
@@ -504,141 +492,6 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
 }
 
 /*
- * Some drivers, like pci-stub, are only used to prevent other drivers from
- * claiming a device and are therefore perfectly legitimate for a user owned
- * group.  The pci-stub driver has no dependencies on DMA or the IOVA mapping
- * of the device, but it does prevent the user from having direct access to
- * the device, which is useful in some circumstances.
- *
- * We also assume that we can include PCI interconnect devices, ie. bridges.
- * IOMMU grouping on PCI necessitates that if we lack isolation on a bridge
- * then all of the downstream devices will be part of the same IOMMU group as
- * the bridge.  Thus, if placing the bridge into the user owned IOVA space
- * breaks anything, it only does so for user owned devices downstream.  Note
- * that error notification via MSI can be affected for platforms that handle
- * MSI within the same IOVA space as DMA.
- */
-static const char * const vfio_driver_allowed[] = { "pci-stub" };
-
-static bool vfio_dev_driver_allowed(struct device *dev,
-                                   struct device_driver *drv)
-{
-       if (dev_is_pci(dev)) {
-               struct pci_dev *pdev = to_pci_dev(dev);
-
-               if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
-                       return true;
-       }
-
-       return match_string(vfio_driver_allowed,
-                           ARRAY_SIZE(vfio_driver_allowed),
-                           drv->name) >= 0;
-}
-
-/*
- * A vfio group is viable for use by userspace if all devices are in
- * one of the following states:
- *  - driver-less
- *  - bound to a vfio driver
- *  - bound to an otherwise allowed driver
- *  - a PCI interconnect device
- *
- * We use two methods to determine whether a device is bound to a vfio
- * driver.  The first is to test whether the device exists in the vfio
- * group.  The second is to test if the device exists on the group
- * unbound_list, indicating it's in the middle of transitioning from
- * a vfio driver to driver-less.
- */
-static int vfio_dev_viable(struct device *dev, void *data)
-{
-       struct vfio_group *group = data;
-       struct vfio_device *device;
-       struct device_driver *drv = READ_ONCE(dev->driver);
-
-       if (!drv || vfio_dev_driver_allowed(dev, drv))
-               return 0;
-
-       device = vfio_group_get_device(group, dev);
-       if (device) {
-               vfio_device_put(device);
-               return 0;
-       }
-
-       return -EINVAL;
-}
-
-/*
- * Async device support
- */
-static int vfio_group_nb_add_dev(struct vfio_group *group, struct device *dev)
-{
-       struct vfio_device *device;
-
-       /* Do we already know about it?  We shouldn't */
-       device = vfio_group_get_device(group, dev);
-       if (WARN_ON_ONCE(device)) {
-               vfio_device_put(device);
-               return 0;
-       }
-
-       /* Nothing to do for idle groups */
-       if (!atomic_read(&group->container_users))
-               return 0;
-
-       /* TODO Prevent device auto probing */
-       dev_WARN(dev, "Device added to live group %d!\n",
-                iommu_group_id(group->iommu_group));
-
-       return 0;
-}
-
-static int vfio_group_nb_verify(struct vfio_group *group, struct device *dev)
-{
-       /* We don't care what happens when the group isn't in use */
-       if (!atomic_read(&group->container_users))
-               return 0;
-
-       return vfio_dev_viable(dev, group);
-}
-
-static int vfio_iommu_group_notifier(struct notifier_block *nb,
-                                    unsigned long action, void *data)
-{
-       struct vfio_group *group = container_of(nb, struct vfio_group, nb);
-       struct device *dev = data;
-
-       switch (action) {
-       case IOMMU_GROUP_NOTIFY_ADD_DEVICE:
-               vfio_group_nb_add_dev(group, dev);
-               break;
-       case IOMMU_GROUP_NOTIFY_DEL_DEVICE:
-               /*
-                * Nothing to do here.  If the device is in use, then the
-                * vfio sub-driver should block the remove callback until
-                * it is unused.  If the device is unused or attached to a
-                * stub driver, then it should be released and we don't
-                * care that it will be going away.
-                */
-               break;
-       case IOMMU_GROUP_NOTIFY_BIND_DRIVER:
-               dev_dbg(dev, "%s: group %d binding to driver\n", __func__,
-                       iommu_group_id(group->iommu_group));
-               break;
-       case IOMMU_GROUP_NOTIFY_BOUND_DRIVER:
-               dev_dbg(dev, "%s: group %d bound to driver %s\n", __func__,
-                       iommu_group_id(group->iommu_group), dev->driver->name);
-               BUG_ON(vfio_group_nb_verify(group, dev));
-               break;
-       case IOMMU_GROUP_NOTIFY_UNBIND_DRIVER:
-               dev_dbg(dev, "%s: group %d unbinding from driver %s\n",
-                       __func__, iommu_group_id(group->iommu_group),
-                       dev->driver->name);
-               break;
-       }
-       return NOTIFY_OK;
-}
-
-/*
  * VFIO driver API
  */
 void vfio_init_group_dev(struct vfio_device *device, struct device *dev,