[PATCH RFC v3 62/88] vfio: Dispatch guest_memfd check_set_attributes via vfio_device_ops

From: Ackerley Tng via B4 Relay

Date: Fri Nov 06 2026 - 20:08:19 EST


From: Ackerley Tng <ackerleytng@xxxxxxxxxx>

When userspace requests attribute conversion on a guest_memfd file
backed by a VFIO resource descriptor, guest_memfd invokes the
.check_set_attributes provider operation under the exclusive filemap
invalidation lock before committing attribute changes.

Implement .check_set_attributes on vfio_device_gmem_provider_ops to
dispatch to the bus driver's .gmem_check_set_attributes callback on
struct vfio_device_ops if implemented, allowing the driver to inspect
and validate the requested attributes and offset range.

Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
---
drivers/vfio/vfio_main.c | 24 ++++++++++++++++++++----
include/linux/vfio.h | 3 +++
2 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
index 979ed69c5ebf7..e4e7bfe77d03b 100644
--- a/drivers/vfio/vfio_main.c
+++ b/drivers/vfio/vfio_main.c
@@ -1621,11 +1621,27 @@ static int vfio_device_gmem_mmap(void *provider, struct vm_area_struct *vma)
return vfio_device_mmap(df->device, vma);
}

+static int vfio_device_gmem_check_set_attributes(void *provider, pgoff_t index,
+ size_t nr_pages,
+ u64 attributes)
+{
+ struct file *file = provider;
+ struct vfio_device_file *df = file->private_data;
+ struct vfio_device *device = df->device;
+
+ if (!device->ops->gmem_check_set_attributes)
+ return 0;
+
+ return device->ops->gmem_check_set_attributes(device, index, nr_pages,
+ attributes);
+}
+
static const struct guest_memfd_provider_operations vfio_device_gmem_provider_ops = {
- .attach = vfio_device_gmem_attach,
- .release = vfio_device_gmem_release,
- .get_pfn = vfio_device_gmem_get_pfn,
- .mmap = vfio_device_gmem_mmap,
+ .attach = vfio_device_gmem_attach,
+ .release = vfio_device_gmem_release,
+ .get_pfn = vfio_device_gmem_get_pfn,
+ .mmap = vfio_device_gmem_mmap,
+ .check_set_attributes = vfio_device_gmem_check_set_attributes,
};
#endif

diff --git a/include/linux/vfio.h b/include/linux/vfio.h
index 51e04b980a381..ffb01e655735f 100644
--- a/include/linux/vfio.h
+++ b/include/linux/vfio.h
@@ -125,6 +125,9 @@ struct vfio_device_ops {
int (*gmem_get_pfn)(struct vfio_device *device, pgoff_t index,
unsigned long *pfn, int *max_order,
u64 *pfn_attrs);
+ int (*gmem_check_set_attributes)(struct vfio_device *device,
+ pgoff_t index, size_t nr_pages,
+ u64 attributes);
char *name;
int (*init)(struct vfio_device *vdev);
void (*release)(struct vfio_device *vdev);

--
2.56.0.455.g6c5a503b38-goog