include/hw/vfio/vfio-container.h | 15 ---------- hw/vfio/container.c | 38 ------------------------ hw/vfio/iommufd.c | 50 +++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 66 deletions(-)
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.
Signed-off-by: Cédric Le Goater <clg@redhat.com>
---
include/hw/vfio/vfio-container.h | 15 ----------
hw/vfio/container.c | 38 ------------------------
hw/vfio/iommufd.c | 50 +++++++++++++++++++++++---------
3 files changed, 37 insertions(+), 66 deletions(-)
diff --git a/include/hw/vfio/vfio-container.h b/include/hw/vfio/vfio-container.h
index a7d5c5ed679a0338937ae02f37140d94720f6f11..c70828a0529cb2b41162a8bd452da1d9c20bc08f 100644
--- a/include/hw/vfio/vfio-container.h
+++ b/include/hw/vfio/vfio-container.h
@@ -172,21 +172,6 @@ struct VFIOIOMMUClass {
int (*dma_map)(const VFIOContainer *bcontainer,
hwaddr iova, uint64_t size,
void *vaddr, bool readonly, MemoryRegion *mr);
- /**
- * @dma_map_file
- *
- * Map a file range for the container.
- *
- * @bcontainer: #VFIOContainer to use for map
- * @iova: start address to map
- * @size: size of the range to map
- * @fd: descriptor of the file to map
- * @start: starting file offset of the range to map
- * @readonly: map read only if true
- */
- int (*dma_map_file)(const VFIOContainer *bcontainer,
- hwaddr iova, uint64_t size,
- int fd, unsigned long start, bool readonly);
/**
* @dma_unmap
*
diff --git a/hw/vfio/container.c b/hw/vfio/container.c
index 56bd9ac0095df7b0f4da85f1d8dcb8d571fa9f2a..d09a6637324c6bf29b2fe22369082f87e280c98f 100644
--- a/hw/vfio/container.c
+++ b/hw/vfio/container.c
@@ -15,7 +15,6 @@
#include <linux/vfio.h>
#include "system/tcg.h"
-#include "system/ramblock.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "hw/vfio/vfio-container.h"
@@ -74,49 +73,12 @@ void vfio_address_space_insert(VFIOAddressSpace *space,
bcontainer->space = space;
}
-static bool vfio_container_can_dma_map_file(VFIOContainer *bcontainer,
- MemoryRegion *mr, int *fd)
-{
- VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
- RAMBlock *rb = mr->ram_block;
-
- if (!vioc->dma_map_file || !rb) {
- return false;
- }
-
- *fd = qemu_ram_get_fd(rb);
- if (*fd < 0) {
- return false;
- }
-
- /*
- * We can use IOMMU DMA mapping (IOMMU_IOAS_MAP_FILE) for :
- *
- * 1) Guest RAM blocks explicitly configured as shared (MAP_SHARED)
- * 2) RAM device sub-regions (MMIO BARs)
- *
- * Private RAM mappings (MAP_PRIVATE) are strictly excluded. Because
- * they are subject to copy-on-write (COW) anomalies, their underlying
- * PFNs can permanently diverge from the backing file
- */
- return qemu_ram_is_shared(rb) || memory_region_is_ram_device(mr);
-}
-
int vfio_container_dma_map(VFIOContainer *bcontainer,
hwaddr iova, uint64_t size,
void *vaddr, bool readonly, MemoryRegion *mr)
{
VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer);
- int mfd;
- if (vfio_container_can_dma_map_file(bcontainer, mr, &mfd)) {
- RAMBlock *rb = mr->ram_block;
- unsigned long start = vaddr - qemu_ram_get_host_addr(rb);
- unsigned long offset = qemu_ram_get_fd_offset(rb);
-
- return vioc->dma_map_file(bcontainer, iova, size, mfd, start + offset,
- readonly);
- }
g_assert(vioc->dma_map);
return vioc->dma_map(bcontainer, iova, size, vaddr, readonly, mr);
}
diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c
index 68f2ae6f9f667bb05c20e452e8c5b43da6558098..6ff668d2597e07c6953cf0f1997514aec199642c 100644
--- a/hw/vfio/iommufd.c
+++ b/hw/vfio/iommufd.c
@@ -20,6 +20,7 @@
#include "trace.h"
#include "qapi/error.h"
#include "system/iommufd.h"
+#include "system/ramblock.h"
#include "hw/core/iommu.h"
#include "hw/core/qdev.h"
#include "hw/vfio/vfio-cpr.h"
@@ -35,26 +36,50 @@
#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO \
TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio"
+static bool iommufd_cdev_can_map_file_dma(MemoryRegion *mr, int *fd)
+{
+ RAMBlock *rb = mr ? mr->ram_block : NULL;
+
+ if (!rb) {
+ return false;
+ }
+
+ *fd = qemu_ram_get_fd(rb);
+ if (*fd < 0) {
+ return false;
+ }
+
+ /*
+ * Use iommufd_backend_map_file_dma() (IOMMU_IOAS_MAP_FILE) for:
+ * 1) Guest RAM blocks explicitly configured as shared (MAP_SHARED)
+ * 2) RAM device sub-regions (MMIO BARs)
+ *
+ * Private RAM mappings (MAP_PRIVATE) are excluded: copy-on-write
+ * semantics can cause their underlying PFNs to permanently diverge
+ * from the backing file.
+ */
+ return qemu_ram_is_shared(rb) || memory_region_is_ram_device(mr);
+}
+
static int iommufd_cdev_map(const VFIOContainer *bcontainer, hwaddr iova,
uint64_t size, void *vaddr, bool readonly,
MemoryRegion *mr)
{
const VFIOIOMMUFDContainer *container = VFIO_IOMMU_IOMMUFD(bcontainer);
+ int fd;
- return iommufd_backend_map_dma(container->be,
- container->ioas_id,
- iova, size, vaddr, readonly);
-}
+ if (iommufd_cdev_can_map_file_dma(mr, &fd)) {
+ RAMBlock *rb = mr->ram_block;
+ unsigned long start = vaddr - qemu_ram_get_host_addr(rb);
+ unsigned long offset = qemu_ram_get_fd_offset(rb);
-static int iommufd_cdev_map_file(const VFIOContainer *bcontainer,
- hwaddr iova, uint64_t size,
- int fd, unsigned long start, bool readonly)
-{
- const VFIOIOMMUFDContainer *container = VFIO_IOMMU_IOMMUFD(bcontainer);
+ return iommufd_backend_map_file_dma(container->be, container->ioas_id,
+ iova, size, fd,
+ start + offset, readonly);
+ }
- return iommufd_backend_map_file_dma(container->be,
- container->ioas_id,
- iova, size, fd, start, readonly);
+ return iommufd_backend_map_dma(container->be, container->ioas_id,
+ iova, size, vaddr, readonly);
}
static int iommufd_cdev_unmap(const VFIOContainer *bcontainer,
@@ -929,7 +954,6 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, const void *data)
VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass);
vioc->dma_map = iommufd_cdev_map;
- vioc->dma_map_file = iommufd_cdev_map_file;
vioc->dma_unmap = iommufd_cdev_unmap;
vioc->attach_device = iommufd_cdev_attach;
vioc->detach_device = iommufd_cdev_detach;
--
2.54.0
© 2016 - 2026 Red Hat, Inc.