vfio/pci: Pull BAR mapping setup from read-write path
authorAlex Williamson <alex.williamson@redhat.com>
Wed, 21 Mar 2018 18:46:20 +0000 (12:46 -0600)
committerAlex Williamson <alex.williamson@redhat.com>
Mon, 26 Mar 2018 19:22:58 +0000 (13:22 -0600)
This creates a common helper that we'll use for ioeventfd setup.

Reviewed-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/pci/vfio_pci_rdwr.c

index 357243d..5f2b376 100644 (file)
@@ -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;