summaryrefslogtreecommitdiff
path: root/include/linux/vfio.h
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@nvidia.com>2021-08-05 22:19:00 -0300
committerAlex Williamson <alex.williamson@redhat.com>2021-08-11 09:50:10 -0600
commit2fd585f4ed9de9b9259e95affdd7d8cde06b48c3 (patch)
tree765157afafc629b94e83741d26184e5b911eb298 /include/linux/vfio.h
parentae03c3771b8cbbed3802ad1153d896c32015c520 (diff)
vfio: Provide better generic support for open/release vfio_device_ops
Currently the driver ops have an open/release pair that is called once each time a device FD is opened or closed. Add an additional set of open/close_device() ops which are called when the device FD is opened for the first time and closed for the last time. An analysis shows that all of the drivers require this semantic. Some are open coding it as part of their reflck implementation, and some are just buggy and miss it completely. To retain the current semantics PCI and FSL depend on, introduce the idea of a "device set" which is a grouping of vfio_device's that share the same lock around opening. The device set is established by providing a 'set_id' pointer. All vfio_device's that provide the same pointer will be joined to the same singleton memory and lock across the whole set. This effectively replaces the oddly named reflck. After conversion the set_id will be sourced from: - A struct device from a fsl_mc_device (fsl) - A struct pci_slot (pci) - A struct pci_bus (pci) - The struct vfio_device (everything) The design ensures that the above pointers are live as long as the vfio_device is registered, so they form reliable unique keys to group vfio_devices into sets. This implementation uses xarray instead of searching through the driver core structures, which simplifies the somewhat tricky locking in this area. Following patches convert all the drivers. Signed-off-by: Yishai Hadas <yishaih@nvidia.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Link: https://lore.kernel.org/r/4-v4-9ea22c5e6afb+1adf-vfio_reflck_jgg@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Diffstat (limited to 'include/linux/vfio.h')
-rw-r--r--include/linux/vfio.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index b0875cf8e496..f0e6a72875e4 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -15,13 +15,28 @@
#include <linux/poll.h>
#include <uapi/linux/vfio.h>
+/*
+ * VFIO devices can be placed in a set, this allows all devices to share this
+ * structure and the VFIO core will provide a lock that is held around
+ * open_device()/close_device() for all devices in the set.
+ */
+struct vfio_device_set {
+ void *set_id;
+ struct mutex lock;
+ struct list_head device_list;
+ unsigned int device_count;
+};
+
struct vfio_device {
struct device *dev;
const struct vfio_device_ops *ops;
struct vfio_group *group;
+ struct vfio_device_set *dev_set;
+ struct list_head dev_set_list;
/* Members below here are private, not for driver use */
refcount_t refcount;
+ unsigned int open_count;
struct completion comp;
struct list_head group_next;
};
@@ -29,6 +44,8 @@ struct vfio_device {
/**
* struct vfio_device_ops - VFIO bus driver device callbacks
*
+ * @open_device: Called when the first file descriptor is opened for this device
+ * @close_device: Opposite of open_device
* @open: Called when userspace creates new file descriptor for device
* @release: Called when userspace releases file descriptor for device
* @read: Perform read(2) on device file descriptor
@@ -43,6 +60,8 @@ struct vfio_device {
*/
struct vfio_device_ops {
char *name;
+ int (*open_device)(struct vfio_device *vdev);
+ void (*close_device)(struct vfio_device *vdev);
int (*open)(struct vfio_device *vdev);
void (*release)(struct vfio_device *vdev);
ssize_t (*read)(struct vfio_device *vdev, char __user *buf,
@@ -67,6 +86,8 @@ void vfio_unregister_group_dev(struct vfio_device *device);
extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);
extern void vfio_device_put(struct vfio_device *device);
+int vfio_assign_device_set(struct vfio_device *device, void *set_id);
+
/* events for the backend driver notify callback */
enum vfio_iommu_notify_type {
VFIO_IOMMU_CONTAINER_CLOSE = 0,