Skip to content

Commit 036f305

Browse files
committed
FROMLIST: misc: fastrpc: Allocate entire reserved memory for Audio PD in probe
The entire reserved-memory region is now assigned to DSP VMIDs during channel setup and stored in cctx->remote_heap. Memory is reclaimed in rpmsg_remove by revoking DSP permissions and freeing the buffer, tying heap lifecycle to the rpmsg channel. Link: https://lore.kernel.org/all/20260115082851.570-5-jianping.li@oss.qualcomm.com/ Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
1 parent 07e3995 commit 036f305

1 file changed

Lines changed: 45 additions & 50 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,8 @@ struct fastrpc_channel_ctx {
295295
struct kref refcount;
296296
/* Flag if dsp attributes are cached */
297297
bool valid_attributes;
298+
/* Flag if audio PD init mem was allocated */
299+
bool audio_init_mem;
298300
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
299301
struct fastrpc_device *secure_fdevice;
300302
struct fastrpc_device *fdevice;
@@ -1396,7 +1398,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13961398
struct fastrpc_phy_page pages[1];
13971399
char *name;
13981400
int err;
1399-
bool scm_done = false;
14001401
struct {
14011402
int client_id;
14021403
u32 namelen;
@@ -1426,31 +1427,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14261427
inbuf.client_id = fl->client_id;
14271428
inbuf.namelen = init.namelen;
14281429
inbuf.pageslen = 0;
1429-
if (!fl->cctx->remote_heap) {
1430-
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
1431-
&fl->cctx->remote_heap);
1432-
if (err)
1433-
goto err_name;
1434-
1435-
/* Map if we have any heap VMIDs associated with this ADSP Static Process. */
1436-
if (fl->cctx->vmcount) {
1437-
u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
1438-
1439-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
1440-
(u64)fl->cctx->remote_heap->size,
1441-
&src_perms, fl->cctx->vmperms,
1442-
fl->cctx->vmcount);
1443-
if (err) {
1444-
dev_err(fl->sctx->dev,
1445-
"Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
1446-
&fl->cctx->remote_heap->dma_addr,
1447-
fl->cctx->remote_heap->size, err);
1448-
goto err_map;
1449-
}
1450-
scm_done = true;
1451-
inbuf.pageslen = 1;
1452-
}
1453-
}
14541430

14551431
fl->pd = USER_PD;
14561432

@@ -1462,8 +1438,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14621438
args[1].length = inbuf.namelen;
14631439
args[1].fd = -1;
14641440

1465-
pages[0].addr = fl->cctx->remote_heap->dma_addr;
1466-
pages[0].size = fl->cctx->remote_heap->size;
1441+
if (!fl->cctx->audio_init_mem) {
1442+
pages[0].addr = fl->cctx->remote_heap->dma_addr;
1443+
pages[0].size = fl->cctx->remote_heap->size;
1444+
fl->cctx->audio_init_mem = true;
1445+
inbuf.pageslen = 1;
1446+
} else {
1447+
pages[0].addr = 0;
1448+
pages[0].size = 0;
1449+
}
14671450

14681451
args[2].ptr = (u64)(uintptr_t) pages;
14691452
args[2].length = sizeof(*pages);
@@ -1481,26 +1464,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14811464

14821465
return 0;
14831466
err_invoke:
1484-
if (fl->cctx->vmcount && scm_done) {
1485-
u64 src_perms = 0;
1486-
struct qcom_scm_vmperm dst_perms;
1487-
u32 i;
1488-
1489-
for (i = 0; i < fl->cctx->vmcount; i++)
1490-
src_perms |= BIT(fl->cctx->vmperms[i].vmid);
1491-
1492-
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
1493-
dst_perms.perm = QCOM_SCM_PERM_RWX;
1494-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
1495-
(u64)fl->cctx->remote_heap->size,
1496-
&src_perms, &dst_perms, 1);
1497-
if (err)
1498-
dev_err(fl->sctx->dev, "Failed to assign memory dma_addr %pad size 0x%llx err %d\n",
1499-
&fl->cctx->remote_heap->dma_addr, fl->cctx->remote_heap->size, err);
1500-
}
1501-
err_map:
1502-
fastrpc_buf_free(fl->cctx->remote_heap);
1503-
err_name:
1467+
fl->cctx->audio_init_mem = false;
15041468
kfree(name);
15051469
err:
15061470
kfree(args);
@@ -2516,7 +2480,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
25162480
}
25172481
}
25182482

2519-
if (domain_id == SDSP_DOMAIN_ID) {
2483+
if (domain_id == SDSP_DOMAIN_ID || domain_id == ADSP_DOMAIN_ID) {
25202484
struct resource res;
25212485
u64 src_perms;
25222486

@@ -2527,6 +2491,15 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
25272491
qcom_scm_assign_mem(res.start, resource_size(&res), &src_perms,
25282492
data->vmperms, data->vmcount);
25292493
}
2494+
if (domain_id == ADSP_DOMAIN_ID) {
2495+
data->remote_heap =
2496+
kzalloc(sizeof(*data->remote_heap), GFP_KERNEL);
2497+
if (!data->remote_heap)
2498+
return -ENOMEM;
2499+
2500+
data->remote_heap->dma_addr = res.start;
2501+
data->remote_heap->size = resource_size(&res);
2502+
}
25302503

25312504
}
25322505

@@ -2608,10 +2581,13 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
26082581
struct fastrpc_buf *buf, *b;
26092582
struct fastrpc_user *user;
26102583
unsigned long flags;
2584+
bool skip_free = false;
2585+
int err;
26112586

26122587
/* No invocations past this point */
26132588
spin_lock_irqsave(&cctx->lock, flags);
26142589
cctx->rpdev = NULL;
2590+
cctx->audio_init_mem = false;
26152591
list_for_each_entry(user, &cctx->users, user)
26162592
fastrpc_notify_users(user);
26172593
spin_unlock_irqrestore(&cctx->lock, flags);
@@ -2625,7 +2601,26 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
26252601
list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
26262602
list_del(&buf->node);
26272603

2628-
fastrpc_buf_free(cctx->remote_heap);
2604+
if (cctx->remote_heap) {
2605+
if (cctx->vmcount) {
2606+
u64 src_perms = 0;
2607+
struct qcom_scm_vmperm dst_perms;
2608+
2609+
for (u32 i = 0; i < cctx->vmcount; i++)
2610+
src_perms |= BIT(cctx->vmperms[i].vmid);
2611+
2612+
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
2613+
dst_perms.perm = QCOM_SCM_PERM_RWX;
2614+
2615+
err = qcom_scm_assign_mem(cctx->remote_heap->dma_addr,
2616+
cctx->remote_heap->size,
2617+
&src_perms, &dst_perms, 1);
2618+
if (err)
2619+
skip_free = true;
2620+
}
2621+
if (!skip_free)
2622+
fastrpc_buf_free(cctx->remote_heap);
2623+
}
26292624

26302625
of_platform_depopulate(&rpdev->dev);
26312626

0 commit comments

Comments
 (0)