[PATCH V1] dma-mapping: Set dma_mem pointer as NULL after it's freed

From: joakim . zhang
Date: Tue Dec 12 2023 - 00:22:02 EST


From: Joakim Zhang <joakim.zhang@xxxxxxxxxxx>

Reproduced with below sequence:
dma_declare_coherent_memory()->dma_release_coherent_memory()
->dma_declare_coherent_memory()->"return -EBUSY" error

It will return -EBUSY from the dma_assign_coherent_memory()
in dma_declare_coherent_memory(), the reason is that dev->dma_mem
pointer has not been set to NULL after it's freed.

Go through the driver, found there is a issue in
rmem_dma_device_release(), the reserved memory has not been
freed before "dev->dma_mem = NULL;". So if user call
of_reserved_mem_device_release(), will not free reserved mem
in fact.

Fixes: cf65a0f6f6ff ("dma-mapping: move all DMA mapping code to kernel/dma")
Signed-off-by: Joakim Zhang <joakim.zhang@xxxxxxxxxxx>
---
kernel/dma/coherent.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index c21abc77c53e..602e055fc1bf 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -132,8 +132,10 @@ int dma_declare_coherent_memory(struct device *dev, phys_addr_t phys_addr,

void dma_release_coherent_memory(struct device *dev)
{
- if (dev)
+ if (dev) {
_dma_release_coherent_memory(dev->dma_mem);
+ dev->dma_mem = NULL;
+ }
}

static void *__dma_alloc_from_coherent(struct device *dev,
@@ -349,8 +351,10 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
static void rmem_dma_device_release(struct reserved_mem *rmem,
struct device *dev)
{
- if (dev)
+ if (dev) {
+ _dma_release_coherent_memory(rmem->priv);
dev->dma_mem = NULL;
+ }
}

static const struct reserved_mem_ops rmem_dma_ops = {
--
2.25.1