mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/5] dma-mapping: assorted sashiko.dev fixes
       [not found] <CGME20261026095434eucas1p29408e916eda327a5e9c83f64b0df4e66@eucas1p2.samsung.com>
@ 2026-10-26  9:54 ` Marek Szyprowski
       [not found]   ` <CGME20261026095434eucas1p1bb0ac7f1e94bcac196fdc97a0f2c9e9f@eucas1p1.samsung.com>
                     ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-10-26  9:54 UTC (permalink / raw)
  To: iommu, linux-kernel
  Cc: Marek Szyprowski, Robin Murphy, Andrew Morton,
	Konrad Rzeszutek Wilk, Claire Chang, Petr Tesarik,
	Nicolas Saenz Julienne, Christoph Hellwig, Lucas Stach

Hi,

This series collects fixes for the DMA-mapping code, developed while
analyzing issues reported by the sashiko.dev automated review. All
patches were prepared with LLM assistance and then reviewed manually.

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


Marek Szyprowski (5):
  dma-coherent: serialize reserved memory pool initialization
  dma: swiotlb: Serialize restricted DMA pool initialization
  dma: swiotlb: Remove default pool from the pools list on exit
  dma-pool: release CMA pages on atomic_pool_expand() error path
  dma-direct: zero memory allocated with DMA_ATTR_NO_KERNEL_MAPPING

 kernel/dma/coherent.c | 11 ++++++++++-
 kernel/dma/direct.c   |  3 ++-
 kernel/dma/pool.c     |  3 ++-
 kernel/dma/swiotlb.c  | 15 +++++++++++++--
 4 files changed, 27 insertions(+), 5 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] dma-coherent: serialize reserved memory pool initialization
       [not found]   ` <CGME20261026095434eucas1p1bb0ac7f1e94bcac196fdc97a0f2c9e9f@eucas1p1.samsung.com>
@ 2026-10-26  9:54     ` Marek Szyprowski
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-10-26  9:54 UTC (permalink / raw)
  To: iommu, linux-kernel; +Cc: Marek Szyprowski, Robin Murphy, Andrew Morton, stable

Multiple devices can share the same "shared-dma-pool" reserved memory
region, in which case the dma_coherent_mem structure is created by the
first device attached to it and stored in rmem->priv. To avoid the
potential race, serialize the check and initialization of rmem->priv
with a mutex.

Fixes: 7bfa5ab6fa1b ("drivers: dma-coherent: add initialization from device tree")
Cc: stable@vger.kernel.org
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 kernel/dma/coherent.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 4d0266893bcc..ac62b6bd3d0d 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -7,6 +7,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/dma-direct.h>
 #include <linux/dma-map-ops.h>
 
@@ -335,10 +336,18 @@ static phys_addr_t dma_reserved_default_memory_base __initdata;
 static phys_addr_t dma_reserved_default_memory_size __initdata;
 #endif
 
