vfio: Include optional device match in vfio_device_ops callbacks
authorAlex Williamson <alex.williamson@redhat.com>
Tue, 24 Mar 2020 15:28:25 +0000 (09:28 -0600)
committerAlex Williamson <alex.williamson@redhat.com>
Tue, 24 Mar 2020 15:28:25 +0000 (09:28 -0600)
Allow bus drivers to provide their own callback to match a device to
the user provided string.

Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/vfio.c
include/linux/vfio.h

index c848262..0bd77d6 100644 (file)
@@ -875,11 +875,23 @@ EXPORT_SYMBOL_GPL(vfio_device_get_from_dev);
 static struct vfio_device *vfio_device_get_from_name(struct vfio_group *group,
                                                     char *buf)
 {
-       struct vfio_device *it, *device = NULL;
+       struct vfio_device *it, *device = ERR_PTR(-ENODEV);
 
        mutex_lock(&group->device_lock);
        list_for_each_entry(it, &group->device_list, group_next) {
-               if (!strcmp(dev_name(it->dev), buf)) {
+               int ret;
+
+               if (it->ops->match) {
+                       ret = it->ops->match(it->device_data, buf);
+                       if (ret < 0) {
+                               device = ERR_PTR(ret);
+                               break;
+                       }
+               } else {
+                       ret = !strcmp(dev_name(it->dev), buf);
+               }
+
+               if (ret) {
                        device = it;
                        vfio_device_get(device);
                        break;
@@ -1430,8 +1442,8 @@ static int vfio_group_get_device_fd(struct vfio_group *group, char *buf)
                return -EPERM;
 
        device = vfio_device_get_from_name(group, buf);
-       if (!device)
-               return -ENODEV;
+       if (IS_ERR(device))
+               return PTR_ERR(device);
 
        ret = device->ops->open(device->device_data);
        if (ret) {
index e42a711..029694b 100644 (file)
@@ -26,6 +26,9 @@
  *         operations documented below
  * @mmap: Perform mmap(2) on a region of the device file descriptor
  * @request: Request for the bus driver to release the device
+ * @match: Optional device name match callback (return: 0 for no-match, >0 for
+ *         match, -errno for abort (ex. match with insufficient or incorrect
+ *         additional args)
  */
 struct vfio_device_ops {
        char    *name;
@@ -39,6 +42,7 @@ struct vfio_device_ops {
                         unsigned long arg);
        int     (*mmap)(void *device_data, struct vm_area_struct *vma);
        void    (*request)(void *device_data, unsigned int count);
+       int     (*match)(void *device_data, char *buf);
 };
 
 extern struct iommu_group *vfio_iommu_group_get(struct device *dev);