[PATCH v2 3/4] vfio: Introduce vfio_device_ops.get_mapping_order hook

Peter Xu
2025-12-04T15:10:20Z

Add a hook to vfio_device_ops to allow sub-modules provide mapping order
hint for an mmap() request. When not available, use the default value (0).

Note that this patch will change the code path for vfio on mmap() when
allocating the virtual address range to be mapped, however it should not
change the result of the VA allocated, because the default value (0) should
be the old behavior.

Signed-off-by: Peter Xu <peterx@redhat.com>
---
drivers/vfio/vfio_main.c | 14 ++++++++++++++
include/linux/vfio.h | 5 +++++
2 files changed, 19 insertions(+)

diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 38c8e9350a60e..3f2107ff93e5d 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -1372,6 +1372,19 @@ static void vfio_device_show_fdinfo(struct seq_file *m, struct file *filep)
}
#endif

+static int vfio_device_get_mapping_order(struct file *file,
+ unsigned long pgoff,
+ size_t len)
+{
+ struct vfio_device_file *df = file->private_data;
+ struct vfio_device *device = df->device;
+
+ if (device->ops->get_mapping_order)
+ return device->ops->get_mapping_order(device, pgoff, len);
+
+ return 0;
+}
+
const struct file_operations vfio_device_fops = {
.owner = THIS_MODULE,
.open = vfio_device_fops_cdev_open,
@@ -1384,6 +1397,7 @@ const struct file_operations vfio_device_fops = {
#ifdef CONFIG_PROC_FS
.show_fdinfo = vfio_device_show_fdinfo,
#endif
+ .get_mapping_order = vfio_device_get_mapping_order,
};

static struct vfio_device *vfio_device_from_file(struct file *file)
diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index eb563f538dee5..46a4d85fc4953 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -111,6 +111,8 @@ struct vfio_device {
* @dma_unmap: Called when userspace unmaps IOVA from the container
* this device is attached to.
* @device_feature: Optional, fill in the VFIO_DEVICE_FEATURE ioctl
+ * @get_mapping_order: Optional, provide mapping order hints for mmap().
+ * When unavailable, use the default order (zero).
*/
struct vfio_device_ops {
char *name;
@@ -139,6 +141,9 @@ struct vfio_device_ops {
void (*dma_unmap)(struct vfio_device *vdev, u64 iova, u64 length);
int (*device_feature)(struct vfio_device *device, u32 flags,
void __user *arg, size_t argsz);
+ int (*get_mapping_order)(struct vfio_device *device,
+ unsigned long pgoff,
+ size_t len);
};

#if IS_ENABLED(CONFIG_IOMMUFD)
--
2.50.1