Add a setup_sparse_mmaps callback to VFIODeviceIOOps so transport backends (such as vfio-user) can parse custom sparse mmap capabilities, falling back to vfio_default_setup_sparse_mmaps() to process shared VFIO mmap capabilities.
Signed-off-by: Naman Gulati <[email protected]> --- hw/vfio/vfio-region.h | 5 +++++ include/hw/vfio/vfio-device.h | 16 ++++++++++++++++ hw/vfio/region.c | 25 ++++++++++++++++++++++--- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/hw/vfio/vfio-region.h b/hw/vfio/vfio-region.h index 9f6a5cf7d5..a0c9533f9f 100644 --- a/hw/vfio/vfio-region.h +++ b/hw/vfio/vfio-region.h @@ -46,4 +46,9 @@ void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); void vfio_region_exit(VFIORegion *region); void vfio_region_finalize(VFIORegion *region); +struct vfio_region_info; +int vfio_default_setup_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp); + #endif /* HW_VFIO_REGION_H */ diff --git a/include/hw/vfio/vfio-device.h b/include/hw/vfio/vfio-device.h index 8472420d3f..3136e152f2 100644 --- a/include/hw/vfio/vfio-device.h +++ b/include/hw/vfio/vfio-device.h @@ -43,6 +43,7 @@ enum { typedef struct VFIODeviceOps VFIODeviceOps; typedef struct VFIODeviceIOOps VFIODeviceIOOps; +typedef struct VFIORegion VFIORegion; typedef struct VFIOMigration VFIOMigration; typedef struct IOMMUFDBackend IOMMUFDBackend; @@ -218,6 +219,21 @@ struct VFIODeviceIOOps { int (*get_region_info)(VFIODevice *vdev, struct vfio_region_info *info, int *fd); + /** + * @setup_sparse_mmaps + * + * Parse sparse mmap capabilities for a region and initialize region->mmaps. + * + * @region: #VFIORegion to set up + * @info: region info struct containing capabilities + * @errp: pointer to Error*, to store an error if it happens + * + * Returns 0 on success, -ENODEV if not sparse, or negative error code. + */ + int (*setup_sparse_mmaps)(VFIORegion *region, + struct vfio_region_info *info, + Error **errp); + /** * @get_irq_info * diff --git a/hw/vfio/region.c b/hw/vfio/region.c index 3c746200ca..3525f4183f 100644 --- a/hw/vfio/region.c +++ b/hw/vfio/region.c @@ -162,9 +162,9 @@ static int vfio_mmap_compare_offset(const void *a, const void *b) return 0; } -static int vfio_setup_region_sparse_mmaps(VFIORegion *region, - struct vfio_region_info *info, - Error **errp) +int vfio_default_setup_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp) { struct vfio_info_cap_header *hdr; struct vfio_region_info_cap_sparse_mmap *sparse; @@ -198,6 +198,25 @@ static int vfio_setup_region_sparse_mmaps(VFIORegion *region, region->nr_mmaps = j; region->mmaps = g_realloc(region->mmaps, j * sizeof(VFIOMmap)); + return 0; +} + +static int vfio_setup_region_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info, + Error **errp) +{ + int ret, i; + + if (region->vbasedev->io_ops && + region->vbasedev->io_ops->setup_sparse_mmaps) { + ret = region->vbasedev->io_ops->setup_sparse_mmaps(region, info, errp); + } else { + ret = vfio_default_setup_sparse_mmaps(region, info, errp); + } + + if (ret) { + return ret; + } /* * Sort sparse mmaps by offset to ensure proper handling of gaps -- 2.55.0.1082.g2b9226bbc0-goog
