Commit 6df62c5b authored by Jason Gunthorpe's avatar Jason Gunthorpe Committed by Alex Williamson
Browse files

vfio: Make vfio_device_ops pass a 'struct vfio_device *' instead of 'void *'



This is the standard kernel pattern, the ops associated with a struct get
the struct pointer in for typesafety. The expected design is to use
container_of to cleanly go from the subsystem level type to the driver
level type without having any type erasure in a void *.

Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Message-Id: <12-v3-225de1400dfc+4e074-vfio1_jgg@nvidia.com>
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 66873b5f
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -269,20 +269,22 @@ ready before calling it. The driver provides an ops structure for callbacks
similar to a file operations structure::

	struct vfio_device_ops {
		int	(*open)(void *device_data);
		void	(*release)(void *device_data);
		ssize_t	(*read)(void *device_data, char __user *buf,
		int	(*open)(struct vfio_device *vdev);
		void	(*release)(struct vfio_device *vdev);
		ssize_t	(*read)(struct vfio_device *vdev, char __user *buf,
				size_t count, loff_t *ppos);
		ssize_t	(*write)(void *device_data, const char __user *buf,
		ssize_t	(*write)(struct vfio_device *vdev,
				 const char __user *buf,
				 size_t size, loff_t *ppos);
		long	(*ioctl)(void *device_data, unsigned int cmd,
		long	(*ioctl)(struct vfio_device *vdev, unsigned int cmd,
				 unsigned long arg);
		int	(*mmap)(void *device_data, struct vm_area_struct *vma);
		int	(*mmap)(struct vfio_device *vdev,
				struct vm_area_struct *vma);
	};

Each function is passed the device_data that was originally registered
Each function is passed the vdev that was originally registered
in the vfio_register_group_dev() call above.  This allows the bus driver
an easy place to store its opaque, private data.  The open/release
to obtain its private data using container_of().  The open/release
callbacks are issued when a new file descriptor is created for a
device (via VFIO_GROUP_GET_DEVICE_FD).  The ioctl interface provides
a direct pass through for VFIO_DEVICE_* ioctls.  The read/write/mmap
+22 −14
Original line number Diff line number Diff line
@@ -135,9 +135,10 @@ static void vfio_fsl_mc_regions_cleanup(struct vfio_fsl_mc_device *vdev)
	kfree(vdev->regions);
}

static int vfio_fsl_mc_open(void *device_data)
static int vfio_fsl_mc_open(struct vfio_device *core_vdev)
{
	struct vfio_fsl_mc_device *vdev = device_data;
	struct vfio_fsl_mc_device *vdev =
		container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
	int ret;

	if (!try_module_get(THIS_MODULE))
@@ -161,9 +162,10 @@ static int vfio_fsl_mc_open(void *device_data)
	return ret;
}

static void vfio_fsl_mc_release(void *device_data)
static void vfio_fsl_mc_release(struct vfio_device *core_vdev)
{
	struct vfio_fsl_mc_device *vdev = device_data;
	struct vfio_fsl_mc_device *vdev =
		container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
	int ret;

	mutex_lock(&vdev->reflck->lock);
@@ -197,11 +199,12 @@ static void vfio_fsl_mc_release(void *device_data)
	module_put(THIS_MODULE);
}

static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
			      unsigned long arg)
static long vfio_fsl_mc_ioctl(struct vfio_device *core_vdev,
			      unsigned int cmd, unsigned long arg)
{
	unsigned long minsz;
	struct vfio_fsl_mc_device *vdev = device_data;
	struct vfio_fsl_mc_device *vdev =
		container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
	struct fsl_mc_device *mc_dev = vdev->mc_dev;

	switch (cmd) {
@@ -327,10 +330,11 @@ static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
	}
}

static ssize_t vfio_fsl_mc_read(void *device_data, char __user *buf,
static ssize_t vfio_fsl_mc_read(struct vfio_device *core_vdev, char __user *buf,
				size_t count, loff_t *ppos)
{
	struct vfio_fsl_mc_device *vdev = device_data;
	struct vfio_fsl_mc_device *vdev =
		container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
	unsigned int index = VFIO_FSL_MC_OFFSET_TO_INDEX(*ppos);
	loff_t off = *ppos & VFIO_FSL_MC_OFFSET_MASK;
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
@@ -404,10 +408,12 @@ static int vfio_fsl_mc_send_command(void __iomem *ioaddr, uint64_t *cmd_data)
	return 0;
}

static ssize_t vfio_fsl_mc_write(void *device_data, const char __user *buf,
				 size_t count, loff_t *ppos)
static ssize_t vfio_fsl_mc_write(struct vfio_device *core_vdev,
				 const char __user *buf, size_t count,
				 loff_t *ppos)
{
	struct vfio_fsl_mc_device *vdev = device_data;
	struct vfio_fsl_mc_device *vdev =
		container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
	unsigned int index = VFIO_FSL_MC_OFFSET_TO_INDEX(*ppos);
	loff_t off = *ppos & VFIO_FSL_MC_OFFSET_MASK;
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
@@ -468,9 +474,11 @@ static int vfio_fsl_mc_mmap_mmio(struct vfio_fsl_mc_region region,
			       size, vma->vm_page_prot);
}

static int vfio_fsl_mc_mmap(void *device_data, struct vm_area_struct *vma)
static int vfio_fsl_mc_mmap(struct vfio_device *core_vdev,
			    struct vm_area_struct *vma)
{
	struct vfio_fsl_mc_device *vdev = device_data;
	struct vfio_fsl_mc_device *vdev =
		container_of(core_vdev, struct vfio_fsl_mc_device, vdev);
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
	unsigned int index;

+18 −15
Original line number Diff line number Diff line
@@ -21,10 +21,11 @@
#define DRIVER_AUTHOR   "NVIDIA Corporation"
#define DRIVER_DESC     "VFIO based driver for Mediated device"

static int vfio_mdev_open(void *device_data)
static int vfio_mdev_open(struct vfio_device *core_vdev)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	int ret;

	if (unlikely(!parent->ops->open))
@@ -40,9 +41,9 @@ static int vfio_mdev_open(void *device_data)
	return ret;
}

static void vfio_mdev_release(void *device_data)
static void vfio_mdev_release(struct vfio_device *core_vdev)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	if (likely(parent->ops->release))
@@ -51,10 +52,10 @@ static void vfio_mdev_release(void *device_data)
	module_put(THIS_MODULE);
}

static long vfio_mdev_unlocked_ioctl(void *device_data,
static long vfio_mdev_unlocked_ioctl(struct vfio_device *core_vdev,
				     unsigned int cmd, unsigned long arg)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	if (unlikely(!parent->ops->ioctl))
@@ -63,10 +64,10 @@ static long vfio_mdev_unlocked_ioctl(void *device_data,
	return parent->ops->ioctl(mdev, cmd, arg);
}

static ssize_t vfio_mdev_read(void *device_data, char __user *buf,
static ssize_t vfio_mdev_read(struct vfio_device *core_vdev, char __user *buf,
			      size_t count, loff_t *ppos)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	if (unlikely(!parent->ops->read))
@@ -75,10 +76,11 @@ static ssize_t vfio_mdev_read(void *device_data, char __user *buf,
	return parent->ops->read(mdev, buf, count, ppos);
}

static ssize_t vfio_mdev_write(void *device_data, const char __user *buf,
			       size_t count, loff_t *ppos)
static ssize_t vfio_mdev_write(struct vfio_device *core_vdev,
			       const char __user *buf, size_t count,
			       loff_t *ppos)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	if (unlikely(!parent->ops->write))
@@ -87,9 +89,10 @@ static ssize_t vfio_mdev_write(void *device_data, const char __user *buf,
	return parent->ops->write(mdev, buf, count, ppos);
}

static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma)
static int vfio_mdev_mmap(struct vfio_device *core_vdev,
			  struct vm_area_struct *vma)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	if (unlikely(!parent->ops->mmap))
@@ -98,9 +101,9 @@ static int vfio_mdev_mmap(void *device_data, struct vm_area_struct *vma)
	return parent->ops->mmap(mdev, vma);
}

static void vfio_mdev_request(void *device_data, unsigned int count)
static void vfio_mdev_request(struct vfio_device *core_vdev, unsigned int count)
{
	struct mdev_device *mdev = device_data;
	struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
	struct mdev_parent *parent = mdev->parent;

	if (parent->ops->request)
+29 −18
Original line number Diff line number Diff line
@@ -553,9 +553,10 @@ static void vfio_pci_vf_token_user_add(struct vfio_pci_device *vdev, int val)
	vfio_device_put(pf_dev);
}

static void vfio_pci_release(void *device_data)
static void vfio_pci_release(struct vfio_device *core_vdev)
{
	struct vfio_pci_device *vdev = device_data;
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);

	mutex_lock(&vdev->reflck->lock);

@@ -581,9 +582,10 @@ static void vfio_pci_release(void *device_data)
	module_put(THIS_MODULE);
}

