Skip to content

Commit 02c54de

Browse files
Jianping-Liekanshibu
authored andcommitted
FROMLIST: misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
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. Link: https://lore.kernel.org/all/20260409062617.1182-4-jianping.li@oss.qualcomm.com/ Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
1 parent 4e84a34 commit 02c54de

1 file changed

Lines changed: 51 additions & 51 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ struct fastrpc_channel_ctx {
292292
struct kref refcount;
293293
/* Flag if dsp attributes are cached */
294294
bool valid_attributes;
295+
/* Flag if audio PD init mem was allocated */
296+
bool audio_init_mem;
295297
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
296298
struct fastrpc_device *secure_fdevice;
297299
struct fastrpc_device *fdevice;
@@ -1417,15 +1419,16 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14171419
struct fastrpc_init_create_static init;
14181420
struct fastrpc_invoke_args *args;
14191421
struct fastrpc_phy_page pages[1];
1422+
struct fastrpc_channel_ctx *cctx = fl->cctx;
14201423
char *name;
14211424
int err;
1422-
bool scm_done = false;
14231425
struct {
14241426
int client_id;
14251427
u32 namelen;
14261428
u32 pageslen;
14271429
} inbuf;
14281430
u32 sc;
1431+
unsigned long flags;
14291432

14301433
args = kzalloc_objs(*args, FASTRPC_CREATE_STATIC_PROCESS_NARGS);
14311434
if (!args)
@@ -1449,31 +1452,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14491452
inbuf.client_id = fl->client_id;
14501453
inbuf.namelen = init.namelen;
14511454
inbuf.pageslen = 0;
1452-
if (!fl->cctx->remote_heap) {
1453-
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
1454-
&fl->cctx->remote_heap);
1455-
if (err)
1456-
goto err_name;
1457-
1458-
/* Map if we have any heap VMIDs associated with this ADSP Static Process. */
1459-
if (fl->cctx->vmcount) {
1460-
u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
1461-
1462-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
1463-
(u64)fl->cctx->remote_heap->size,
1464-
&src_perms,
1465-
fl->cctx->vmperms, fl->cctx->vmcount);
1466-
if (err) {
1467-
dev_err(fl->sctx->dev,
1468-
"Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
1469-
&fl->cctx->remote_heap->dma_addr,
1470-
fl->cctx->remote_heap->size, err);
1471-
goto err_map;
1472-
}
1473-
scm_done = true;
1474-
inbuf.pageslen = 1;
1475-
}
1476-
}
14771455

14781456
fl->pd = USER_PD;
14791457

@@ -1485,8 +1463,25 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14851463
args[1].length = inbuf.namelen;
14861464
args[1].fd = -1;
14871465

1488-
pages[0].addr = fl->cctx->remote_heap->dma_addr;
1489-
pages[0].size = fl->cctx->remote_heap->size;
1466+
spin_lock_irqsave(&cctx->lock, flags);
1467+
if (!fl->cctx->audio_init_mem) {
1468+
if (!fl->cctx->remote_heap ||
1469+
!fl->cctx->remote_heap->dma_addr ||
1470+
!fl->cctx->remote_heap->size) {
1471+
spin_unlock_irqrestore(&cctx->lock, flags);
1472+
err = -ENOMEM;
1473+
goto err;
1474+
}
1475+
1476+
pages[0].addr = fl->cctx->remote_heap->dma_addr;
1477+
pages[0].size = fl->cctx->remote_heap->size;
1478+
fl->cctx->audio_init_mem = true;
1479+
inbuf.pageslen = 1;
1480+
} else {
1481+
pages[0].addr = 0;
1482+
pages[0].size = 0;
1483+
}
1484+
spin_unlock_irqrestore(&cctx->lock, flags);
14901485

14911486
args[2].ptr = (u64)(uintptr_t) pages;
14921487
args[2].length = sizeof(*pages);
@@ -1504,26 +1499,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
15041499

15051500
return 0;
15061501
err_invoke:
1507-
if (fl->cctx->vmcount && scm_done) {
1508-
u64 src_perms = 0;
1509-
struct qcom_scm_vmperm dst_perms;
1510-
u32 i;
1511-
1512-
for (i = 0; i < fl->cctx->vmcount; i++)
1513-
src_perms |= BIT(fl->cctx->vmperms[i].vmid);
1514-
1515-
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
1516-
dst_perms.perm = QCOM_SCM_PERM_RWX;
1517-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
1518-
(u64)fl->cctx->remote_heap->size,
1519-
&src_perms, &dst_perms, 1);
1520-
if (err)
1521-
dev_err(fl->sctx->dev, "Failed to assign memory dma_addr %pad size 0x%llx err %d\n",
1522-
&fl->cctx->remote_heap->dma_addr, fl->cctx->remote_heap->size, err);
1523-
}
1524-
err_map:
1525-
fastrpc_buf_free(fl->cctx->remote_heap);
1526-
err_name:
1502+
fl->cctx->audio_init_mem = false;
15271503
kfree(name);
15281504
err:
15291505
kfree(args);
@@ -2538,7 +2514,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
25382514
}
25392515
}
25402516

2541-
if (domain_id == SDSP_DOMAIN_ID) {
2517+
if (domain_id == SDSP_DOMAIN_ID || domain_id == ADSP_DOMAIN_ID) {
25422518
struct resource res;
25432519
u64 src_perms;
25442520

@@ -2550,6 +2526,15 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
25502526
data->vmperms, data->vmcount);
25512527
}
25522528

2529+
if (domain_id == ADSP_DOMAIN_ID) {
2530+
data->remote_heap =
2531+
kzalloc_obj(*data->remote_heap, GFP_KERNEL);
2532+
if (!data->remote_heap)
2533+
return -ENOMEM;
2534+
2535+
data->remote_heap->dma_addr = res.start;
2536+
data->remote_heap->size = resource_size(&res);
2537+
}
25532538
}
25542539

25552540
secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain"));
@@ -2630,6 +2615,7 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
26302615
struct fastrpc_buf *buf, *b;
26312616
struct fastrpc_user *user;
26322617
unsigned long flags;
2618+
int err;
26332619

26342620
/* No invocations past this point */
26352621
spin_lock_irqsave(&cctx->lock, flags);
@@ -2647,8 +2633,22 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
26472633
list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
26482634
list_del(&buf->node);
26492635

2650-
if (cctx->remote_heap)
2651-
fastrpc_buf_free(cctx->remote_heap);
2636+
if (cctx->remote_heap && cctx->vmcount) {
2637+
u64 src_perms = 0;
2638+
struct qcom_scm_vmperm dst_perms;
2639+
2640+
for (u32 i = 0; i < cctx->vmcount; i++)
2641+
src_perms |= BIT(cctx->vmperms[i].vmid);
2642+
2643+
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
2644+
dst_perms.perm = QCOM_SCM_PERM_RWX;
2645+
2646+
err = qcom_scm_assign_mem(cctx->remote_heap->dma_addr,
2647+
cctx->remote_heap->size, &src_perms,
2648+
&dst_perms, 1);
2649+
if (!err)
2650+
fastrpc_buf_free(cctx->remote_heap);
2651+
}
26522652

26532653
of_platform_depopulate(&rpdev->dev);
26542654

0 commit comments

Comments
 (0)