summaryrefslogtreecommitdiffstats
path: root/drivers/vfio/pci/vfio_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vfio/pci/vfio_pci.c')
-rw-r--r--drivers/vfio/pci/vfio_pci.c64
1 files changed, 8 insertions, 56 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index de48acd..b0f7594 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -565,47 +565,15 @@ static int vfio_pci_for_each_slot_or_bus(struct pci_dev *pdev,
return walk.ret;
}
-static int msix_sparse_mmap_cap(struct vfio_pci_device *vdev,
- struct vfio_info_cap *caps)
+static int msix_mmappable_cap(struct vfio_pci_device *vdev,
+ struct vfio_info_cap *caps)
{
- struct vfio_region_info_cap_sparse_mmap *sparse;
- size_t end, size;
- int nr_areas = 2, i = 0, ret;
-
- end = pci_resource_len(vdev->pdev, vdev->msix_bar);
-
- /* If MSI-X table is aligned to the start or end, only one area */
- if (((vdev->msix_offset & PAGE_MASK) == 0) ||
- (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) >= end))
- nr_areas = 1;
-
- size = sizeof(*sparse) + (nr_areas * sizeof(*sparse->areas));
-
- sparse = kzalloc(size, GFP_KERNEL);
- if (!sparse)
- return -ENOMEM;
-
- sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
- sparse->header.version = 1;
- sparse->nr_areas = nr_areas;
-
- if (vdev->msix_offset & PAGE_MASK) {
- sparse->areas[i].offset = 0;
- sparse->areas[i].size = vdev->msix_offset & PAGE_MASK;
- i++;
- }
-
- if (PAGE_ALIGN(vdev->msix_offset + vdev->msix_size) < end) {
- sparse->areas[i].offset = PAGE_ALIGN(vdev->msix_offset +
- vdev->msix_size);
- sparse->areas[i].size = end - sparse->areas[i].offset;
- i++;
- }
-
- ret = vfio_info_add_capability(caps, &sparse->header, size);
- kfree(sparse);
+ struct vfio_info_cap_header header = {
+ .id = VFIO_REGION_INFO_CAP_MSIX_MAPPABLE,
+ .version = 1
+ };
- return ret;
+ return vfio_info_add_capability(caps, &header, sizeof(header));
}
int vfio_pci_register_dev_region(struct vfio_pci_device *vdev,
@@ -696,7 +664,7 @@ static long vfio_pci_ioctl(void *device_data,
if (vdev->bar_mmap_supported[info.index]) {
info.flags |= VFIO_REGION_INFO_FLAG_MMAP;
if (info.index == vdev->msix_bar) {
- ret = msix_sparse_mmap_cap(vdev, &caps);
+ ret = msix_mmappable_cap(vdev, &caps);
if (ret)
return ret;
}
@@ -1127,22 +1095,6 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
if (req_start + req_len > phys_len)
return -EINVAL;
- if (index == vdev->msix_bar) {
- /*
- * Disallow mmaps overlapping the MSI-X table; users don't
- * get to touch this directly. We could find somewhere
- * else to map the overlap, but page granularity is only
- * a recommendation, not a requirement, so the user needs
- * to know which bits are real. Requiring them to mmap
- * around the table makes that clear.
- */
-
- /* If neither entirely above nor below, then it overlaps */
- if (!(req_start >= vdev->msix_offset + vdev->msix_size ||
- req_start + req_len <= vdev->msix_offset))
- return -EINVAL;
- }
-
/*
* Even though we don't make use of the barmap for the mmap,
* we need to request the region and the barmap tracks that.
OpenPOWER on IntegriCloud