Commit 0d77ed35 authored by Alex Williamson's avatar Alex Williamson
Browse files

vfio/pci: Pull BAR mapping setup from read-write path



This creates a common helper that we'll use for ioeventfd setup.

Reviewed-by: default avatarPeter Xu <peterx@redhat.com>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Reviewed-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 356e88eb
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
@@ -113,6 +113,30 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
	return done;
}

static int vfio_pci_setup_barmap(struct vfio_pci_device *vdev, int bar)
{
	struct pci_dev *pdev = vdev->pdev;
	int ret;
	void __iomem *io;

	if (vdev->barmap[bar])
		return 0;

	ret = pci_request_selected_regions(pdev, 1 << bar, "vfio");
	if (ret)
		return ret;

	io = pci_iomap(pdev, bar, 0);
	if (!io) {
		pci_release_selected_regions(pdev, 1 << bar);
		return -ENOMEM;
	}

	vdev->barmap[bar] = io;

	return 0;
}

ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
			size_t count, loff_t *ppos, bool iswrite)
{
@@ -147,22 +171,13 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
		if (!io)
			return -ENOMEM;
		x_end = end;
	} else if (!vdev->barmap[bar]) {
		int ret;

		ret = pci_request_selected_regions(pdev, 1 << bar, "vfio");
	} else {
		int ret = vfio_pci_setup_barmap(vdev, bar);
		if (ret)
			return ret;

		io = pci_iomap(pdev, bar, 0);
		if (!io) {
			pci_release_selected_regions(pdev, 1 << bar);
			return -ENOMEM;
		}

		vdev->barmap[bar] = io;
	} else
		io = vdev->barmap[bar];
	}

	if (bar == vdev->msix_bar) {
		x_start = vdev->msix_offset;