Skip to content

Commit fcc978d

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 9c111d9 commit fcc978d

1 file changed

Lines changed: 45 additions & 48 deletions

File tree

drivers/misc/fastrpc.c

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ struct fastrpc_channel_ctx {
289289
struct kref refcount;
290290
/* Flag if dsp attributes are cached */
291291
bool valid_attributes;
292+
/* Flag if audio PD init mem was allocated */
293+
bool audio_init_mem;
292294
u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
293295
struct fastrpc_device *secure_fdevice;
294296
struct fastrpc_device *fdevice;
@@ -1365,7 +1367,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13651367
struct fastrpc_phy_page pages[1];
13661368
char *name;
13671369
int err;
1368-
bool scm_done = false;
13691370
struct {
13701371
int client_id;
13711372
u32 namelen;
@@ -1395,29 +1396,6 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
13951396
inbuf.client_id = fl->client_id;
13961397
inbuf.namelen = init.namelen;
13971398
inbuf.pageslen = 0;
1398-
if (!fl->cctx->remote_heap) {
1399-
err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
1400-
&fl->cctx->remote_heap);
1401-
if (err)
1402-
goto err_name;
1403-
1404-
/* Map if we have any heap VMIDs associated with this ADSP Static Process. */
1405-
if (fl->cctx->vmcount) {
1406-
u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
1407-
1408-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
1409-
(u64)fl->cctx->remote_heap->size,
1410-
&src_perms,
1411-
fl->cctx->vmperms, fl->cctx->vmcount);
1412-
if (err) {
1413-
dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
1414-
fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
1415-
goto err_map;
1416-
}
1417-
scm_done = true;
1418-
inbuf.pageslen = 1;
1419-
}
1420-
}
14211399

14221400
fl->pd = USER_PD;
14231401

@@ -1429,8 +1407,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14291407
args[1].length = inbuf.namelen;
14301408
args[1].fd = -1;
14311409

1432-
pages[0].addr = fl->cctx->remote_heap->phys;
1433-
pages[0].size = fl->cctx->remote_heap->size;
1410+
if (!fl->cctx->audio_init_mem) {
1411+
pages[0].addr = fl->cctx->remote_heap->phys;
1412+
pages[0].size = fl->cctx->remote_heap->size;
1413+
fl->cctx->audio_init_mem = true;
1414+
inbuf.pageslen = 1;
1415+
} else {
1416+
pages[0].addr = 0;
1417+
pages[0].size = 0;
1418+
}
14341419

14351420
args[2].ptr = (u64)(uintptr_t) pages;
14361421
args[2].length = sizeof(*pages);
@@ -1448,26 +1433,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
14481433

14491434
return 0;
14501435
err_invoke:
1451-
if (fl->cctx->vmcount && scm_done) {
1452-
u64 src_perms = 0;
1453-
struct qcom_scm_vmperm dst_perms;
1454-
u32 i;
1455-
1456-
for (i = 0; i < fl->cctx->vmcount; i++)
1457-
src_perms |= BIT(fl->cctx->vmperms[i].vmid);
1458-
1459-
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
1460-
dst_perms.perm = QCOM_SCM_PERM_RWX;
1461-
err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
1462-
(u64)fl->cctx->remote_heap->size,
1463-
&src_perms, &dst_perms, 1);
1464-
if (err)
1465-
dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
1466-
fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
1467-
}
1468-
err_map:
1469-
fastrpc_buf_free(fl->cctx->remote_heap);
1470-
err_name:
1436+
fl->cctx->audio_init_mem = false;
14711437
kfree(name);
14721438
err:
14731439
kfree(args);
@@ -2461,7 +2427,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
24612427
}
24622428
}
24632429

2464-
if (domain_id == SDSP_DOMAIN_ID) {
2430+
if (domain_id == SDSP_DOMAIN_ID || domain_id == ADSP_DOMAIN_ID) {
24652431
struct resource res;
24662432
u64 src_perms;
24672433

@@ -2472,6 +2438,15 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
24722438
qcom_scm_assign_mem(res.start, resource_size(&res), &src_perms,
24732439
data->vmperms, data->vmcount);
24742440
}
2441+
if (domain_id == ADSP_DOMAIN_ID) {
2442+
data->remote_heap =
2443+
kzalloc(sizeof(*data->remote_heap), GFP_KERNEL);
2444+
if (!data->remote_heap)
2445+
return -ENOMEM;
2446+
2447+
data->remote_heap->phys = res.start;
2448+
data->remote_heap->size = resource_size(&res);
2449+
}
24752450

24762451
}
24772452

@@ -2552,10 +2527,13 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
25522527
struct fastrpc_buf *buf, *b;
25532528
struct fastrpc_user *user;
25542529
unsigned long flags;
2530+
bool skip_free = false;
2531+
int err;
25552532

25562533
/* No invocations past this point */
25572534
spin_lock_irqsave(&cctx->lock, flags);
25582535
cctx->rpdev = NULL;
2536+
cctx->audio_init_mem = false;
25592537
list_for_each_entry(user, &cctx->users, user)
25602538
fastrpc_notify_users(user);
25612539
spin_unlock_irqrestore(&cctx->lock, flags);
@@ -2569,7 +2547,26 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
25692547
list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
25702548
list_del(&buf->node);
25712549

2572-
fastrpc_buf_free(cctx->remote_heap);
2550+
if (cctx->remote_heap) {
2551+
if (cctx->vmcount) {
2552+
u64 src_perms = 0;
2553+
struct qcom_scm_vmperm dst_perms;
2554+
2555+
for (u32 i = 0; i < cctx->vmcount; i++)
2556+
src_perms |= BIT(cctx->vmperms[i].vmid);
2557+
2558+
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
2559+
dst_perms.perm = QCOM_SCM_PERM_RWX;
2560+
2561+
err = qcom_scm_assign_mem(cctx->remote_heap->phys,
2562+
cctx->remote_heap->size,
2563+
&src_perms, &dst_perms, 1);
2564+
if (err)
2565+
skip_free = true;
2566+
}
2567+
if (!skip_free)
2568+
fastrpc_buf_free(cctx->remote_heap);
2569+
}
25732570

25742571
of_platform_depopulate(&rpdev->dev);
25752572

0 commit comments

Comments
 (0)