From 057e5e07420c753f248f9ce148040ab6dcf8359f Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 16 Sep 2026 23:23:33 +0800 Subject: [PATCH 1/2] iommu/dma: skip swiotlb bounce for DMA_ATTR_MMIO in iommu_dma_map_phys MMIO resources mapped via dma_map_resource() carry DMA_ATTR_MMIO. These never need swiotlb bounce buffering, but the current code enters the swiotlb path when the physical address is not page-aligned, then rejects the mapping because MMIO cannot be bounced. Move the DMA_ATTR_MMIO check before the swiotlb block so the entire bounce path is skipped for MMIO, falling through directly to __iommu_dma_map() which creates the IOVA mapping. Fixes: f9374de14c0e8 ("iommu/dma: implement DMA_ATTR_MMIO for iommu_dma_(un)map_phys()") Assisted-by: Claude:claude-opus-4-6 Signed-off-by: Peng Fan Acked-by: Robin Murphy Link: https://lore.kernel.org/r/20260916-iommu-dma-fix-v1-1-a59a0c45ec5b@nxp.com Signed-off-by: Marek Szyprowski --- drivers/iommu/dma-iommu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 58c624513cd4..68ee57800fef 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -1228,9 +1228,9 @@ dma_addr_t iommu_dma_map_phys(struct device *dev, phys_addr_t phys, size_t size, * If both the physical buffer start address and size are page aligned, * we don't need to use a bounce page. */ - if (dev_use_swiotlb(dev, size, dir) && + if (!(attrs & DMA_ATTR_MMIO) && dev_use_swiotlb(dev, size, dir) && iova_unaligned(iovad, phys, size)) { - if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT)) + if (attrs & DMA_ATTR_REQUIRE_COHERENT) return DMA_MAPPING_ERROR; phys = iommu_dma_map_swiotlb(dev, phys, size, dir, attrs); From 911655ab1dfb9d526978a75df3b210132620d30a Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Wed, 30 Sep 2026 10:50:55 +0200 Subject: [PATCH 2/2] swiotlb: fix default_swiotlb_limit() for non-growable default pool Commit ad96ce3252db ("swiotlb: determine potential physical address limit") changed default_swiotlb_limit() to return the maximum physical address that could ever be used by dynamically allocated pools, so that the value stays constant when CONFIG_SWIOTLB_DYNAMIC=y. However, io_tlb_default_mem.phys_limit is returned even when the default pool cannot grow, e.g. when swiotlb_init_remap() is called with a remap callback. This breaks Xen dom0 on x86: pci_xen_swiotlb_init() passes SWIOTLB_ANY and xen_swiotlb_fixup(), so phys_limit is set to the top of dom0 memory, although xen_swiotlb_fixup() makes the default pool below the 32-bit boundary. xen_swiotlb_dma_supported() then rejects 32-bit DMA masks, even though the bounce buffer is perfectly usable by such devices. Return phys_limit only if the default pool can actually grow, otherwise report the real end of the default pool, like in the !CONFIG_SWIOTLB_DYNAMIC case. Reported-by: Andreas Greve Reported-by: James Dingwall Fixes: ad96ce3252db ("swiotlb: determine potential physical address limit") Closes: https://lore.kernel.org/xen-devel/f74668db-52fd-4575-8372-7bfdf10d62ac@a-greve.de/ Cc: stable@vger.kernel.org Assisted-by: Claude Opus 5.5 (1M context) Tested-by: James Dingwall Link: https://lore.kernel.org/all/20261005070518.1590097-1-m.szyprowski@samsung.com/ Signed-off-by: Marek Szyprowski --- kernel/dma/swiotlb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index aa2f1c4588b9..5edea93ec635 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -1844,10 +1844,10 @@ phys_addr_t default_swiotlb_base(void) phys_addr_t default_swiotlb_limit(void) { #ifdef CONFIG_SWIOTLB_DYNAMIC - return io_tlb_default_mem.phys_limit; -#else - return io_tlb_default_mem.defpool.end - 1; + if (io_tlb_default_mem.can_grow) + return io_tlb_default_mem.phys_limit; #endif + return io_tlb_default_mem.defpool.end - 1; } #ifdef CONFIG_DEBUG_FS