[PATCH 2/5] dma: swiotlb: Serialize restricted DMA pool initialization
From: Marek Szyprowski
Date: Mon Oct 26 2026 - 06:03:24 EST
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@xxxxxxxxxxxxxxx
Signed-off-by: Marek Szyprowski <m.szyprowski@xxxxxxxxxxx>
---
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