+static DEFINE_MUTEX(rmem_dma_mutex);
+
 static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
 {
-	struct dma_coherent_mem *mem = rmem->priv;
+	struct dma_coherent_mem *mem;
 
+	/*
+	 * Multiple devices can share the same pool and may be probed
+	 * concurrently, so serialize the initialization of rmem->priv.
+	 */
+	guard(mutex)(&rmem_dma_mutex);
+	mem = rmem->priv;
 	if (!mem) {
 		mem = dma_init_coherent_memory(rmem->base, rmem->base,
 					       rmem->size, true);
-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/5] dma: swiotlb: Serialize restricted DMA pool initialization
       [not found]   ` <CGME20261026095435eucas1p1f2245a6982ef110340685dc66be53590@eucas1p1.samsung.com>
@ 2026-10-26  9:54     ` Marek Szyprowski
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-10-26  9:54 UTC (permalink / raw)
  To: iommu, linux-kernel
  Cc: Marek Szyprowski, Robin Murphy, Konrad Rzeszutek Wilk,
	Claire Chang, stable

Multiple devices can share the same restricted DMA pool, in which case
the io_tlb_mem structure is allocated and initialized by the first
device attached to it and stored in rmem->priv. To avoid the potential
race, serialize the check and initialization of rmem->priv with a mutex.

Fixes: 0b84e4f8b793 ("swiotlb: Add restricted DMA pool initialization")
Closes: https://sashiko.dev/#/bug/linux-6fda7589-591d-4a68-b6e1-b1561f867319
Cc: stable@vger.kernel.org
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 kernel/dma/swiotlb.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 2c57b49ac7c0..db731f7891b7 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/memblock.h>
 #include <linux/mm.h>
+#include <linux/mutex.h>
 #include <linux/pfn.h>
 #include <linux/rculist.h>
 #include <linux/scatterlist.h>
@@ -1986,10 +1987,12 @@ void swiotlb_free_from_pool(struct device *dev,
 	swiotlb_release_slots(dev, tlb_addr, pool);
 }
 
+static DEFINE_MUTEX(rmem_swiotlb_mutex);
+
 static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
 				    struct device *dev)
 {
-	struct io_tlb_mem *mem = rmem->priv;
+	struct io_tlb_mem *mem;
 	unsigned long nslabs = rmem->size >> IO_TLB_SHIFT;
 
 	/* Set Per-device io tlb area to one */
@@ -2003,8 +2006,10 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
 	/*
 	 * Since multiple devices can share the same pool, the private data,
 	 * io_tlb_mem struct, will be initialized by the first device attached
-	 * to it.
+	 * to it. Serialize this, as devices may be probed concurrently.
 	 */
+	guard(mutex)(&rmem_swiotlb_mutex);
+	mem = rmem->priv;
 	if (!mem) {
 		struct io_tlb_pool *pool;
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/5] dma: swiotlb: Remove default pool from the pools list on exit
       [not found]   ` <CGME20261026095435eucas1p129baa137891d2e9f5408b47afd6c556c@eucas1p1.samsung.com>
@ 2026-10-26  9:54     ` Marek Szyprowski
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-10-26  9:54 UTC (permalink / raw)
  To: iommu, linux-kernel; +Cc: Marek Szyprowski, Robin Murphy, Petr Tesarik, stable

With CONFIG_SWIOTLB_DYNAMIC enabled, the default memory pool is added to
the io_tlb_default_mem.pools RCU list during initialization. When an IOMMU
takes over DMA translation, swiotlb_exit() tears the default pool down and
clears it with memset(), but leaves its node on the pools list. The list
then contains a zeroed entry with a NULL next pointer, and any later walk
of the list, for example mem_used() when reading the io_tlb_used debugfs
file, dereferences an invalid pointer and crashes.

Remove the default pool from the list before freeing it, and wait for an
RCU grace period before clearing it, so that no reader can still see it.

Fixes: 1aaa736815eb ("swiotlb: allocate a new memory pool when existing pools are full")
Closes: https://sashiko.dev/#/bug/linux-f75998aa-65ea-4596-9bb4-fa83773012a3
Cc: stable@vger.kernel.org
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 kernel/dma/swiotlb.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index db731f7891b7..51fb2d34f6f2 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -665,6 +665,12 @@ void __init swiotlb_exit(void)
 		return;
 
 	pr_info("tearing down default memory pool\n");
+#ifdef CONFIG_SWIOTLB_DYNAMIC
+	spin_lock(&io_tlb_default_mem.lock);
+	list_del_rcu(&mem->node);
+	spin_unlock(&io_tlb_default_mem.lock);
+	synchronize_rcu();
+#endif
 	tbl_vaddr = (unsigned long)phys_to_virt(mem->start);
 	tbl_size = PAGE_ALIGN(mem->end - mem->start);
 	slots_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), mem->nslabs));
