* [PATCH v5 1/5] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool
2026-05-15 12:42 [PATCH v5 0/5] misc: fastrpc: Add missing bug fixes Jianping Li
@ 2026-05-15 12:42 ` Jianping Li
2026-05-15 13:33 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
2026-05-15 12:42 ` [PATCH v5 2/5] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
` (4 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Jianping Li @ 2026-05-15 12:42 UTC (permalink / raw)
To: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz
Cc: Ekansh Gupta, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable, Jianping Li
From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
The initial buffer allocated for the Audio PD memory pool is never added
to the pool because pageslen is set to 0. As a result, the buffer is not
registered with Audio PD and is never used, causing a memory leak. Audio
PD immediately falls back to allocating memory from the remote heap since
the pool starts out empty.
Fix this by setting pageslen to 1 so that the initially allocated buffer
is correctly registered and becomes part of the Audio PD memory pool.
Fixes: 0871561055e66 ("misc: fastrpc: Add support for audiopd")
Cc: stable@kernel.org
Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 1080f9acf70a..8b21f85cd9f4 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1324,7 +1324,9 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
err = PTR_ERR(name);
goto err;
}
-
+ inbuf.client_id = fl->client_id;
+ inbuf.namelen = init.namelen;
+ inbuf.pageslen = 0;
if (!fl->cctx->remote_heap) {
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
&fl->cctx->remote_heap);
@@ -1347,12 +1349,10 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
goto err_map;
}
scm_done = true;
+ inbuf.pageslen = 1;
}
}
- inbuf.client_id = fl->client_id;
- inbuf.namelen = init.namelen;
- inbuf.pageslen = 0;
fl->pd = USER_PD;
args[0].ptr = (u64)(uintptr_t)&inbuf;
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v5 1/5] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool
2026-05-15 12:42 ` [PATCH v5 1/5] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool Jianping Li
@ 2026-05-15 13:33 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-05-15 13:33 UTC (permalink / raw)
To: Jianping Li
Cc: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz,
Ekansh Gupta, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable
On Fri, May 15, 2026 at 08:42:13PM +0800, Jianping Li wrote:
> From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
>
> The initial buffer allocated for the Audio PD memory pool is never added
> to the pool because pageslen is set to 0. As a result, the buffer is not
> registered with Audio PD and is never used, causing a memory leak. Audio
> PD immediately falls back to allocating memory from the remote heap since
> the pool starts out empty.
>
> Fix this by setting pageslen to 1 so that the initially allocated buffer
> is correctly registered and becomes part of the Audio PD memory pool.
>
> Fixes: 0871561055e66 ("misc: fastrpc: Add support for audiopd")
> Cc: stable@kernel.org
> Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
If it's From:Ekansh, it can't be CDB: Ekansh. How can Ekansh co-develop
the patch with himself?
> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
> ---
> drivers/misc/fastrpc.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 1080f9acf70a..8b21f85cd9f4 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -1324,7 +1324,9 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
> err = PTR_ERR(name);
> goto err;
> }
> -
> + inbuf.client_id = fl->client_id;
> + inbuf.namelen = init.namelen;
> + inbuf.pageslen = 0;
> if (!fl->cctx->remote_heap) {
> err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
> &fl->cctx->remote_heap);
> @@ -1347,12 +1349,10 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
> goto err_map;
> }
> scm_done = true;
> + inbuf.pageslen = 1;
> }
> }
>
> - inbuf.client_id = fl->client_id;
> - inbuf.namelen = init.namelen;
> - inbuf.pageslen = 0;
> fl->pd = USER_PD;
>
> args[0].ptr = (u64)(uintptr_t)&inbuf;
> --
> 2.43.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread* Claude review: misc: fastrpc: Fix initial memory allocation for Audio PD memory pool
2026-05-15 12:42 ` [PATCH v5 1/5] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool Jianping Li
2026-05-15 13:33 ` Dmitry Baryshkov
@ 2026-05-15 23:09 ` Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-05-15 23:09 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
**Verdict: Looks good.**
The fix is correct. In the original code, `inbuf.pageslen` is unconditionally set to 0 *after* the remote heap allocation and SCM assignment block, so the DSP never receives the allocated buffer:
```c
// original: pageslen always 0
inbuf.client_id = fl->client_id;
inbuf.namelen = init.namelen;
inbuf.pageslen = 0;
```
The patch moves these assignments before the allocation block and sets `pageslen = 1` when the SCM assignment succeeds:
```c
+ scm_done = true;
+ inbuf.pageslen = 1;
```
This ensures the initially allocated buffer is actually registered with the Audio PD. The logic is clean: default `pageslen=0`, set to 1 only when memory is both allocated and SCM-assigned.
Note: This code is removed by patch 4, so this fix is primarily for stable backports.
---
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v5 2/5] misc: fastrpc: Remove buffer from list prior to unmap operation
2026-05-15 12:42 [PATCH v5 0/5] misc: fastrpc: Add missing bug fixes Jianping Li
2026-05-15 12:42 ` [PATCH v5 1/5] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool Jianping Li
@ 2026-05-15 12:42 ` Jianping Li
2026-05-15 13:36 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
2026-05-15 12:42 ` [PATCH v5 3/5] misc: fastrpc: Fail Audio PD init when reserved memory is missing Jianping Li
` (3 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Jianping Li @ 2026-05-15 12:42 UTC (permalink / raw)
To: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz
Cc: Ekansh Gupta, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable, Jianping Li
From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
fastrpc_req_munmap_impl() is called to unmap any buffer. The buffer is
getting removed from the list after it is unmapped from DSP. This can
create potential race conditions if any other thread removes the entry
from list while unmap operation is ongoing. Remove the entry before
calling unmap operation.
Fixes: 2419e55e532de ("misc: fastrpc: add mmap/unmap support")
Cc: stable@kernel.org
Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 8b21f85cd9f4..3c7c3b410d7d 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1863,9 +1863,6 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
&args[0]);
if (!err) {
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
- spin_lock(&fl->lock);
- list_del(&buf->node);
- spin_unlock(&fl->lock);
fastrpc_buf_free(buf);
} else {
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
@@ -1879,6 +1876,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_req_munmap req;
struct device *dev = fl->sctx->dev;
+ int err;
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;
@@ -1886,6 +1884,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
spin_lock(&fl->lock);
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
+ list_del(&iter->node);
buf = iter;
break;
}
@@ -1898,7 +1897,14 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
return -EINVAL;
}
- return fastrpc_req_munmap_impl(fl, buf);
+ err = fastrpc_req_munmap_impl(fl, buf);
+ if (err) {
+ spin_lock(&fl->lock);
+ list_add_tail(&buf->node, &fl->mmaps);
+ spin_unlock(&fl->lock);
+ }
+
+ return err;
}
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
@@ -1989,14 +1995,17 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
err = -EFAULT;
- goto err_assign;
+ goto err_copy;
}
dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
buf->raddr, buf->size);
return 0;
-
+err_copy:
+ spin_lock(&fl->lock);
+ list_del(&buf->node);
+ spin_unlock(&fl->lock);
err_assign:
fastrpc_req_munmap_impl(fl, buf);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v5 2/5] misc: fastrpc: Remove buffer from list prior to unmap operation
2026-05-15 12:42 ` [PATCH v5 2/5] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
@ 2026-05-15 13:36 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-05-15 13:36 UTC (permalink / raw)
To: Jianping Li
Cc: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz,
Ekansh Gupta, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable
On Fri, May 15, 2026 at 08:42:14PM +0800, Jianping Li wrote:
> From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
>
> fastrpc_req_munmap_impl() is called to unmap any buffer. The buffer is
> getting removed from the list after it is unmapped from DSP. This can
> create potential race conditions if any other thread removes the entry
> from list while unmap operation is ongoing. Remove the entry before
How can it remove the entry from the list?
> calling unmap operation.
>
> Fixes: 2419e55e532de ("misc: fastrpc: add mmap/unmap support")
> Cc: stable@kernel.org
> Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
> ---
> drivers/misc/fastrpc.c | 21 +++++++++++++++------
> 1 file changed, 15 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 8b21f85cd9f4..3c7c3b410d7d 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -1863,9 +1863,6 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
> &args[0]);
> if (!err) {
> dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
> - spin_lock(&fl->lock);
> - list_del(&buf->node);
> - spin_unlock(&fl->lock);
> fastrpc_buf_free(buf);
> } else {
> dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
> @@ -1879,6 +1876,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
> struct fastrpc_buf *buf = NULL, *iter, *b;
> struct fastrpc_req_munmap req;
> struct device *dev = fl->sctx->dev;
> + int err;
>
> if (copy_from_user(&req, argp, sizeof(req)))
> return -EFAULT;
> @@ -1886,6 +1884,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
> spin_lock(&fl->lock);
> list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
> if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
> + list_del(&iter->node);
> buf = iter;
> break;
> }
> @@ -1898,7 +1897,14 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
> return -EINVAL;
> }
>
> - return fastrpc_req_munmap_impl(fl, buf);
> + err = fastrpc_req_munmap_impl(fl, buf);
> + if (err) {
> + spin_lock(&fl->lock);
> + list_add_tail(&buf->node, &fl->mmaps);
> + spin_unlock(&fl->lock);
> + }
Is it expected that userspace tries to unmap it again? Or why is it
being added to the list?
> +
> + return err;
> }
>
> static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
> @@ -1989,14 +1995,17 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
>
> if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
> err = -EFAULT;
> - goto err_assign;
> + goto err_copy;
> }
>
> dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
> buf->raddr, buf->size);
>
> return 0;
> -
> +err_copy:
> + spin_lock(&fl->lock);
> + list_del(&buf->node);
> + spin_unlock(&fl->lock);
This is a separate fix.
> err_assign:
> fastrpc_req_munmap_impl(fl, buf);
>
> --
> 2.43.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread* Claude review: misc: fastrpc: Remove buffer from list prior to unmap operation
2026-05-15 12:42 ` [PATCH v5 2/5] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
2026-05-15 13:36 ` Dmitry Baryshkov
@ 2026-05-15 23:09 ` Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-05-15 23:09 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
**Verdict: Looks good, minor style nit.**
Moving the `list_del` from `fastrpc_req_munmap_impl()` into the caller `fastrpc_req_munmap()` before the unmap call is the correct fix for the race. The rollback on failure is also correct:
```c
+ err = fastrpc_req_munmap_impl(fl, buf);
+ if (err) {
+ spin_lock(&fl->lock);
+ list_add_tail(&buf->node, &fl->mmaps);
+ spin_unlock(&fl->lock);
+ }
```
The `fastrpc_req_mmap()` error path changes are also correct: the new `err_copy` label removes the buffer from the list (it was added in the success path above) before falling through to `err_assign` which calls `fastrpc_req_munmap_impl()`:
```c
+err_copy:
+ spin_lock(&fl->lock);
+ list_del(&buf->node);
+ spin_unlock(&fl->lock);
err_assign:
fastrpc_req_munmap_impl(fl, buf);
```
This is consistent since `fastrpc_req_munmap_impl()` no longer touches the list.
---
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v5 3/5] misc: fastrpc: Fail Audio PD init when reserved memory is missing
2026-05-15 12:42 [PATCH v5 0/5] misc: fastrpc: Add missing bug fixes Jianping Li
2026-05-15 12:42 ` [PATCH v5 1/5] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool Jianping Li
2026-05-15 12:42 ` [PATCH v5 2/5] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
@ 2026-05-15 12:42 ` Jianping Li
2026-05-15 13:37 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
2026-05-15 12:42 ` [PATCH v5 4/5] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
` (2 subsequent siblings)
5 siblings, 2 replies; 17+ messages in thread
From: Jianping Li @ 2026-05-15 12:42 UTC (permalink / raw)
To: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz
Cc: Jianping Li, linux-arm-msm, dri-devel, linux-kernel, ekansh.gupta,
quic_chennak, stable
Audio PD static process creation assumes that a reserved-memory
region is defined in DT and exposed via cctx->remote_heap.
If reserved-memory is missing or incomplete, the driver may pass
invalid address/size information to the DSP, leading to undefined
behavior or crashes.
Add explicit validation for remote_heap presence and size before
sending the memory to DSP, and fail early if the configuration is
invalid.
Fixes: 0871561055e66 ("misc: fastrpc: Add support for audiopd")
Cc: stable@kernel.org
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 3c7c3b410d7d..a0337cce77f3 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1363,6 +1363,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
args[1].length = inbuf.namelen;
args[1].fd = -1;
+ if (!fl->cctx->remote_heap ||
+ !fl->cctx->remote_heap->dma_addr ||
+ !fl->cctx->remote_heap->size) {
+ err = -ENOMEM;
+ goto err;
+ }
pages[0].addr = fl->cctx->remote_heap->dma_addr;
pages[0].size = fl->cctx->remote_heap->size;
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v5 3/5] misc: fastrpc: Fail Audio PD init when reserved memory is missing
2026-05-15 12:42 ` [PATCH v5 3/5] misc: fastrpc: Fail Audio PD init when reserved memory is missing Jianping Li
@ 2026-05-15 13:37 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-05-15 13:37 UTC (permalink / raw)
To: Jianping Li
Cc: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz,
linux-arm-msm, dri-devel, linux-kernel, ekansh.gupta,
quic_chennak, stable
On Fri, May 15, 2026 at 08:42:15PM +0800, Jianping Li wrote:
> Audio PD static process creation assumes that a reserved-memory
> region is defined in DT and exposed via cctx->remote_heap.
>
> If reserved-memory is missing or incomplete, the driver may pass
> invalid address/size information to the DSP, leading to undefined
> behavior or crashes.
>
> Add explicit validation for remote_heap presence and size before
> sending the memory to DSP, and fail early if the configuration is
> invalid.
>
> Fixes: 0871561055e66 ("misc: fastrpc: Add support for audiopd")
> Cc: stable@kernel.org
> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
> ---
> drivers/misc/fastrpc.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 3c7c3b410d7d..a0337cce77f3 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -1363,6 +1363,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
> args[1].length = inbuf.namelen;
> args[1].fd = -1;
>
> + if (!fl->cctx->remote_heap ||
> + !fl->cctx->remote_heap->dma_addr ||
> + !fl->cctx->remote_heap->size) {
I guess that !dma_addr || !size should fail much earlier than here.
> + err = -ENOMEM;
> + goto err;
> + }
> pages[0].addr = fl->cctx->remote_heap->dma_addr;
> pages[0].size = fl->cctx->remote_heap->size;
>
> --
> 2.43.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread* Claude review: misc: fastrpc: Fail Audio PD init when reserved memory is missing
2026-05-15 12:42 ` [PATCH v5 3/5] misc: fastrpc: Fail Audio PD init when reserved memory is missing Jianping Li
2026-05-15 13:37 ` Dmitry Baryshkov
@ 2026-05-15 23:09 ` Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-05-15 23:09 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
**Verdict: Looks good, minor observation.**
The validation is correct and prevents NULL dereferences:
```c
+ if (!fl->cctx->remote_heap ||
+ !fl->cctx->remote_heap->dma_addr ||
+ !fl->cctx->remote_heap->size) {
+ err = -ENOMEM;
+ goto err;
+ }
```
Minor note: Checking `!fl->cctx->remote_heap->dma_addr` could theoretically be a false positive if a DMA address is legitimately 0, but in practice reserved-memory regions on ARM platforms will never map to physical address 0. This is a standard defensive check.
This patch is superseded by patch 4 for mainline but is important for stable backports. The error code `-ENOMEM` is reasonable since the memory region is absent.
---
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v5 4/5] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-05-15 12:42 [PATCH v5 0/5] misc: fastrpc: Add missing bug fixes Jianping Li
` (2 preceding siblings ...)
2026-05-15 12:42 ` [PATCH v5 3/5] misc: fastrpc: Fail Audio PD init when reserved memory is missing Jianping Li
@ 2026-05-15 12:42 ` Jianping Li
2026-05-15 13:38 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
2026-05-15 12:42 ` [PATCH v5 5/5] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL Jianping Li
2026-05-15 23:09 ` Claude review: misc: fastrpc: Add missing bug fixes Claude Code Review Bot
5 siblings, 2 replies; 17+ messages in thread
From: Jianping Li @ 2026-05-15 12:42 UTC (permalink / raw)
To: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz
Cc: Jianping Li, linux-arm-msm, dri-devel, linux-kernel, ekansh.gupta,
quic_chennak
Allocating and freeing Audio PD memory from userspace is unsafe because
the kernel cannot reliably determine when the DSP has finished using the
memory. Userspace may free buffers while they are still in use by the DSP,
and remote free requests cannot be safely trusted.
Allocate the entire Audio PD reserved-memory region upfront during rpmsg
probe and tie its lifetime to the rpmsg channel. This avoids userspace-
controlled alloc/free and ensures memory is reclaimed only when the DSP
shuts down.
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 107 +++++++++++++++++++----------------------
1 file changed, 49 insertions(+), 58 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index a0337cce77f3..9c70788afa0f 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -276,6 +276,8 @@ struct fastrpc_channel_ctx {
struct kref refcount;
/* Flag if dsp attributes are cached */
bool valid_attributes;
+ /* Flag if audio PD init mem was allocated */
+ bool audio_init_mem;
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
struct fastrpc_device *secure_fdevice;
struct fastrpc_device *fdevice;
@@ -1295,15 +1297,16 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
struct fastrpc_init_create_static init;
struct fastrpc_invoke_args *args;
struct fastrpc_phy_page pages[1];
+ struct fastrpc_channel_ctx *cctx = fl->cctx;
char *name;
int err;
- bool scm_done = false;
struct {
int client_id;
u32 namelen;
u32 pageslen;
} inbuf;
u32 sc;
+ unsigned long flags;
args = kzalloc_objs(*args, FASTRPC_CREATE_STATIC_PROCESS_NARGS);
if (!args)
@@ -1327,31 +1330,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
inbuf.client_id = fl->client_id;
inbuf.namelen = init.namelen;
inbuf.pageslen = 0;
- if (!fl->cctx->remote_heap) {
- err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
- &fl->cctx->remote_heap);
- if (err)
- goto err_name;
-
- /* Map if we have any heap VMIDs associated with this ADSP Static Process. */
- if (fl->cctx->vmcount) {
- u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
-
- err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
- (u64)fl->cctx->remote_heap->size,
- &src_perms,
- fl->cctx->vmperms, fl->cctx->vmcount);
- if (err) {
- dev_err(fl->sctx->dev,
- "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
- &fl->cctx->remote_heap->dma_addr,
- fl->cctx->remote_heap->size, err);
- goto err_map;
- }
- scm_done = true;
- inbuf.pageslen = 1;
- }
- }
fl->pd = USER_PD;
@@ -1363,14 +1341,24 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
args[1].length = inbuf.namelen;
args[1].fd = -1;
- if (!fl->cctx->remote_heap ||
- !fl->cctx->remote_heap->dma_addr ||
- !fl->cctx->remote_heap->size) {
- err = -ENOMEM;
- goto err;
+ spin_lock_irqsave(&cctx->lock, flags);
+ if (!fl->cctx->audio_init_mem) {
+ if (!fl->cctx->remote_heap ||
+ !fl->cctx->remote_heap->dma_addr ||
+ !fl->cctx->remote_heap->size) {
+ spin_unlock_irqrestore(&cctx->lock, flags);
+ err = -ENOMEM;
+ goto err;
+ }
+ pages[0].addr = fl->cctx->remote_heap->dma_addr;
+ pages[0].size = fl->cctx->remote_heap->size;
+ fl->cctx->audio_init_mem = true;
+ inbuf.pageslen = 1;
+ } else {
+ pages[0].addr = 0;
+ pages[0].size = 0;
}
- pages[0].addr = fl->cctx->remote_heap->dma_addr;
- pages[0].size = fl->cctx->remote_heap->size;
+ spin_unlock_irqrestore(&cctx->lock, flags);
args[2].ptr = (u64)(uintptr_t) pages;
args[2].length = sizeof(*pages);
@@ -1388,27 +1376,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
return 0;
err_invoke:
- if (fl->cctx->vmcount && scm_done) {
- u64 src_perms = 0;
- struct qcom_scm_vmperm dst_perms;
- u32 i;
-
- for (i = 0; i < fl->cctx->vmcount; i++)
- src_perms |= BIT(fl->cctx->vmperms[i].vmid);
-
- dst_perms.vmid = QCOM_SCM_VMID_HLOS;
- dst_perms.perm = QCOM_SCM_PERM_RWX;
- err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
- (u64)fl->cctx->remote_heap->size,
- &src_perms, &dst_perms, 1);
- if (err)
- dev_err(fl->sctx->dev, "Failed to assign memory dma_addr %pad size 0x%llx err %d\n",
- &fl->cctx->remote_heap->dma_addr, fl->cctx->remote_heap->size, err);
- }
-err_map:
- fastrpc_buf_free(fl->cctx->remote_heap);
- fl->cctx->remote_heap = NULL;
-err_name:
+ fl->cctx->audio_init_mem = false;
kfree(name);
err:
kfree(args);
@@ -2397,12 +2365,21 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
}
}
- if (domain_id == SDSP_DOMAIN_ID) {
+ if (domain_id == SDSP_DOMAIN_ID || domain_id == ADSP_DOMAIN_ID) {
struct resource res;
u64 src_perms;
err = of_reserved_mem_region_to_resource(rdev->of_node, 0, &res);
if (!err) {
+ if (domain_id == ADSP_DOMAIN_ID) {
+ data->remote_heap =
+ kzalloc_obj(*data->remote_heap, GFP_KERNEL);
+ if (!data->remote_heap)
+ return -ENOMEM;
+
+ data->remote_heap->dma_addr = res.start;
+ data->remote_heap->size = resource_size(&res);
+ }
src_perms = BIT(QCOM_SCM_VMID_HLOS);
err = qcom_scm_assign_mem(res.start, resource_size(&res), &src_perms,
@@ -2410,7 +2387,6 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
if (err)
goto err_free_data;
}
-
}
secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain"));
@@ -2491,6 +2467,7 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
struct fastrpc_buf *buf, *b;
struct fastrpc_user *user;
unsigned long flags;
+ int err;
/* No invocations past this point */
spin_lock_irqsave(&cctx->lock, flags);
@@ -2508,8 +2485,22 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
list_del(&buf->node);
- if (cctx->remote_heap)
- fastrpc_buf_free(cctx->remote_heap);
+ if (cctx->remote_heap && cctx->vmcount) {
+ u64 src_perms = 0;
+ struct qcom_scm_vmperm dst_perms;
+
+ for (u32 i = 0; i < cctx->vmcount; i++)
+ src_perms |= BIT(cctx->vmperms[i].vmid);
+
+ dst_perms.vmid = QCOM_SCM_VMID_HLOS;
+ dst_perms.perm = QCOM_SCM_PERM_RWX;
+
+ err = qcom_scm_assign_mem(cctx->remote_heap->dma_addr,
+ cctx->remote_heap->size, &src_perms,
+ &dst_perms, 1);
+ if (!err)
+ kfree(cctx->remote_heap);
+ }
of_platform_depopulate(&rpdev->dev);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Re: [PATCH v5 4/5] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-05-15 12:42 ` [PATCH v5 4/5] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
@ 2026-05-15 13:38 ` Dmitry Baryshkov
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Dmitry Baryshkov @ 2026-05-15 13:38 UTC (permalink / raw)
To: Jianping Li
Cc: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz,
linux-arm-msm, dri-devel, linux-kernel, ekansh.gupta,
quic_chennak
On Fri, May 15, 2026 at 08:42:16PM +0800, Jianping Li wrote:
> Allocating and freeing Audio PD memory from userspace is unsafe because
> the kernel cannot reliably determine when the DSP has finished using the
> memory. Userspace may free buffers while they are still in use by the DSP,
> and remote free requests cannot be safely trusted.
>
> Allocate the entire Audio PD reserved-memory region upfront during rpmsg
> probe and tie its lifetime to the rpmsg channel. This avoids userspace-
> controlled alloc/free and ensures memory is reclaimed only when the DSP
> shuts down.
So, is this a bugfix or not? Is it possible to make the kernel misbehave
without this patch being applied?
>
> Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
> ---
> drivers/misc/fastrpc.c | 107 +++++++++++++++++++----------------------
> 1 file changed, 49 insertions(+), 58 deletions(-)
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 17+ messages in thread
* Claude review: misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-05-15 12:42 ` [PATCH v5 4/5] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
2026-05-15 13:38 ` Dmitry Baryshkov
@ 2026-05-15 23:09 ` Claude Code Review Bot
1 sibling, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-05-15 23:09 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
**Verdict: Needs fixes — two memory leaks in probe error paths, and a logic issue with `audio_init_mem` reset.**
**Bug 1: Memory leak on kzalloc failure in probe**
```c
+ if (domain_id == ADSP_DOMAIN_ID) {
+ data->remote_heap =
+ kzalloc_obj(*data->remote_heap, GFP_KERNEL);
+ if (!data->remote_heap)
+ return -ENOMEM;
```
At this point, `data` has already been allocated (line ~2373). The bare `return -ENOMEM` leaks `data`. This should be `goto err_free_data` or equivalent. Also, note that `kzalloc_obj(*data->remote_heap)` without explicit `GFP_KERNEL` would be equivalent since `default_gfp()` defaults to `GFP_KERNEL`.
**Bug 2: Memory leak on SCM failure in probe**
If `qcom_scm_assign_mem()` fails after `data->remote_heap` was allocated:
```c
err = qcom_scm_assign_mem(res.start, resource_size(&res), &src_perms,
data->vmperms, data->vmcount);
if (err)
goto err_free_data;
```
The `err_free_data` label only does `kfree(data)` — it does not free `data->remote_heap`. This leaks the remote_heap allocation.
**Issue 3: Unconditional `audio_init_mem = false` in err_invoke**
```c
err_invoke:
- if (fl->cctx->vmcount && scm_done) { ... }
-err_map:
- fastrpc_buf_free(fl->cctx->remote_heap);
- fl->cctx->remote_heap = NULL;
-err_name:
+ fl->cctx->audio_init_mem = false;
```
If two concurrent callers enter `fastrpc_init_create_static_process()`, the first one sets `audio_init_mem = true` and succeeds. The second caller takes the `else` branch (pageslen=0, pages=0). If the second caller's invoke fails, `audio_init_mem` is unconditionally reset to `false`. A subsequent third caller would then re-send the memory information to the DSP, which the DSP may have already received from the first call. The reset should be conditional:
```c
err_invoke:
if (inbuf.pageslen)
fl->cctx->audio_init_mem = false;
```
**Style nit: Inconsistent cctx usage**
The patch adds `struct fastrpc_channel_ctx *cctx = fl->cctx;` but then mixes `fl->cctx->` and `cctx->` in the same code block:
```c
+ spin_lock_irqsave(&cctx->lock, flags);
+ if (!fl->cctx->audio_init_mem) {
+ if (!fl->cctx->remote_heap ||
```
Should consistently use `cctx->` throughout.
**Observation on remove path**
The remove path correctly uses `kfree()` instead of `fastrpc_buf_free()` since the buffer was allocated with `kzalloc_obj` (not DMA coherent allocation). However, if `qcom_scm_assign_mem` fails during remove, the remote_heap struct is never freed:
```c
+ err = qcom_scm_assign_mem(cctx->remote_heap->dma_addr,
+ cctx->remote_heap->size, &src_perms,
+ &dst_perms, 1);
+ if (!err)
+ kfree(cctx->remote_heap);
```
If the SCM call fails during teardown, there's not much that can be done, but a `dev_err()` log would be helpful for debugging, and the memory should arguably be freed anyway since the channel is shutting down (the SCM failure means the memory ownership is in a bad state, but leaking the tracking struct doesn't help).
Also: if `cctx->vmcount` is 0 but `cctx->remote_heap` is non-NULL, the entire block is skipped and `remote_heap` is leaked. This could happen if the ADSP domain has reserved-memory in DT but no `qcom,vmids`.
---
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v5 5/5] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL
2026-05-15 12:42 [PATCH v5 0/5] misc: fastrpc: Add missing bug fixes Jianping Li
` (3 preceding siblings ...)
2026-05-15 12:42 ` [PATCH v5 4/5] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
@ 2026-05-15 12:42 ` Jianping Li
2026-05-15 23:09 ` Claude review: " Claude Code Review Bot
2026-05-15 23:09 ` Claude review: misc: fastrpc: Add missing bug fixes Claude Code Review Bot
5 siblings, 1 reply; 17+ messages in thread
From: Jianping Li @ 2026-05-15 12:42 UTC (permalink / raw)
To: srini, amahesh, arnd, gregkh, abelvesa, jorge.ramirez-ortiz
Cc: Ekansh Gupta, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, Jianping Li
From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Make fastrpc_buf_free() a no-op when passed a NULL pointer, allowing
callers to avoid open-coded NULL checks.
Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 9c70788afa0f..82bfbf342725 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -416,6 +416,9 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
static void fastrpc_buf_free(struct fastrpc_buf *buf)
{
+ if (!buf)
+ return;
+
dma_free_coherent(buf->dev, buf->size, buf->virt,
fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr));
kfree(buf);
@@ -512,8 +515,7 @@ static void fastrpc_context_free(struct kref *ref)
for (i = 0; i < ctx->nbufs; i++)
fastrpc_map_put(ctx->maps[i]);
- if (ctx->buf)
- fastrpc_buf_free(ctx->buf);
+ fastrpc_buf_free(ctx->buf);
spin_lock_irqsave(&cctx->lock, flags);
idr_remove(&cctx->ctx_idr, ctx->ctxid >> 4);
@@ -1564,8 +1566,7 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
list_del(&fl->user);
spin_unlock_irqrestore(&cctx->lock, flags);
- if (fl->init_mem)
- fastrpc_buf_free(fl->init_mem);
+ fastrpc_buf_free(fl->init_mem);
list_for_each_entry_safe(ctx, n, &fl->pending, node) {
list_del(&ctx->node);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Claude review: misc: fastrpc: Allow fastrpc_buf_free() to accept NULL
2026-05-15 12:42 ` [PATCH v5 5/5] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL Jianping Li
@ 2026-05-15 23:09 ` Claude Code Review Bot
0 siblings, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-05-15 23:09 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
**Verdict: Looks good.**
Clean kernel-convention cleanup. Making `fastrpc_buf_free()` NULL-safe like `kfree()`:
```c
+ if (!buf)
+ return;
```
And removing the now-redundant NULL checks in callers:
```c
- if (ctx->buf)
- fastrpc_buf_free(ctx->buf);
+ fastrpc_buf_free(ctx->buf);
```
No functional change. This is a nice hardening that follows established kernel patterns (cf. `kfree`, `vfree`, `dma_free_coherent` on newer kernels, etc.).
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread
* Claude review: misc: fastrpc: Add missing bug fixes
2026-05-15 12:42 [PATCH v5 0/5] misc: fastrpc: Add missing bug fixes Jianping Li
` (4 preceding siblings ...)
2026-05-15 12:42 ` [PATCH v5 5/5] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL Jianping Li
@ 2026-05-15 23:09 ` Claude Code Review Bot
5 siblings, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-05-15 23:09 UTC (permalink / raw)
To: dri-devel-reviews
Overall Series Review
Subject: misc: fastrpc: Add missing bug fixes
Author: Jianping Li <jianping.li@oss.qualcomm.com>
Patches: 10
Reviewed: 2026-05-16T09:09:53.913817
---
This v5 series addresses multiple memory handling bugs in the FastRPC Audio PD remote heap. The first three patches are self-contained bug fixes with `Fixes:` tags and `Cc: stable`, while patches 4-5 are structural improvements that supersede some of the earlier fixes in mainline.
The series has a **sound overall design**: moving Audio PD reserved-memory allocation to rpmsg probe and tying its lifetime to the channel is the right approach. However, **patch 4 has two memory leak bugs in error paths** and an unconditional `audio_init_mem = false` reset that can affect concurrent users. Patch 2 is solid and correctly addresses the race. Patches 1, 3, and 5 are clean fixes/cleanups.
**Recommendation:** Patches 1, 2, 3, and 5 look good. Patch 4 needs fixes for the error paths in probe and the `err_invoke` label logic before it can be merged.
---
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v4 2/4] misc: fastrpc: Remove buffer from list prior to unmap operation
2026-04-09 6:26 [PATCH v4 0/4] " Jianping Li
@ 2026-04-09 6:26 ` Jianping Li
2026-04-12 1:44 ` Claude review: " Claude Code Review Bot
0 siblings, 1 reply; 17+ messages in thread
From: Jianping Li @ 2026-04-09 6:26 UTC (permalink / raw)
To: Srinivas Kandagatla, Amol Maheshwari
Cc: Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa, Jorge Ramirez-Ortiz,
linux-arm-msm, dri-devel, linux-kernel, ekansh.gupta,
quic_chennak, stable, Jianping Li
From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
fastrpc_req_munmap_impl() is called to unmap any buffer. The buffer is
getting removed from the list after it is unmapped from DSP. This can
create potential race conditions if any other thread removes the entry
from list while unmap operation is ongoing. Remove the entry before
calling unmap operation.
Fixes: 2419e55e532de ("misc: fastrpc: add mmap/unmap support")
Cc: stable@kernel.org
Co-developed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
---
drivers/misc/fastrpc.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index b87a5f97c96f..148085c3b61a 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1862,9 +1862,6 @@ static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *
&args[0]);
if (!err) {
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
- spin_lock(&fl->lock);
- list_del(&buf->node);
- spin_unlock(&fl->lock);
fastrpc_buf_free(buf);
} else {
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
@@ -1878,6 +1875,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_req_munmap req;
struct device *dev = fl->sctx->dev;
+ int err;
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;
@@ -1885,6 +1883,7 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
spin_lock(&fl->lock);
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
+ list_del(&iter->node);
buf = iter;
break;
}
@@ -1897,7 +1896,14 @@ static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
return -EINVAL;
}
- return fastrpc_req_munmap_impl(fl, buf);
+ err = fastrpc_req_munmap_impl(fl, buf);
+ if (err) {
+ spin_lock(&fl->lock);
+ list_add_tail(&buf->node, &fl->mmaps);
+ spin_unlock(&fl->lock);
+ }
+
+ return err;
}
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
@@ -1988,14 +1994,17 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
err = -EFAULT;
- goto err_assign;
+ goto err_copy;
}
dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
buf->raddr, buf->size);
return 0;
-
+err_copy:
+ spin_lock(&fl->lock);
+ list_del(&buf->node);
+ spin_unlock(&fl->lock);
err_assign:
fastrpc_req_munmap_impl(fl, buf);
--
2.43.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* Claude review: misc: fastrpc: Remove buffer from list prior to unmap operation
2026-04-09 6:26 ` [PATCH v4 2/4] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
@ 2026-04-12 1:44 ` Claude Code Review Bot
0 siblings, 0 replies; 17+ messages in thread
From: Claude Code Review Bot @ 2026-04-12 1:44 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
**Verdict: Reasonable fix with one concern.**
The change moves the `list_del` out of `fastrpc_req_munmap_impl()` and into the caller `fastrpc_req_munmap()`, done under the spinlock before the DSP unmap RPC:
```c
spin_lock(&fl->lock);
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
list_del(&iter->node); // remove before unlocking
buf = iter;
break;
}
}
spin_unlock(&fl->lock);
```
If the DSP unmap fails, the buffer is re-added:
```c
err = fastrpc_req_munmap_impl(fl, buf);
if (err) {
spin_lock(&fl->lock);
list_add_tail(&buf->node, &fl->mmaps);
spin_unlock(&fl->lock);
}
```
This prevents a race where two threads could both find and try to unmap the same buffer. The remove-first, re-add-on-failure pattern is reasonable.
The `fastrpc_req_mmap` error path change is also correct: when `copy_to_user` fails, the buffer (already added to the list) must be removed before calling `fastrpc_req_munmap_impl` (which no longer does `list_del`):
```c
err_copy:
spin_lock(&fl->lock);
list_del(&buf->node);
spin_unlock(&fl->lock);
err_assign:
fastrpc_req_munmap_impl(fl, buf);
```
**Concern:** After removing the `list_del` from `fastrpc_req_munmap_impl`, ensure all callers handle list removal. There are at least two callers: `fastrpc_req_munmap` (handled) and the `err_assign` path in `fastrpc_req_mmap` (handled via new `err_copy`). The `fastrpc_device_release` path iterates the list and calls `fastrpc_buf_free` directly (not through `_impl`), so it's not affected. This looks complete.
---
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 17+ messages in thread