Commit 1669ecf9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'vfio-v5.10-rc3' of git://github.com/awilliam/linux-vfio

Pull VFIO fixes from Alex Williamson:

 - Remove code by using existing helper (Zenghui Yu)

 - fsl-mc copy-user return and underflow fixes (Dan Carpenter)

 - fsl-mc static function declaration (Diana Craciun)

 - Fix ioeventfd sleeping under spinlock (Alex Williamson)

 - Fix pm reference count leak in vfio-platform (Zhang Qilong)

 - Allow opening IGD device w/o OpRegion support (Fred Gao)

* tag 'vfio-v5.10-rc3' of git://github.com/awilliam/linux-vfio:
  vfio/pci: Bypass IGD init in case of -ENODEV
  vfio: platform: fix reference leak in vfio_platform_open
  vfio/pci: Implement ioeventfd thread handler for contended memory lock
  vfio/fsl-mc: Make vfio_fsl_mc_irqs_allocate static
  vfio/fsl-mc: prevent underflow in vfio_fsl_mc_mmap()
  vfio/fsl-mc: return -EFAULT if copy_to_user() fails
  vfio/type1: Use the new helper to find vfio_group
parents 30f3f68e e4eccb85
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -248,7 +248,9 @@ static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
		info.size = vdev->regions[info.index].size;
		info.flags = vdev->regions[info.index].flags;

		return copy_to_user((void __user *)arg, &info, minsz);
		if (copy_to_user((void __user *)arg, &info, minsz))
			return -EFAULT;
		return 0;
	}
	case VFIO_DEVICE_GET_IRQ_INFO:
	{
@@ -267,7 +269,9 @@ static long vfio_fsl_mc_ioctl(void *device_data, unsigned int cmd,
		info.flags = VFIO_IRQ_INFO_EVENTFD;
		info.count = 1;

		return copy_to_user((void __user *)arg, &info, minsz);
		if (copy_to_user((void __user *)arg, &info, minsz))
			return -EFAULT;
		return 0;
	}
	case VFIO_DEVICE_SET_IRQS:
	{
@@ -468,7 +472,7 @@ static int vfio_fsl_mc_mmap(void *device_data, struct vm_area_struct *vma)
{
	struct vfio_fsl_mc_device *vdev = device_data;
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
	int index;
	unsigned int index;

	index = vma->vm_pgoff >> (VFIO_FSL_MC_OFFSET_SHIFT - PAGE_SHIFT);

+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
#include "linux/fsl/mc.h"
#include "vfio_fsl_mc_private.h"

int vfio_fsl_mc_irqs_allocate(struct vfio_fsl_mc_device *vdev)
static int vfio_fsl_mc_irqs_allocate(struct vfio_fsl_mc_device *vdev)
{
	struct fsl_mc_device *mc_dev = vdev->mc_dev;
	struct vfio_fsl_mc_irq *mc_irq;
+1 −1
Original line number Diff line number Diff line
@@ -385,7 +385,7 @@ static int vfio_pci_enable(struct vfio_pci_device *vdev)
	    pdev->vendor == PCI_VENDOR_ID_INTEL &&
	    IS_ENABLED(CONFIG_VFIO_PCI_IGD)) {
		ret = vfio_pci_igd_init(vdev);
		if (ret) {
		if (ret && ret != -ENODEV) {
			pci_warn(pdev, "Failed to setup Intel IGD regions\n");
			goto disable_exit;
		}
+35 −8
Original line number Diff line number Diff line
@@ -356,33 +356,59 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
	return done;
}

static int vfio_pci_ioeventfd_handler(void *opaque, void *unused)
static void vfio_pci_ioeventfd_do_write(struct vfio_pci_ioeventfd *ioeventfd,
					bool test_mem)
{
	struct vfio_pci_ioeventfd *ioeventfd = opaque;

	switch (ioeventfd->count) {
	case 1:
		vfio_pci_iowrite8(ioeventfd->vdev, ioeventfd->test_mem,
		vfio_pci_iowrite8(ioeventfd->vdev, test_mem,
				  ioeventfd->data, ioeventfd->addr);
		break;
	case 2:
		vfio_pci_iowrite16(ioeventfd->vdev, ioeventfd->test_mem,
		vfio_pci_iowrite16(ioeventfd->vdev, test_mem,
				   ioeventfd->data, ioeventfd->addr);
		break;
	case 4:
		vfio_pci_iowrite32(ioeventfd->vdev, ioeventfd->test_mem,
		vfio_pci_iowrite32(ioeventfd->vdev, test_mem,
				   ioeventfd->data, ioeventfd->addr);
		break;
#ifdef iowrite64
	case 8:
		vfio_pci_iowrite64(ioeventfd->vdev, ioeventfd->test_mem,
		vfio_pci_iowrite64(ioeventfd->vdev, test_mem,
				   ioeventfd->data, ioeventfd->addr);
		break;
#endif
	}
}

static int vfio_pci_ioeventfd_handler(void *opaque, void *unused)
{
	struct vfio_pci_ioeventfd *ioeventfd = opaque;
	struct vfio_pci_device *vdev = ioeventfd->vdev;

	if (ioeventfd->test_mem) {
		if (!down_read_trylock(&vdev->memory_lock))
			return 1; /* Lock contended, use thread */
		if (!__vfio_pci_memory_enabled(vdev)) {
			up_read(&vdev->memory_lock);
			return 0;
		}
	}

	vfio_pci_ioeventfd_do_write(ioeventfd, false);

	if (ioeventfd->test_mem)
		up_read(&vdev->memory_lock);

	return 0;
}

static void vfio_pci_ioeventfd_thread(void *opaque, void *unused)
{
	struct vfio_pci_ioeventfd *ioeventfd = opaque;

	vfio_pci_ioeventfd_do_write(ioeventfd, ioeventfd->test_mem);
}

long vfio_pci_ioeventfd(struct vfio_pci_device *vdev, loff_t offset,
			uint64_t data, int count, int fd)
@@ -457,7 +483,8 @@ long vfio_pci_ioeventfd(struct vfio_pci_device *vdev, loff_t offset,
	ioeventfd->test_mem = vdev->pdev->resource[bar].flags & IORESOURCE_MEM;

	ret = vfio_virqfd_enable(ioeventfd, vfio_pci_ioeventfd_handler,
				 NULL, NULL, &ioeventfd->virqfd, fd);
				 vfio_pci_ioeventfd_thread, NULL,
				 &ioeventfd->virqfd, fd);
	if (ret) {
		kfree(ioeventfd);
		goto out_unlock;
+1 −2
Original line number Diff line number Diff line
@@ -267,7 +267,7 @@ static int vfio_platform_open(void *device_data)

		ret = pm_runtime_get_sync(vdev->device);
		if (ret < 0)
			goto err_pm;
			goto err_rst;

		ret = vfio_platform_call_reset(vdev, &extra_dbg);
		if (ret && vdev->reset_required) {
@@ -284,7 +284,6 @@ static int vfio_platform_open(void *device_data)

err_rst:
	pm_runtime_put(vdev->device);
err_pm:
	vfio_platform_irq_cleanup(vdev);
err_irq:
	vfio_platform_regions_cleanup(vdev);
Loading