-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/5] dma-pool: release CMA pages on atomic_pool_expand() error path
       [not found]   ` <CGME20261026095436eucas1p295baef3daff27873165c70d6d578c1b6@eucas1p2.samsung.com>
@ 2026-10-26  9:54     ` Marek Szyprowski
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-10-26  9:54 UTC (permalink / raw)
  To: iommu, linux-kernel
  Cc: Marek Szyprowski, Robin Murphy, Nicolas Saenz Julienne, stable

atomic_pool_expand() may allocate the pool backing pages from CMA via
dma_alloc_from_contiguous(), but the error path unconditionally frees
them with __free_pages(). This hands CMA pages to the buddy allocator
while leaving them marked as allocated in the CMA bitmap, permanently
leaking CMA capacity on every failed expansion.

Try dma_release_from_contiguous() first and fall back to __free_pages()
only for pages that did not come from CMA, as the code did before CMA
allocation was temporarily removed from the pool.

Fixes: d7e673ec2c8e ("dma-pool: Only allocate from CMA when in same memory zone")
Closes: https://sashiko.dev/#/bug/linux-fdfc6e83-15e4-4980-9818-691b034397e7
Cc: stable@vger.kernel.org
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 kernel/dma/pool.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
index 00f422a1e896..381b3cb28368 100644
--- a/kernel/dma/pool.c
+++ b/kernel/dma/pool.c
@@ -152,7 +152,8 @@ static int atomic_pool_expand(struct dma_gen_pool *dma_pool, size_t pool_size,
 	dma_common_free_remap(addr, pool_size);
 free_page:
 #endif
-	if (!leak_pages)
+	if (!leak_pages &&
+	    !dma_release_from_contiguous(NULL, page, 1 << order))
 		__free_pages(page, order);
 out:
 	return ret;
-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/5] dma-direct: zero memory allocated with DMA_ATTR_NO_KERNEL_MAPPING
       [not found]   ` <CGME20261026095436eucas1p1338aced1035d6754d5094555237b6748@eucas1p1.samsung.com>
@ 2026-10-26  9:54     ` Marek Szyprowski
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-10-26  9:54 UTC (permalink / raw)
  To: iommu, linux-kernel
  Cc: Marek Szyprowski, Robin Murphy, Christoph Hellwig, Lucas Stach, stable

dma_direct_alloc_no_mapping() explicitly clears __GFP_ZERO before
allocating the pages, so buffers allocated with
DMA_ATTR_NO_KERNEL_MAPPING are handed out with stale contents of the
previously freed pages. Such buffers are typically passed to devices or
mapped to userspace, which may expose old kernel data.

The mask comes from the regular allocation path, which always zeroes the
buffer manually through its kernel mapping once it is set up. The
DMA_ATTR_NO_KERNEL_MAPPING path returns early with only a page cookie,
so it never reaches that memset(). This has been the case since the
attribute was first supported in the generic remap code in commit
e440e26a0251 ("dma-remap: support DMA_ATTR_NO_KERNEL_MAPPING") and was
carried over during dma-direct refactoring.

All other dma_alloc_* paths always return zeroed memory, so do the same
here and pass __GFP_ZERO to the page allocator instead of masking it out.

