* [PATCH v8 1/4] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool
2026-06-09 2:59 [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Jianping Li
@ 2026-06-09 2:59 ` Jianping Li
2026-06-09 2:59 ` [PATCH v8 2/4] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jianping Li @ 2026-06-09 2:59 UTC (permalink / raw)
To: Srinivas Kandagatla, Amol Maheshwari
Cc: Ekansh Gupta, Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa,
Jorge Ramirez-Ortiz, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable, Dmitry Baryshkov, 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
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@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 a9b2ae44c06f..96961217b856 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1370,7 +1370,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);
@@ -1393,12 +1395,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] 10+ messages in thread* [PATCH v8 2/4] misc: fastrpc: Remove buffer from list prior to unmap operation
2026-06-09 2:59 [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Jianping Li
2026-06-09 2:59 ` [PATCH v8 1/4] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool Jianping Li
@ 2026-06-09 2:59 ` Jianping Li
2026-06-09 2:59 ` [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jianping Li @ 2026-06-09 2:59 UTC (permalink / raw)
To: Srinivas Kandagatla, Amol Maheshwari
Cc: Ekansh Gupta, Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa,
Jorge Ramirez-Ortiz, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, stable, Dmitry Baryshkov, 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 multiple threads invoke unmap
concurrently, where one thread may remove the entry from the list while
another thread's unmap operation is still ongoing.
Fix this by removing the buffer entry from the list before calling the
unmap operation. If the unmap fails, the entry is re-added to the list
so that userspace can retry the unmap, or alternatively, the buffer
will be cleaned up during device release when the DSP process is torn
down and all DSP-side mappings are freed along with remaining buffers
in the list.
Fixes: 2419e55e532de ("misc: fastrpc: add mmap/unmap support")
Cc: stable@kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@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 | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 96961217b856..517884000331 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1889,9 +1889,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);
@@ -1905,6 +1902,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;
@@ -1912,6 +1910,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;
}
@@ -1924,7 +1923,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)
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-06-09 2:59 [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Jianping Li
2026-06-09 2:59 ` [PATCH v8 1/4] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool Jianping Li
2026-06-09 2:59 ` [PATCH v8 2/4] misc: fastrpc: Remove buffer from list prior to unmap operation Jianping Li
@ 2026-06-09 2:59 ` Jianping Li
2026-07-01 20:37 ` Srinivas Kandagatla
2026-06-09 2:59 ` [PATCH v8 4/4] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL Jianping Li
2026-07-01 20:39 ` (subset) [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Srinivas Kandagatla
4 siblings, 1 reply; 10+ messages in thread
From: Jianping Li @ 2026-06-09 2:59 UTC (permalink / raw)
To: Srinivas Kandagatla, Amol Maheshwari
Cc: Jianping Li, Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa,
Jorge Ramirez-Ortiz, linux-arm-msm, dri-devel, linux-kernel,
ekansh.gupta, quic_chennak, stable
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.
Additionally, the current implementation allows userspace to repeatedly
grow the Audio PD heap, but does not support shrinking it. This can lead
to unbounded memory usage over time, effectively causing a memory leak.
Fix this by allocating the entire Audio PD reserved-memory region during
rpmsg probe and tying its lifetime to the rpmsg channel. This removes
userspace-controlled alloc/free and ensures that memory is reclaimed only
when the DSP process is torn down.
Add explicit validation for remote_heap presence and size before sending
the memory to DSP, and fail early if the reserved-memory region is
missing or incomplete.
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 | 112 ++++++++++++++++++++++-------------------
1 file changed, 59 insertions(+), 53 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 517884000331..1942e74535e5 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;
@@ -1341,15 +1343,24 @@ 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;
+
+ if (!cctx->remote_heap || !cctx->remote_heap->dma_addr ||
+ !cctx->remote_heap->size) {
+ err = -ENOMEM;
+ dev_err(fl->sctx->dev,
+ "remote heap memory region is not added\n");
+ return err;
+ }
args = kzalloc_objs(*args, FASTRPC_CREATE_STATIC_PROCESS_NARGS);
if (!args)
@@ -1373,31 +1384,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;
@@ -1409,8 +1395,17 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
args[1].length = inbuf.namelen;
args[1].fd = -1;
- pages[0].addr = fl->cctx->remote_heap->dma_addr;
- pages[0].size = fl->cctx->remote_heap->size;
+ spin_lock_irqsave(&cctx->lock, flags);
+ if (!cctx->audio_init_mem) {
+ pages[0].addr = cctx->remote_heap->dma_addr;
+ pages[0].size = cctx->remote_heap->size;
+ cctx->audio_init_mem = true;
+ inbuf.pageslen = 1;
+ } else {
+ pages[0].addr = 0;
+ pages[0].size = 0;
+ }
+ spin_unlock_irqrestore(&cctx->lock, flags);
args[2].ptr = (u64)(uintptr_t) pages;
args[2].length = sizeof(*pages);
@@ -1428,27 +1423,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:
+ cctx->audio_init_mem = false;
kfree(name);
err:
kfree(args);
@@ -2415,12 +2390,23 @@ 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) {
+ err = -ENOMEM;
+ goto err_free_data;
+ }
+
+ 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,
@@ -2428,7 +2414,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"));
@@ -2487,6 +2472,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
misc_deregister(&data->secure_fdevice->miscdev);
err_free_data:
+ kfree(data->remote_heap);
kfree(data);
return err;
}
@@ -2509,6 +2495,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);
@@ -2526,8 +2513,27 @@ 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)
+ dev_err(&rpdev->dev,
+ "Failed to assign memory back to HLOS: dma_addr %pad size %#llx err %d\n",
+ &cctx->remote_heap->dma_addr, cctx->remote_heap->size, err);
+ }
+
+ kfree(cctx->remote_heap);
+ cctx->remote_heap = NULL;
of_platform_depopulate(&rpdev->dev);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-06-09 2:59 ` [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
@ 2026-07-01 20:37 ` Srinivas Kandagatla
2026-07-02 4:02 ` Ekansh Gupta
0 siblings, 1 reply; 10+ messages in thread
From: Srinivas Kandagatla @ 2026-07-01 20:37 UTC (permalink / raw)
To: Jianping Li, 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
On 6/9/26 3:59 AM, 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.
>
> Additionally, the current implementation allows userspace to repeatedly
> grow the Audio PD heap, but does not support shrinking it. This can lead
> to unbounded memory usage over time, effectively causing a memory leak.
>
> Fix this by allocating the entire Audio PD reserved-memory region during
> rpmsg probe and tying its lifetime to the rpmsg channel. This removes
> userspace-controlled alloc/free and ensures that memory is reclaimed only
> when the DSP process is torn down.
>
> Add explicit validation for remote_heap presence and size before sending
> the memory to DSP, and fail early if the reserved-memory region is
> missing or incomplete.
>
> 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 | 112 ++++++++++++++++++++++-------------------
> 1 file changed, 59 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 517884000331..1942e74535e5 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;
> @@ -1341,15 +1343,24 @@ 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;
> +
> + if (!cctx->remote_heap || !cctx->remote_heap->dma_addr ||
> + !cctx->remote_heap->size) {
> + err = -ENOMEM;
> + dev_err(fl->sctx->dev,
> + "remote heap memory region is not added\n");
> + return err;
> + }
>
> args = kzalloc_objs(*args, FASTRPC_CREATE_STATIC_PROCESS_NARGS);
> if (!args)
> @@ -1373,31 +1384,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;
>
> @@ -1409,8 +1395,17 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
> args[1].length = inbuf.namelen;
> args[1].fd = -1;
>
> - pages[0].addr = fl->cctx->remote_heap->dma_addr;
> - pages[0].size = fl->cctx->remote_heap->size;
> + spin_lock_irqsave(&cctx->lock, flags);
> + if (!cctx->audio_init_mem) {
> + pages[0].addr = cctx->remote_heap->dma_addr;
> + pages[0].size = cctx->remote_heap->size;
> + cctx->audio_init_mem = true;
> + inbuf.pageslen = 1;
> + } else {
> + pages[0].addr = 0;
> + pages[0].size = 0;
What is the expected behavoiur in this case?
> + }
> + spin_unlock_irqrestore(&cctx->lock, flags);
>
> args[2].ptr = (u64)(uintptr_t) pages;
> args[2].length = sizeof(*pages);
> @@ -1428,27 +1423,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:
> + cctx->audio_init_mem = false;
this can race.
> kfree(name);
> err:
> kfree(args);
> @@ -2415,12 +2390,23 @@ 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) {
> + err = -ENOMEM;
> + goto err_free_data;
> + }
> +
> + 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,
> @@ -2428,7 +2414,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"));
> @@ -2487,6 +2472,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
> misc_deregister(&data->secure_fdevice->miscdev);
>
> err_free_data:
> + kfree(data->remote_heap);
> kfree(data);
> return err;
> }
> @@ -2509,6 +2495,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);
> @@ -2526,8 +2513,27 @@ 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)
> + dev_err(&rpdev->dev,
> + "Failed to assign memory back to HLOS: dma_addr %pad size %#llx err %d\n",
> + &cctx->remote_heap->dma_addr, cctx->remote_heap->size, err);
> + }
> +
> + kfree(cctx->remote_heap);
> + cctx->remote_heap = NULL;
>
> of_platform_depopulate(&rpdev->dev);
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-07-01 20:37 ` Srinivas Kandagatla
@ 2026-07-02 4:02 ` Ekansh Gupta
2026-07-02 6:46 ` Srinivas Kandagatla
0 siblings, 1 reply; 10+ messages in thread
From: Ekansh Gupta @ 2026-07-02 4:02 UTC (permalink / raw)
To: Srinivas Kandagatla, Jianping Li, Amol Maheshwari
Cc: Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa, Jorge Ramirez-Ortiz,
linux-arm-msm, dri-devel, linux-kernel, quic_chennak, stable
On 02-07-2026 02:07, Srinivas Kandagatla wrote:
>
>
> On 6/9/26 3:59 AM, 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.
>>
>> Additionally, the current implementation allows userspace to repeatedly
>> grow the Audio PD heap, but does not support shrinking it. This can lead
>> to unbounded memory usage over time, effectively causing a memory leak.
>>
>> Fix this by allocating the entire Audio PD reserved-memory region during
>> rpmsg probe and tying its lifetime to the rpmsg channel. This removes
>> userspace-controlled alloc/free and ensures that memory is reclaimed only
>> when the DSP process is torn down.
>>
>> Add explicit validation for remote_heap presence and size before sending
>> the memory to DSP, and fail early if the reserved-memory region is
>> missing or incomplete.
>>
>> 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 | 112 ++++++++++++++++++++++-------------------
>> 1 file changed, 59 insertions(+), 53 deletions(-)
>>
>> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
>> index 517884000331..1942e74535e5 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;
>> @@ -1341,15 +1343,24 @@ 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;
>> +
>> + if (!cctx->remote_heap || !cctx->remote_heap->dma_addr ||
>> + !cctx->remote_heap->size) {
>> + err = -ENOMEM;
>> + dev_err(fl->sctx->dev,
>> + "remote heap memory region is not added\n");
>> + return err;
>> + }
>>
>> args = kzalloc_objs(*args, FASTRPC_CREATE_STATIC_PROCESS_NARGS);
>> if (!args)
>> @@ -1373,31 +1384,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;
>>
>> @@ -1409,8 +1395,17 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
>> args[1].length = inbuf.namelen;
>> args[1].fd = -1;
>>
>> - pages[0].addr = fl->cctx->remote_heap->dma_addr;
>> - pages[0].size = fl->cctx->remote_heap->size;
>> + spin_lock_irqsave(&cctx->lock, flags);
>> + if (!cctx->audio_init_mem) {
>> + pages[0].addr = cctx->remote_heap->dma_addr;
>> + pages[0].size = cctx->remote_heap->size;
>> + cctx->audio_init_mem = true;
>> + inbuf.pageslen = 1;
>> + } else {
>> + pages[0].addr = 0;
>> + pages[0].size = 0;
>
> What is the expected behavoiur in this case?
Audio daemon is expected to take the memory information to DSP audio PD
only the first time it goes and attaches there.
This is the case where daemon was killed but audio PD session is still
running. In such cases, daemon is not expected to take any memory
information to audio PD as the earlier shared information is already
there with audio PD which it is using irrespective of daemon state.>
>> + }
>> + spin_unlock_irqrestore(&cctx->lock, flags);
>>
>> args[2].ptr = (u64)(uintptr_t) pages;
>> args[2].length = sizeof(*pages);
>> @@ -1428,27 +1423,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:
>> + cctx->audio_init_mem = false;
> this can race.
>
>> kfree(name);
>> err:
>> kfree(args);
>> @@ -2415,12 +2390,23 @@ 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) {
>> + err = -ENOMEM;
>> + goto err_free_data;
>> + }
>> +
>> + 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,
>> @@ -2428,7 +2414,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"));
>> @@ -2487,6 +2472,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
>> misc_deregister(&data->secure_fdevice->miscdev);
>>
>> err_free_data:
>> + kfree(data->remote_heap);
>> kfree(data);
>> return err;
>> }
>> @@ -2509,6 +2495,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);
>> @@ -2526,8 +2513,27 @@ 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)
>> + dev_err(&rpdev->dev,
>> + "Failed to assign memory back to HLOS: dma_addr %pad size %#llx err %d\n",
>> + &cctx->remote_heap->dma_addr, cctx->remote_heap->size, err);
>> + }
>> +
>> + kfree(cctx->remote_heap);
>> + cctx->remote_heap = NULL;
>>
>> of_platform_depopulate(&rpdev->dev);
>>
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-07-02 4:02 ` Ekansh Gupta
@ 2026-07-02 6:46 ` Srinivas Kandagatla
2026-07-02 8:43 ` Ekansh Gupta
0 siblings, 1 reply; 10+ messages in thread
From: Srinivas Kandagatla @ 2026-07-02 6:46 UTC (permalink / raw)
To: Ekansh Gupta, Srinivas Kandagatla, Jianping Li, Amol Maheshwari
Cc: Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa, Jorge Ramirez-Ortiz,
linux-arm-msm, dri-devel, linux-kernel, quic_chennak, stable
On 7/2/26 5:02 AM, Ekansh Gupta wrote:
>>> @@ -1409,8 +1395,17 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
>>> args[1].length = inbuf.namelen;
>>> args[1].fd = -1;
>>>
>>> - pages[0].addr = fl->cctx->remote_heap->dma_addr;
>>> - pages[0].size = fl->cctx->remote_heap->size;
>>> + spin_lock_irqsave(&cctx->lock, flags);
>>> + if (!cctx->audio_init_mem) {
>>> + pages[0].addr = cctx->remote_heap->dma_addr;
>>> + pages[0].size = cctx->remote_heap->size;
>>> + cctx->audio_init_mem = true;
>>> + inbuf.pageslen = 1;
>>> + } else {
>>> + pages[0].addr = 0;
>>> + pages[0].size = 0;
>> What is the expected behavoiur in this case?
> Audio daemon is expected to take the memory information to DSP audio PD
> only the first time it goes and attaches there.
>
> This is the case where daemon was killed but audio PD session is still
> running. In such cases, daemon is not expected to take any memory
> information to audio PD as the earlier shared information is already
> there with audio PD which it is using irrespective of daemon state.>
Wow, this behavior is not documented or pl consider adding a comment
here, Can we not query the dsp before creating new audiopd service?
Does it make sense to attach instead of creating?
--srini
>>> + }
>>> + spin_unlock_irqrestore(&cctx->lock, flags);
>>>
>>> args[2].ptr = (u64)(uintptr_t) pages;
>>> args[2].length = sizeof(*pages);
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
2026-07-02 6:46 ` Srinivas Kandagatla
@ 2026-07-02 8:43 ` Ekansh Gupta
0 siblings, 0 replies; 10+ messages in thread
From: Ekansh Gupta @ 2026-07-02 8:43 UTC (permalink / raw)
To: Srinivas Kandagatla, Jianping Li, Amol Maheshwari
Cc: Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa, Jorge Ramirez-Ortiz,
linux-arm-msm, dri-devel, linux-kernel, quic_chennak, stable
On 02-07-2026 12:16, Srinivas Kandagatla wrote:
>
>
> On 7/2/26 5:02 AM, Ekansh Gupta wrote:
>>>> @@ -1409,8 +1395,17 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
>>>> args[1].length = inbuf.namelen;
>>>> args[1].fd = -1;
>>>>
>>>> - pages[0].addr = fl->cctx->remote_heap->dma_addr;
>>>> - pages[0].size = fl->cctx->remote_heap->size;
>>>> + spin_lock_irqsave(&cctx->lock, flags);
>>>> + if (!cctx->audio_init_mem) {
>>>> + pages[0].addr = cctx->remote_heap->dma_addr;
>>>> + pages[0].size = cctx->remote_heap->size;
>>>> + cctx->audio_init_mem = true;
>>>> + inbuf.pageslen = 1;
>>>> + } else {
>>>> + pages[0].addr = 0;
>>>> + pages[0].size = 0;
>>> What is the expected behavoiur in this case?
>> Audio daemon is expected to take the memory information to DSP audio PD
>> only the first time it goes and attaches there.
>>
>> This is the case where daemon was killed but audio PD session is still
>> running. In such cases, daemon is not expected to take any memory
>> information to audio PD as the earlier shared information is already
>> there with audio PD which it is using irrespective of daemon state.>
> Wow, this behavior is not documented or pl consider adding a comment
> here, Can we not query the dsp before creating new audiopd service?
Agree with your point about documentation, maybe Jianping can add the
information.
audio PD is generally not aware/affected by the state of daemon
process(other than the reverse request break) and there is no such query
supported to see if the audio PD already has the memory information.>
>
> Does it make sense to attach instead of creating?
Calling it attach as PD creation is not done by the daemon, PD is
statically created upon DSP boot-up, the daemon just acts as a listener
for that PD to take up reverse fastrpc request.>
> --srini
>
>>>> + }
>>>> + spin_unlock_irqrestore(&cctx->lock, flags);
>>>>
>>>> args[2].ptr = (u64)(uintptr_t) pages;
>>>> args[2].length = sizeof(*pages);
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v8 4/4] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL
2026-06-09 2:59 [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Jianping Li
` (2 preceding siblings ...)
2026-06-09 2:59 ` [PATCH v8 3/4] misc: fastrpc: Allocate entire reserved memory for Audio PD in probe Jianping Li
@ 2026-06-09 2:59 ` Jianping Li
2026-07-01 20:39 ` (subset) [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Srinivas Kandagatla
4 siblings, 0 replies; 10+ messages in thread
From: Jianping Li @ 2026-06-09 2:59 UTC (permalink / raw)
To: Srinivas Kandagatla, Amol Maheshwari
Cc: Ekansh Gupta, Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa,
Jorge Ramirez-Ortiz, linux-arm-msm, dri-devel, linux-kernel,
quic_chennak, Dmitry Baryshkov, 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.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@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 1942e74535e5..b4912b443b98 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -424,6 +424,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);
@@ -516,8 +519,7 @@ static void fastrpc_user_free(struct kref *ref)
struct fastrpc_map *map, *m;
struct fastrpc_buf *buf, *b;
- 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);
@@ -562,8 +564,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);
--
2.43.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: (subset) [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes
2026-06-09 2:59 [PATCH v8 0/4] misc: fastrpc: Add missing bug fixes Jianping Li
` (3 preceding siblings ...)
2026-06-09 2:59 ` [PATCH v8 4/4] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL Jianping Li
@ 2026-07-01 20:39 ` Srinivas Kandagatla
4 siblings, 0 replies; 10+ messages in thread
From: Srinivas Kandagatla @ 2026-07-01 20:39 UTC (permalink / raw)
To: Amol Maheshwari, Jianping Li
Cc: Arnd Bergmann, Greg Kroah-Hartman, Abel Vesa, linux-arm-msm,
dri-devel, linux-kernel, ekansh.gupta, quic_chennak,
Jorge Ramirez-Ortiz
On Tue, 09 Jun 2026 10:59:34 +0800, Jianping Li wrote:
> Add missing bug fixes in memory areas. This patch series fixes multiple memory
> handling issues in the FastRPC driver, primarily around the Audio PD remote heap.
>
> The Audio PD uses a reserved memory-region that is shared between HLOS
> and the DSP. Allocating and freeing this memory from userspace is unsafe,
> as the kernel cannot reliably determine when the DSP has finished using
> the buffers.
>
> [...]
Applied, thanks!
[1/4] misc: fastrpc: Fix initial memory allocation for Audio PD memory pool
commit: 36090f35ca19c1422bd56f03cdc3b5703ca18a15
[2/4] misc: fastrpc: Remove buffer from list prior to unmap operation
commit: 902b8ec9dd1098cc133cffa8be0b6378544f27ba
[4/4] misc: fastrpc: Allow fastrpc_buf_free() to accept NULL
commit: a4f06f06c20a72b2ee96fd964ce93a18e321bd0a
Best regards,
--
Srinivas Kandagatla <srini@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread