aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vfio/vfio.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index f018d8d0f975..43d5622b19b7 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -63,6 +63,11 @@ struct vfio_container {
63 void *iommu_data; 63 void *iommu_data;
64}; 64};
65 65
66struct vfio_unbound_dev {
67 struct device *dev;
68 struct list_head unbound_next;
69};
70
66struct vfio_group { 71struct vfio_group {
67 struct kref kref; 72 struct kref kref;
68 int minor; 73 int minor;
@@ -75,6 +80,8 @@ struct vfio_group {
75 struct notifier_block nb; 80 struct notifier_block nb;
76 struct list_head vfio_next; 81 struct list_head vfio_next;
77 struct list_head container_next; 82 struct list_head container_next;
83 struct list_head unbound_list;
84 struct mutex unbound_lock;
78 atomic_t opened; 85 atomic_t opened;
79}; 86};
80 87
@@ -204,6 +211,8 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
204 kref_init(&group->kref); 211 kref_init(&group->kref);
205 INIT_LIST_HEAD(&group->device_list); 212 INIT_LIST_HEAD(&group->device_list);
206 mutex_init(&group->device_lock); 213 mutex_init(&group->device_lock);
214 INIT_LIST_HEAD(&group->unbound_list);
215 mutex_init(&group->unbound_lock);
207 atomic_set(&group->container_users, 0); 216 atomic_set(&group->container_users, 0);
208 atomic_set(&group->opened, 0); 217 atomic_set(&group->opened, 0);
209 group->iommu_group = iommu_group; 218 group->iommu_group = iommu_group;
@@ -264,9 +273,16 @@ static struct vfio_group *vfio_create_group(struct iommu_group *iommu_group)
264static void vfio_group_release(struct kref *kref) 273static void vfio_group_release(struct kref *kref)
265{ 274{
266 struct vfio_group *group = container_of(kref, struct vfio_group, kref); 275 struct vfio_group *group = container_of(kref, struct vfio_group, kref);
276 struct vfio_unbound_dev *unbound, *tmp;
267 277
268 WARN_ON(!list_empty(&group->device_list)); 278 WARN_ON(!list_empty(&group->device_list));
269 279
280 list_for_each_entry_safe(unbound, tmp,
281 &group->unbound_list, unbound_next) {
282 list_del(&unbound->unbound_next);
283 kfree(unbound);
284 }
285
270 device_destroy(vfio.class, MKDEV(MAJOR(vfio.group_devt), group->minor)); 286 device_destroy(vfio.class, MKDEV(MAJOR(vfio.group_devt), group->minor));
271 list_del(&group->vfio_next); 287 list_del(&group->vfio_next);
272 vfio_free_group_minor(group->minor); 288 vfio_free_group_minor(group->minor);
@@ -440,17 +456,36 @@ static bool vfio_whitelisted_driver(struct device_driver *drv)
440} 456}
441 457
442/* 458/*
443 * A vfio group is viable for use by userspace if all devices are either 459 * A vfio group is viable for use by userspace if all devices are in
444 * driver-less or bound to a vfio or whitelisted driver. We test the 460 * one of the following states:
445 * latter by the existence of a struct vfio_device matching the dev. 461 * - driver-less
462 * - bound to a vfio driver
463 * - bound to a whitelisted driver
464 *
465 * We use two methods to determine whether a device is bound to a vfio
466 * driver. The first is to test whether the device exists in the vfio
467 * group. The second is to test if the device exists on the group
468 * unbound_list, indicating it's in the middle of transitioning from
469 * a vfio driver to driver-less.
446 */ 470 */
447static int vfio_dev_viable(struct device *dev, void *data) 471static int vfio_dev_viable(struct device *dev, void *data)
448{ 472{
449 struct vfio_group *group = data; 473 struct vfio_group *group = data;
450 struct vfio_device *device; 474 struct vfio_device *device;
451 struct device_driver *drv = ACCESS_ONCE(dev->driver); 475 struct device_driver *drv = ACCESS_ONCE(dev->driver);
476 struct vfio_unbound_dev *unbound;
477 int ret = -EINVAL;
452 478
453 if (!drv || vfio_whitelisted_driver(drv)) 479 mutex_lock(&group->unbound_lock);
480 list_for_each_entry(unbound, &group->unbound_list, unbound_next) {
481 if (dev == unbound->dev) {
482 ret = 0;
483 break;
484 }
485 }
486 mutex_unlock(&group->unbound_lock);
487
488 if (!ret || !drv || vfio_whitelisted_driver(drv))
454 return 0; 489 return 0;
455 490
456 device = vfio_group_get_device(group, dev); 491 device = vfio_group_get_device(group, dev);
@@ -459,7 +494,7 @@ static int vfio_dev_viable(struct device *dev, void *data)
459 return 0; 494 return 0;
460 } 495 }
461 496
462 return -EINVAL; 497 return ret;
463} 498}
464 499
465/** 500/**
@@ -501,6 +536,7 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
501{ 536{
502 struct vfio_group *group = container_of(nb, struct vfio_group, nb); 537 struct vfio_group *group = container_of(nb, struct vfio_group, nb);
503 struct device *dev = data; 538 struct device *dev = data;
539 struct vfio_unbound_dev *unbound;
504 540
505 /* 541 /*
506 * Need to go through a group_lock lookup to get a reference or we 542 * Need to go through a group_lock lookup to get a reference or we
@@ -550,6 +586,17 @@ static int vfio_iommu_group_notifier(struct notifier_block *nb,
550 * stop the system to maintain isolation. At a minimum, we'd 586 * stop the system to maintain isolation. At a minimum, we'd
551 * want a toggle to disable driver auto probe for this device. 587 * want a toggle to disable driver auto probe for this device.
552 */ 588 */
589
590 mutex_lock(&group->unbound_lock);
591 list_for_each_entry(unbound,
592 &group->unbound_list, unbound_next) {
593 if (dev == unbound->dev) {
594 list_del(&unbound->unbound_next);
595 kfree(unbound);
596 break;
597 }
598 }
599 mutex_unlock(&group->unbound_lock);
553 break; 600 break;
554 } 601 }
555 602
@@ -657,6 +704,7 @@ void *vfio_del_group_dev(struct device *dev)
657 struct vfio_group *group = device->group; 704 struct vfio_group *group = device->group;
658 struct iommu_group *iommu_group = group->iommu_group; 705 struct iommu_group *iommu_group = group->iommu_group;
659 void *device_data = device->device_data; 706 void *device_data = device->device_data;
707 struct vfio_unbound_dev *unbound;
660 708
661 /* 709 /*
662 * The group exists so long as we have a device reference. Get 710 * The group exists so long as we have a device reference. Get
@@ -664,6 +712,24 @@ void *vfio_del_group_dev(struct device *dev)
664 */ 712 */
665 vfio_group_get(group); 713 vfio_group_get(group);
666 714
715 /*
716 * When the device is removed from the group, the group suddenly
717 * becomes non-viable; the device has a driver (until the unbind
718 * completes), but it's not present in the group. This is bad news
719 * for any external users that need to re-acquire a group reference
720 * in order to match and release their existing reference. To
721 * solve this, we track such devices on the unbound_list to bridge
722 * the gap until they're fully unbound.
723 */
724 unbound = kzalloc(sizeof(*unbound), GFP_KERNEL);
725 if (unbound) {
726 unbound->dev = dev;
727 mutex_lock(&group->unbound_lock);
728 list_add(&unbound->unbound_next, &group->unbound_list);
729 mutex_unlock(&group->unbound_lock);
730 }
731 WARN_ON(!unbound);
732
667 vfio_device_put(device); 733 vfio_device_put(device);
668 734
669 /* TODO send a signal to encourage this to be released */ 735 /* TODO send a signal to encourage this to be released */