static int vfio_pci_open(void *device_data)
static int vfio_pci_open(struct vfio_device *core_vdev)
{
	struct vfio_pci_device *vdev = device_data;
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);
	int ret = 0;

	if (!try_module_get(THIS_MODULE))
@@ -797,10 +799,11 @@ struct vfio_devices {
	int max_index;
};

static long vfio_pci_ioctl(void *device_data,
static long vfio_pci_ioctl(struct vfio_device *core_vdev,
			   unsigned int cmd, unsigned long arg)
{
	struct vfio_pci_device *vdev = device_data;
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);
	unsigned long minsz;

	if (cmd == VFIO_DEVICE_GET_INFO) {
@@ -1402,11 +1405,10 @@ static long vfio_pci_ioctl(void *device_data,
	return -ENOTTY;
}

static ssize_t vfio_pci_rw(void *device_data, char __user *buf,
static ssize_t vfio_pci_rw(struct vfio_pci_device *vdev, char __user *buf,
			   size_t count, loff_t *ppos, bool iswrite)
{
	unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
	struct vfio_pci_device *vdev = device_data;

	if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
		return -EINVAL;
@@ -1434,22 +1436,28 @@ static ssize_t vfio_pci_rw(void *device_data, char __user *buf,
	return -EINVAL;
}

static ssize_t vfio_pci_read(void *device_data, char __user *buf,
static ssize_t vfio_pci_read(struct vfio_device *core_vdev, char __user *buf,
			     size_t count, loff_t *ppos)
{
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);

	if (!count)
		return 0;

	return vfio_pci_rw(device_data, buf, count, ppos, false);
	return vfio_pci_rw(vdev, buf, count, ppos, false);
}

static ssize_t vfio_pci_write(void *device_data, const char __user *buf,
static ssize_t vfio_pci_write(struct vfio_device *core_vdev, const char __user *buf,
			      size_t count, loff_t *ppos)
{
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);

	if (!count)
		return 0;

	return vfio_pci_rw(device_data, (char __user *)buf, count, ppos, true);
	return vfio_pci_rw(vdev, (char __user *)buf, count, ppos, true);
}

/* Return 1 on zap and vma_lock acquired, 0 on contention (only with @try) */
@@ -1646,9 +1654,10 @@ static const struct vm_operations_struct vfio_pci_mmap_ops = {
	.fault = vfio_pci_mmap_fault,
};

static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
static int vfio_pci_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma)
{
	struct vfio_pci_device *vdev = device_data;
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);
	struct pci_dev *pdev = vdev->pdev;
	unsigned int index;
	u64 phys_len, req_len, pgoff, req_start;
@@ -1714,9 +1723,10 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
	return 0;
}

static void vfio_pci_request(void *device_data, unsigned int count)
static void vfio_pci_request(struct vfio_device *core_vdev, unsigned int count)
{
	struct vfio_pci_device *vdev = device_data;
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);
	struct pci_dev *pdev = vdev->pdev;

	mutex_lock(&vdev->igate);
@@ -1830,9 +1840,10 @@ static int vfio_pci_validate_vf_token(struct vfio_pci_device *vdev,

#define VF_TOKEN_ARG "vf_token="

static int vfio_pci_match(void *device_data, char *buf)
static int vfio_pci_match(struct vfio_device *core_vdev, char *buf)
{
	struct vfio_pci_device *vdev = device_data;
	struct vfio_pci_device *vdev =
		container_of(core_vdev, struct vfio_pci_device, vdev);
	bool vf_token = false;
	uuid_t uuid;
	int ret;
+20 −13
Original line number Diff line number Diff line
@@ -218,9 +218,10 @@ static int vfio_platform_call_reset(struct vfio_platform_device *vdev,
	return -EINVAL;
}

static void vfio_platform_release(void *device_data)
static void vfio_platform_release(struct vfio_device *core_vdev)
{
	struct vfio_platform_device *vdev = device_data;
	struct vfio_platform_device *vdev =
		container_of(core_vdev, struct vfio_platform_device, vdev);

	mutex_lock(&driver_lock);

@@ -244,9 +245,10 @@ static void vfio_platform_release(void *device_data)
	module_put(vdev->parent_module);
}

static int vfio_platform_open(void *device_data)
static int vfio_platform_open(struct vfio_device *core_vdev)
{
	struct vfio_platform_device *vdev = device_data;
	struct vfio_platform_device *vdev =
		container_of(core_vdev, struct vfio_platform_device, vdev);
	int ret;

	if (!try_module_get(vdev->parent_module))
@@ -293,10 +295,12 @@ static int vfio_platform_open(void *device_data)
	return ret;
}

static long vfio_platform_ioctl(void *device_data,
static long vfio_platform_ioctl(struct vfio_device *core_vdev,
				unsigned int cmd, unsigned long arg)
{
	struct vfio_platform_device *vdev = device_data;
	struct vfio_platform_device *vdev =
		container_of(core_vdev, struct vfio_platform_device, vdev);

	unsigned long minsz;

	if (cmd == VFIO_DEVICE_GET_INFO) {
@@ -455,10 +459,11 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg,
	return -EFAULT;
}

static ssize_t vfio_platform_read(void *device_data, char __user *buf,
				  size_t count, loff_t *ppos)
static ssize_t vfio_platform_read(struct vfio_device *core_vdev,
				  char __user *buf, size_t count, loff_t *ppos)
{
	struct vfio_platform_device *vdev = device_data;
	struct vfio_platform_device *vdev =
		container_of(core_vdev, struct vfio_platform_device, vdev);
	unsigned int index = VFIO_PLATFORM_OFFSET_TO_INDEX(*ppos);
	loff_t off = *ppos & VFIO_PLATFORM_OFFSET_MASK;

@@ -531,10 +536,11 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg,
	return -EFAULT;
}

static ssize_t vfio_platform_write(void *device_data, const char __user *buf,
static ssize_t vfio_platform_write(struct vfio_device *core_vdev, const char __user *buf,
				   size_t count, loff_t *ppos)
{
	struct vfio_platform_device *vdev = device_data;
	struct vfio_platform_device *vdev =
		container_of(core_vdev, struct vfio_platform_device, vdev);
	unsigned int index = VFIO_PLATFORM_OFFSET_TO_INDEX(*ppos);
	loff_t off = *ppos & VFIO_PLATFORM_OFFSET_MASK;

@@ -573,9 +579,10 @@ static int vfio_platform_mmap_mmio(struct vfio_platform_region region,
			       req_len, vma->vm_page_prot);
}

static int vfio_platform_mmap(void *device_data, struct vm_area_struct *vma)
static int vfio_platform_mmap(struct vfio_device *core_vdev, struct vm_area_struct *vma)
{
	struct vfio_platform_device *vdev = device_data;
	struct vfio_platform_device *vdev =
		container_of(core_vdev, struct vfio_platform_device, vdev);
	unsigned int index;

	index = vma->vm_pgoff >> (VFIO_PLATFORM_OFFSET_SHIFT - PAGE_SHIFT);
Loading