[PATCH 2/3] vfio/pci: refactor vfio_pci_bar_rw

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In the next patch the logic for reading ROM will get more complicated,
so decouple the ROM path from the normal path. Also check that for ROM
write is not allowed.

Signed-off-by: Yunxiang Li <Yunxiang.Li@xxxxxxx>
---
 drivers/vfio/pci/vfio_pci_rdwr.c | 47 ++++++++++++++++----------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index a1eeacad82120..4bed9fd5af50f 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -236,10 +236,9 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
 	struct pci_dev *pdev = vdev->pdev;
 	loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;
 	int bar = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
-	size_t x_start = 0, x_end = 0;
+	size_t x_start, x_end;
 	resource_size_t end;
 	void __iomem *io;
-	struct resource *res = &vdev->pdev->resource[bar];
 	ssize_t done;
 
 	if (pci_resource_start(pdev, bar))
@@ -253,41 +252,43 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_core_device *vdev, char __user *buf,
 	count = min(count, (size_t)(end - pos));
 
 	if (bar == PCI_ROM_RESOURCE) {
+		if (iswrite)
+			return -EINVAL;
 		/*
 		 * The ROM can fill less space than the BAR, so we start the
 		 * excluded range at the end of the actual ROM.  This makes
 		 * filling large ROM BARs much faster.
 		 */
 		io = pci_map_rom(pdev, &x_start);
-		if (!io) {
-			done = -ENOMEM;
-			goto out;
-		}
+		if (!io)
+			return -ENOMEM;
 		x_end = end;
+
+		done = vfio_pci_core_do_io_rw(vdev, 1, io, buf, pos,
+					      count, x_start, x_end, 0);
+
+		pci_unmap_rom(pdev, io);
 	} else {
-		int ret = vfio_pci_core_setup_barmap(vdev, bar);
-		if (ret) {
-			done = ret;
-			goto out;
-		}
+		done = vfio_pci_core_setup_barmap(vdev, bar);
+		if (done)
+			return done;
 
 		io = vdev->barmap[bar];
-	}
 
-	if (bar == vdev->msix_bar) {
-		x_start = vdev->msix_offset;
-		x_end = vdev->msix_offset + vdev->msix_size;
-	}
+		if (bar == vdev->msix_bar) {
+			x_start = vdev->msix_offset;
+			x_end = vdev->msix_offset + vdev->msix_size;
+		} else {
+			x_start = 0;
+			x_end = 0;
+		}
 
-	done = vfio_pci_core_do_io_rw(vdev, res->flags & IORESOURCE_MEM, io, buf, pos,
+		done = vfio_pci_core_do_io_rw(vdev, pci_resource_flags(pdev, bar) & IORESOURCE_MEM, io, buf, pos,
 				      count, x_start, x_end, iswrite);
-
-	if (done >= 0)
-		*ppos += done;
-
-	if (bar == PCI_ROM_RESOURCE)
-		pci_unmap_rom(pdev, io);
+	}
 out:
+	if (done > 0)
+		*ppos += done;
 	return done;
 }
 
-- 
2.47.0





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux