@samitouri / QOSamiQemu / commits / 11b9798c7b

memory: Allow RAM device regions to skip IOMMU mapping

Some RAM device regions created with memory_region_init_ram_device_ptr() are not intended to be P2P DMA targets. The VFIO listener currently treats all RAM device regions as DMA capable and attempts to map them into the IOMMU. For regions without dma-buf backing this fails and prints warnings such as: IOMMU_IOAS_MAP failed: Bad address, PCI BAR? Introduce a MemoryRegion flag (ram_device_skip_iommu_map) to mark RAM device regions that should not be IOMMU mapped, paired with memory_region_skip_iommu_map() / memory_region_set_skip_iommu_map() accessors. When the flag is set, the VFIO listener skips DMA mapping for that region. Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Eric Auger <eric.auger@redhat.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com> Message-id: 20260609112552.378999-21-skolothumtho@nvidia.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Shameer Kolothum committed Jun 9, 2026 at 12:25 UTC 11b9798c7b524762b98ea62b1c3fbc6304699784
4 files changed +38
hw/vfio/listener.c
+6
@@ -610,6 +610,12 @@ void vfio_container_region_add(VFIOContainer *bcontainer,
610 }
611 }
612
613 + if (memory_region_skip_iommu_map(section->mr)) {
614 + trace_vfio_listener_region_skip_dma_map(memory_region_name(section->mr),
615 + iova, int128_get64(llsize));
616 + return;
617 + }
618 +
619 ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize),
620 vaddr, section->readonly, section->mr);
621 if (ret) {
hw/vfio/trace-events
+1
@@ -100,6 +100,7 @@ vfio_listener_region_del_iommu(const char *name) "region_del [iommu] %s"
100 vfio_listener_region_add_ram(uint64_t iova_start, uint64_t iova_end, void *vaddr) "region_add [ram] 0x%"PRIx64" - 0x%"PRIx64" [%p]"
101 vfio_known_safe_misalignment(const char *name, uint64_t iova, uint64_t offset_within_region, uintptr_t page_size) "Region \"%s\" iova=0x%"PRIx64" offset_within_region=0x%"PRIx64" qemu_real_host_page_size=0x%"PRIxPTR
102 vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t size, uint64_t page_size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" is not aligned to 0x%"PRIx64" and cannot be mapped for DMA"
103 +vfio_listener_region_skip_dma_map(const char *name, uint64_t iova, uint64_t size) "Region \"%s\" 0x%"PRIx64" size=0x%"PRIx64" marked to skip IOMMU mapping"
104 vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64
105 vfio_device_dirty_tracking_update(uint64_t start, uint64_t end, uint64_t min, uint64_t max) "section 0x%"PRIx64" - 0x%"PRIx64" -> update [0x%"PRIx64" - 0x%"PRIx64"]"
106 vfio_device_dirty_tracking_start(int nr_ranges, uint64_t min32, uint64_t max32, uint64_t min64, uint64_t max64, uint64_t minpci, uint64_t maxpci) "nr_ranges %d 32:[0x%"PRIx64" - 0x%"PRIx64"], 64:[0x%"PRIx64" - 0x%"PRIx64"], pci64:[0x%"PRIx64" - 0x%"PRIx64"]"
include/system/memory.h
+21
@@ -864,6 +864,8 @@ struct MemoryRegion {
864
865 /* For devices designed to perform re-entrant IO into their own IO MRs */
866 bool disable_reentrancy_guard;
867 + /* RAM device region that does not require IOMMU mapping for P2P */
868 + bool ram_device_skip_iommu_map;
869 };
870
871 struct IOMMUMemoryRegion {
@@ -1743,6 +1745,25 @@ static inline bool memory_region_is_romd(const MemoryRegion *mr)
1745 */
1746 bool memory_region_is_protected(const MemoryRegion *mr);
1747
1748 +/**
1749 + * memory_region_skip_iommu_map: check whether a memory region is excluded
1750 + * from IOMMU mapping
1751 + *
1752 + * Returns %true if @mr is a RAM device region marked to skip IOMMU mapping.
1753 + *
1754 + * @mr: the memory region being queried
1755 + */
1756 +bool memory_region_skip_iommu_map(const MemoryRegion *mr);
1757 +
1758 +/**
1759 + * memory_region_set_skip_iommu_map: mark a RAM device region to skip IOMMU
1760 + * mapping
1761 + *
1762 + * @mr: the memory region being modified
1763 + * @skip: %true to skip IOMMU mapping, %false to allow it
1764 + */
1765 +void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip);
1766 +
1767 /**
1768 * memory_region_has_guest_memfd: check whether a memory region has guest_memfd
1769 * associated
system/memory.c
+10
@@ -1814,6 +1814,16 @@ bool memory_region_is_protected(const MemoryRegion *mr)
1814 return mr->ram && (mr->ram_block->flags & RAM_PROTECTED);
1815 }
1816
1817 +bool memory_region_skip_iommu_map(const MemoryRegion *mr)
1818 +{
1819 + return memory_region_is_ram_device(mr) && mr->ram_device_skip_iommu_map;
1820 +}
1821 +
1822 +void memory_region_set_skip_iommu_map(MemoryRegion *mr, bool skip)
1823 +{
1824 + mr->ram_device_skip_iommu_map = skip;
1825 +}
1826 +
1827 bool memory_region_has_guest_memfd(const MemoryRegion *mr)
1828 {
1829 return mr->ram_block && mr->ram_block->guest_memfd >= 0;