support the new vmmap solution to vfio-pci-core, this adds the vfio_pci_mmap struct. the core already keeps the offset and size of the region, extend it with bar_index. Add alloc helper funciton for vfio_pci, which allocates and insert vmmap to the mt, for the transitioning period the mtree_insert_range is used with the same offset calculation as the legacy solution, so that we don't break VFIO_PCI_OFFSET_TO_INDEX usages, eventually after all the vfio_pci_devices are migrated to the new ops, these macros will be replaced with mtree_load or similar, then maple tree allocation could be used instead of direct insertions. Signed-off-by: Mahmoud Adam --- drivers/vfio/pci/vfio_pci_core.c | 44 ++++++++++++++++++++++++++++++++ include/linux/vfio_pci_core.h | 10 ++++++++ 2 files changed, 54 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 467466a0b619f..7a431a03bd850 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -882,6 +882,50 @@ static int msix_mmappable_cap(struct vfio_pci_core_device *vdev, return vfio_info_add_capability(caps, &header, sizeof(header)); } +static void vfio_pci_mmap_free(struct vfio_mmap *core_vmmap) +{ + struct vfio_pci_mmap *vmmap = container_of(core_vmmap, + struct vfio_pci_mmap, + core); + kfree(vmmap); +} + +static struct vfio_mmap_ops vfio_pci_mmap_ops = { + .free = vfio_pci_mmap_free, +}; + +int vfio_pci_mmap_alloc(struct vfio_pci_core_device *vdev, + struct maple_tree *mmap_mt, u32 region_flags, + size_t bar_size, unsigned int bar_index, + unsigned long *offset) +{ + struct vfio_pci_mmap *vmmap; + int ret; + unsigned long alloc_size; + vmmap = kzalloc(sizeof(*vmmap), GFP_KERNEL); + if (!vmmap) + return -ENOMEM; + + alloc_size = PAGE_ALIGN(bar_size); + /* keep the offset aligned to the current usage for now, so we + * don't break VFIO_PCI_OFFSET_TO_INDEX */ + *offset = VFIO_PCI_INDEX_TO_OFFSET(bar_index); + vmmap->bar_index = bar_index; + vfio_mmap_init(&vdev->vdev, &vmmap->core, region_flags, + *offset, alloc_size, &vfio_pci_mmap_ops); + ret = mtree_insert_range(mmap_mt, *offset, + *offset + alloc_size - 1, + &vmmap->core, GFP_KERNEL); + if (ret) { + vfio_mmap_free(&vmmap->core); + /* for now if it exists reuse it */ + if (ret != -EEXIST) + return ret; + } + return 0; +} +EXPORT_SYMBOL(vfio_pci_mmap_alloc); + int vfio_pci_core_register_dev_region(struct vfio_pci_core_device *vdev, unsigned int type, unsigned int subtype, const struct vfio_pci_regops *ops, diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h index fbb472dd99b36..532d2914a9c2e 100644 --- a/include/linux/vfio_pci_core.h +++ b/include/linux/vfio_pci_core.h @@ -49,6 +49,11 @@ struct vfio_pci_region { u32 flags; }; +struct vfio_pci_mmap { + struct vfio_mmap core; + unsigned int bar_index; +}; + struct vfio_pci_core_device { struct vfio_device vdev; struct pci_dev *pdev; @@ -137,6 +142,11 @@ bool vfio_pci_core_range_intersect_range(loff_t buf_start, size_t buf_cnt, loff_t *buf_offset, size_t *intersect_count, size_t *register_offset); +int vfio_pci_mmap_alloc(struct vfio_pci_core_device *vdev, + struct maple_tree *mmap_mt, u32 region_flags, + size_t bar_size, unsigned int bar_index, + unsigned long *offset); + #define VFIO_IOWRITE_DECLARATION(size) \ int vfio_pci_core_iowrite##size(struct vfio_pci_core_device *vdev, \ bool test_mem, u##size val, void __iomem *io); -- 2.47.3 Amazon Web Services Development Center Germany GmbH Tamara-Danz-Str. 13 10243 Berlin Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B Sitz: Berlin Ust-ID: DE 365 538 597