aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2015-02-06 17:05:06 -0500
committerAlex Williamson <alex.williamson@redhat.com>2015-02-06 17:05:06 -0500
commit60720a0fc6469e8f924f85510c2a24ecc7bdaf9c (patch)
treed6adf501a76c7ba94c2fef6465082a49c23885f2
parentc5e6688752c25434d71920bc969f9fab60353c5e (diff)
vfio: Add device tracking during unbind
There's a small window between the vfio bus driver calling vfio_del_group_dev() and the device being completely unbound where the vfio group appears to be non-viable. This creates a race for users like QEMU/KVM where the kvm-vfio module tries to get an external reference to the group in order to match and release an existing reference, while the device is potentially being removed from the vfio bus driver. If the group is momentarily non-viable, kvm-vfio may not be able to release the group reference until VM shutdown, making the group unusable until that point. Bridge the gap between device removal from the group and completion of the driver unbind by tracking it in a list. The device is added to the list before the bus driver reference is released and removed using the existing unbind notifier. Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-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 */