aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vfio/vfio.c24
-rw-r--r--include/linux/vfio.h2
2 files changed, 24 insertions, 2 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index 13e0f39d91e0..4cde85501444 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -710,6 +710,7 @@ void *vfio_del_group_dev(struct device *dev)
710 struct vfio_group *group = device->group; 710 struct vfio_group *group = device->group;
711 void *device_data = device->device_data; 711 void *device_data = device->device_data;
712 struct vfio_unbound_dev *unbound; 712 struct vfio_unbound_dev *unbound;
713 unsigned int i = 0;
713 714
714 /* 715 /*
715 * The group exists so long as we have a device reference. Get 716 * The group exists so long as we have a device reference. Get
@@ -737,8 +738,27 @@ void *vfio_del_group_dev(struct device *dev)
737 738
738 vfio_device_put(device); 739 vfio_device_put(device);
739 740
740 /* TODO send a signal to encourage this to be released */ 741 /*
741 wait_event(vfio.release_q, !vfio_dev_present(group, dev)); 742 * If the device is still present in the group after the above
743 * 'put', then it is in use and we need to request it from the
744 * bus driver. The driver may in turn need to request the
745 * device from the user. We send the request on an arbitrary
746 * interval with counter to allow the driver to take escalating
747 * measures to release the device if it has the ability to do so.
748 */
749 do {
750 device = vfio_group_get_device(group, dev);
751 if (!device)
752 break;
753
754 if (device->ops->request)
755 device->ops->request(device_data, i++);
756
757 vfio_device_put(device);
758
759 } while (wait_event_interruptible_timeout(vfio.release_q,
760 !vfio_dev_present(group, dev),
761 HZ * 10) <= 0);
742 762
743 vfio_group_put(group); 763 vfio_group_put(group);
744 764
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index d3204115f15d..2d67b8998fd8 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -26,6 +26,7 @@
26 * @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_* 26 * @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_*
27 * operations documented below 27 * operations documented below
28 * @mmap: Perform mmap(2) on a region of the device file descriptor 28 * @mmap: Perform mmap(2) on a region of the device file descriptor
29 * @request: Request for the bus driver to release the device
29 */ 30 */
30struct vfio_device_ops { 31struct vfio_device_ops {
31 char *name; 32 char *name;
@@ -38,6 +39,7 @@ struct vfio_device_ops {
38 long (*ioctl)(void *device_data, unsigned int cmd, 39 long (*ioctl)(void *device_data, unsigned int cmd,
39 unsigned long arg); 40 unsigned long arg);
40 int (*mmap)(void *device_data, struct vm_area_struct *vma); 41 int (*mmap)(void *device_data, struct vm_area_struct *vma);
42 void (*request)(void *device_data, unsigned int count);
41}; 43};
42 44
43extern int vfio_add_group_dev(struct device *dev, 45extern int vfio_add_group_dev(struct device *dev,