add mmap maple tree for vfio_device_file, this allows vfio devices to create per mmap request options. the vfio device needs to insert/allocate the region range offset & size and make it accessible for the user, probably when the user is calling DEVICE_GET_REGION_INFO, and then vfio uses the maple_tree to find the entry (vfio_mmap) needed for mmap op, this adds the vfio_mmap_init & vfio_mmap_free for initialization and freeing the entry, the freeing is done through the free callback in the vfio_mmap_ops, which vfio_devices should implement if they are allocating an entry. Signed-off-by: Mahmoud Adam --- I didn't find a situation where we would need to use ref counting for now, so I didn't implement it, I think most cases are already handled by file ref counting, but maybe I'm overlooking something here. drivers/vfio/vfio.h | 1 + drivers/vfio/vfio_main.c | 29 +++++++++++++++++++++++++++++ include/linux/vfio.h | 17 +++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/drivers/vfio/vfio.h b/drivers/vfio/vfio.h index 50128da18bcaf..3f0cf2dd41116 100644 --- a/drivers/vfio/vfio.h +++ b/drivers/vfio/vfio.h @@ -19,6 +19,7 @@ struct vfio_container; struct vfio_device_file { struct vfio_device *device; struct vfio_group *group; + struct maple_tree mmap_mt; u8 access_granted; u32 devid; /* only valid when iommufd is valid */ diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index 1fd261efc582d..4c4af4de60d12 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "vfio.h" #define DRIVER_VERSION "0.3" @@ -498,6 +499,7 @@ vfio_allocate_device_file(struct vfio_device *device) df->device = device; spin_lock_init(&df->kvm_ref_lock); + mt_init_flags(&df->mmap_mt, MT_FLAGS_ALLOC_RANGE); return df; } @@ -622,6 +624,25 @@ static inline void vfio_device_pm_runtime_put(struct vfio_device *device) pm_runtime_put(dev); } +void vfio_mmap_init(struct vfio_device *vdev, struct vfio_mmap *vmmap, + u32 region_flags, u64 offset, u64 size, + struct vfio_mmap_ops *ops) +{ + vmmap->owner = vdev; + vmmap->offset = offset; + vmmap->ops = ops; + vmmap->size = size; + vmmap->region_flags = region_flags; +} +EXPORT_SYMBOL_GPL(vfio_mmap_init); + +void vfio_mmap_free(struct vfio_mmap *vmmap) +{ + if (vmmap->ops && vmmap->ops->free) + vmmap->ops->free(vmmap); +} +EXPORT_SYMBOL_GPL(vfio_mmap_free); + /* * VFIO Device fd */ @@ -629,14 +650,22 @@ static int vfio_device_fops_release(struct inode *inode, struct file *filep) { struct vfio_device_file *df = filep->private_data; struct vfio_device *device = df->device; + struct vfio_mmap *vmmap; + unsigned long index = 0; if (df->group) vfio_df_group_close(df); else vfio_df_unbind_iommufd(df); + mt_for_each(&df->mmap_mt, vmmap, index, ULONG_MAX) { + mtree_erase(&df->mmap_mt, index); + vfio_mmap_free(vmmap); + } + vfio_device_put_registration(device); + mtree_destroy(&df->mmap_mt); kfree(df); return 0; diff --git a/include/linux/vfio.h b/include/linux/vfio.h index 707b00772ce1f..6e0aca05aa406 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -80,6 +80,19 @@ struct vfio_device { #endif }; +struct vfio_mmap { + struct vfio_device *owner; + u64 offset; + u64 size; + u32 region_flags; + struct vfio_mmap_ops *ops; +}; + +struct vfio_mmap_ops { + void (*free)(struct vfio_mmap *vmmap); +}; + + /** * struct vfio_device_ops - VFIO bus driver device callbacks * @@ -338,6 +351,10 @@ int vfio_pin_pages(struct vfio_device *device, dma_addr_t iova, void vfio_unpin_pages(struct vfio_device *device, dma_addr_t iova, int npage); int vfio_dma_rw(struct vfio_device *device, dma_addr_t iova, void *data, size_t len, bool write); +void vfio_mmap_init(struct vfio_device *vdev, struct vfio_mmap *vmmap, + u32 region_flags, u64 offset, u64 size, + struct vfio_mmap_ops *ops); +void vfio_mmap_free(struct vfio_mmap *vmmap); /* * Sub-module helpers -- 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