@samitouri / QOSamiQemu / commits / 877da38313

vfio/iommufd: Merge .dma_map_file() into .dma_map()

Simplify the VFIOIOMMUClass interface by removing the dma_map_file handler. Move the logic to decide between the standard virtual and file-backed mapping into the IOMMUFD backend, utilizing the MemoryRegion already passed to the dma_map handler. This removes redundant dispatch logic from the generic container layer and let backends to manage their own mapping strategies. This is similar to the vfio-user implementation. Reviewed-by: Alex Williamson <alex@shazbot.org> Link: https://lore.kernel.org/qemu-devel/20260608055758.359002-1-clg@redhat.com Signed-off-by: Cédric Le Goater <clg@redhat.com>

Cédric Le Goater committed Jun 8, 2026 at 07:57 UTC 877da3831355ee68e3476a6401bac30ae70097ee
3 files changed +37 -66
hw/vfio/container.c
-38
@@ -15,7 +15,6 @@
15 #include <linux/vfio.h>
16
17 #include "system/tcg.h"
18 -#include "system/ramblock.h"
18 #include "qapi/error.h"
19 #include "qemu/error-report.h"
20 #include "hw/vfio/vfio-container.h"
@@ -74,49 +73,12 @@ void vfio_address_space_insert(VFIOAddressSpace *space,
73 bcontainer->space = space;
74 }
75
77 -static bool vfio_container_can_dma_map_file(VFIOContainer *bcontainer,
78 - MemoryRegion *mr, int *fd)
79 -{
80 - VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
81 - RAMBlock *rb = mr->ram_block;
82 -
83 - if (!vioc->dma_map_file || !rb) {
84 - return false;
85 - }
86 -
87 - *fd = qemu_ram_get_fd(rb);
88 - if (*fd < 0) {
89 - return false;
90 - }
91 -
92 - /*
93 - * We can use IOMMU DMA mapping (IOMMU_IOAS_MAP_FILE) for :
94 - *
95 - * 1) Guest RAM blocks explicitly configured as shared (MAP_SHARED)
96 - * 2) RAM device sub-regions (MMIO BARs)
97 - *
98 - * Private RAM mappings (MAP_PRIVATE) are strictly excluded. Because
99 - * they are subject to copy-on-write (COW) anomalies, their underlying
100 - * PFNs can permanently diverge from the backing file
101 - */
102 - return qemu_ram_is_shared(rb) || memory_region_is_ram_device(mr);
103 -}
104 -
76 int vfio_container_dma_map(VFIOContainer *bcontainer,
77 hwaddr iova, uint64_t size,
78 void *vaddr, bool readonly, MemoryRegion *mr)
79 {
80 VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
110 - int mfd;
81
112 - if (vfio_container_can_dma_map_file(bcontainer, mr, &mfd)) {
113 - RAMBlock *rb = mr->ram_block;
114 - unsigned long start = vaddr - qemu_ram_get_host_addr(rb);
115 - unsigned long offset = qemu_ram_get_fd_offset(rb);
116 -
117 - return vioc->dma_map_file(bcontainer, iova, size, mfd, start + offset,
118 - readonly);
119 - }
82 g_assert(vioc->dma_map);
83 return vioc->dma_map(bcontainer, iova, size, vaddr, readonly, mr);
84 }
hw/vfio/iommufd.c
+37 -13
@@ -20,6 +20,7 @@
20 #include "trace.h"
21 #include "qapi/error.h"
22 #include "system/iommufd.h"
23 +#include "system/ramblock.h"
24 #include "hw/core/iommu.h"
25 #include "hw/core/qdev.h"
26 #include "hw/vfio/vfio-cpr.h"
@@ -35,26 +36,50 @@
36 #define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO \
37 TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio"
38
39 +static bool iommufd_cdev_can_map_file_dma(MemoryRegion *mr, int *fd)
40 +{
41 + RAMBlock *rb = mr ? mr->ram_block : NULL;
42 +
43 + if (!rb) {
44 + return false;
45 + }
46 +
47 + *fd = qemu_ram_get_fd(rb);
48 + if (*fd < 0) {
49 + return false;
50 + }
51 +
52 + /*
53 + * Use iommufd_backend_map_file_dma() (IOMMU_IOAS_MAP_FILE) for:
54 + * 1) Guest RAM blocks explicitly configured as shared (MAP_SHARED)
55 + * 2) RAM device sub-regions (MMIO BARs)
56 + *
57 + * Private RAM mappings (MAP_PRIVATE) are excluded: copy-on-write
58 + * semantics can cause their underlying PFNs to permanently diverge
59 + * from the backing file.
60 + */
61 + return qemu_ram_is_shared(rb) || memory_region_is_ram_device(mr);
62 +}
63 +
64 static int iommufd_cdev_map(const VFIOContainer *bcontainer, hwaddr iova,
65 uint64_t size, void *vaddr, bool readonly,
66 MemoryRegion *mr)
67 {
68 const VFIOIOMMUFDContainer *container = VFIO_IOMMU_IOMMUFD(bcontainer);
69 + int fd;
70
44 - return iommufd_backend_map_dma(container->be,
45 - container->ioas_id,
46 - iova, size, vaddr, readonly);
47 -}
71 + if (iommufd_cdev_can_map_file_dma(mr, &fd)) {
72 + RAMBlock *rb = mr->ram_block;
73 + unsigned long start = vaddr - qemu_ram_get_host_addr(rb);
74 + unsigned long offset = qemu_ram_get_fd_offset(rb);
75
49 -static int iommufd_cdev_map_file(const VFIOContainer *bcontainer,
50 - hwaddr iova, uint64_t size,
51 - int fd, unsigned long start, bool readonly)
52 -{
53 - const VFIOIOMMUFDContainer *container = VFIO_IOMMU_IOMMUFD(bcontainer);
76 + return iommufd_backend_map_file_dma(container->be, container->ioas_id,
77 + iova, size, fd,
78 + start + offset, readonly);
79 + }
80
55 - return iommufd_backend_map_file_dma(container->be,
56 - container->ioas_id,
57 - iova, size, fd, start, readonly);
81 + return iommufd_backend_map_dma(container->be, container->ioas_id,
82 + iova, size, vaddr, readonly);
83 }
84
85 static int iommufd_cdev_unmap(const VFIOContainer *bcontainer,
@@ -929,7 +954,6 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, const void *data)
954 VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass);
955
956 vioc->dma_map = iommufd_cdev_map;
932 - vioc->dma_map_file = iommufd_cdev_map_file;
957 vioc->dma_unmap = iommufd_cdev_unmap;
958 vioc->attach_device = iommufd_cdev_attach;
959 vioc->detach_device = iommufd_cdev_detach;
include/hw/vfio/vfio-container.h
-15
@@ -172,21 +172,6 @@ struct VFIOIOMMUClass {
172 int (*dma_map)(const VFIOContainer *bcontainer,
173 hwaddr iova, uint64_t size,
174 void *vaddr, bool readonly, MemoryRegion *mr);
175 - /**
176 - * @dma_map_file
177 - *
178 - * Map a file range for the container.
179 - *
180 - * @bcontainer: #VFIOContainer to use for map
181 - * @iova: start address to map
182 - * @size: size of the range to map
183 - * @fd: descriptor of the file to map
184 - * @start: starting file offset of the range to map
185 - * @readonly: map read only if true
186 - */
187 - int (*dma_map_file)(const VFIOContainer *bcontainer,
188 - hwaddr iova, uint64_t size,
189 - int fd, unsigned long start, bool readonly);
175 /**
176 * @dma_unmap
177 *