Fixes: e440e26a0251 ("dma-remap: support DMA_ATTR_NO_KERNEL_MAPPING")
Fixes: d98849aff879 ("dma-direct: handle DMA_ATTR_NO_KERNEL_MAPPING in common code")
Fixes: cf14be0b41c6 ("dma-direct: fix DMA_ATTR_NO_KERNEL_MAPPING")
Fixes: 849facea92fa ("dma-direct: simplify the DMA_ATTR_NO_KERNEL_MAPPING handling")
Closes: https://sashiko.dev/#/bug/linux-c4421083-e44e-4373-a2c2-45649ea49c0b
Cc: stable@vger.kernel.org
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 kernel/dma/direct.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 25e9a86835fd..c8a1ae7c618d 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -202,7 +202,8 @@ static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
 {
 	struct page *page;
 
-	page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, true);
+	/* always zero the allocated memory */
+	page = __dma_direct_alloc_pages(dev, size, gfp | __GFP_ZERO, true);
 	if (!page)
 		return NULL;
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] dma-mapping: assorted sashiko.dev fixes
  2026-10-26  9:54 ` [PATCH 0/5] dma-mapping: assorted sashiko.dev fixes Marek Szyprowski
                     ` (4 preceding siblings ...)
       [not found]   ` <CGME20261026095436eucas1p1338aced1035d6754d5094555237b6748@eucas1p1.samsung.com>
@ 2026-11-05  8:03   ` Marek Szyprowski
  5 siblings, 0 replies; 7+ messages in thread
From: Marek Szyprowski @ 2026-11-05  8:03 UTC (permalink / raw)
  To: iommu, linux-kernel
  Cc: Robin Murphy, Andrew Morton, Konrad Rzeszutek Wilk, Claire Chang,
	Petr Tesarik, Nicolas Saenz Julienne, Christoph Hellwig,
	Lucas Stach

On 26.10.2026 10:54, Marek Szyprowski wrote:
> This series collects fixes for the DMA-mapping code, developed while
> analyzing issues reported by the sashiko.dev automated review. All
> patches were prepared with LLM assistance and then reviewed manually.
>
> Best regards
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
>
>
> Marek Szyprowski (5):
>   dma-coherent: serialize reserved memory pool initialization
>   dma: swiotlb: Serialize restricted DMA pool initialization
>   dma: swiotlb: Remove default pool from the pools list on exit
>   dma-pool: release CMA pages on atomic_pool_expand() error path
>   dma-direct: zero memory allocated with DMA_ATTR_NO_KERNEL_MAPPING
Applied patches 1,2 & 4 to dma-mapping-fixes. The remaining two patches
need more work, I will post v2 soon.

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


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-11-05  8:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20261026095434eucas1p29408e916eda327a5e9c83f64b0df4e66@eucas1p2.samsung.com>
2026-10-26  9:54 ` [PATCH 0/5] dma-mapping: assorted sashiko.dev fixes Marek Szyprowski
     [not found]   ` <CGME20261026095434eucas1p1bb0ac7f1e94bcac196fdc97a0f2c9e9f@eucas1p1.samsung.com>
2026-10-26  9:54     ` [PATCH 1/5] dma-coherent: serialize reserved memory pool initialization Marek Szyprowski
     [not found]   ` <CGME20261026095435eucas1p1f2245a6982ef110340685dc66be53590@eucas1p1.samsung.com>
2026-10-26  9:54     ` [PATCH 2/5] dma: swiotlb: Serialize restricted DMA " Marek Szyprowski
     [not found]   ` <CGME20261026095435eucas1p129baa137891d2e9f5408b47afd6c556c@eucas1p1.samsung.com>
2026-10-26  9:54     ` [PATCH 3/5] dma: swiotlb: Remove default pool from the pools list on exit Marek Szyprowski
     [not found]   ` <CGME20261026095436eucas1p295baef3daff27873165c70d6d578c1b6@eucas1p2.samsung.com>
2026-10-26  9:54     ` [PATCH 4/5] dma-pool: release CMA pages on atomic_pool_expand() error path Marek Szyprowski
     [not found]   ` <CGME20261026095436eucas1p1338aced1035d6754d5094555237b6748@eucas1p1.samsung.com>
2026-10-26  9:54     ` [PATCH 5/5] dma-direct: zero memory allocated with DMA_ATTR_NO_KERNEL_MAPPING Marek Szyprowski
2026-11-05  8:03   ` [PATCH 0/5] dma-mapping: assorted sashiko.dev fixes Marek Szyprowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®