lkml.org 
[lkml]   [2022]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RESEND PATCH v8 10/11] vfio: Remove iommu group notifier
    Date
    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>
    ---
    drivers/vfio/vfio.c | 147 --------------------------------------------
    1 file changed, 147 deletions(-)

    diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
    index b2f19d17d0c3..0c766384cee0 100644
    --- a/drivers/vfio/vfio.c
    +++ b/drivers/vfio/vfio.c
    @@ -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);
    }

    @@ -503,141 +491,6 @@ static struct vfio_device *vfio_group_get_device(struct vfio_group *group,
    return NULL;
    }

    -/*
    - * 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
    */
    --
    2.25.1
    \
     
     \ /
      Last update: 2022-04-18 02:53    [W:2.130 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site