[PATCH] swiotlb: fix default_swiotlb_limit() for non-growable default pool

Marek Szyprowski posted 1 patch 2 weeks, 4 days ago
There is a newer version of this series
kernel/dma/swiotlb.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
[PATCH] swiotlb: fix default_swiotlb_limit() for non-growable default pool
Posted by Marek Szyprowski 2 weeks, 4 days ago
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 <andreas.greve@a-greve.de>
Reported-by: James Dingwall <james@dingwall.me.uk>
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) <noreply@anthropic.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 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
-- 
2.43.0
Re: [PATCH] swiotlb: fix default_swiotlb_limit() for non-growable default pool
Posted by Marek Szyprowski 2 weeks, 1 day ago
On 05.10.2026 09:05, Marek Szyprowski wrote:
> 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 <andreas.greve@a-greve.de>
> Reported-by: James Dingwall <james@dingwall.me.uk>
> 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) <noreply@anthropic.com>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>

Applied to dma-mapping-fixes with additional "Tested-by: James Dingwall"
tag, which I've received on priv.


> ---
>  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

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland