Skip to content

Commit 76e8e4a

Browse files
abelvesagregkh
authored andcommitted
misc: fastrpc: Safekeep mmaps on interrupted invoke
If the userspace daemon is killed in the middle of an invoke (e.g. audiopd listerner invoke), we need to skip the unmapping on device release, otherwise the DSP will crash. So lets safekeep all the maps only if there is in invoke interrupted, by attaching them to the channel context (which is resident until RPMSG driver is removed), and free them on RPMSG driver remove. Signed-off-by: Abel Vesa <[email protected]> Signed-off-by: Srinivas Kandagatla <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 0871561 commit 76e8e4a

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

drivers/misc/fastrpc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ struct fastrpc_channel_ctx {
275275
struct fastrpc_device *secure_fdevice;
276276
struct fastrpc_device *fdevice;
277277
struct fastrpc_buf *remote_heap;
278+
struct list_head invoke_interrupted_mmaps;
278279
bool secure;
279280
bool unsigned_support;
280281
};
@@ -1109,6 +1110,8 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
11091110
struct fastrpc_invoke_args *args)
11101111
{
11111112
struct fastrpc_invoke_ctx *ctx = NULL;
1113+
struct fastrpc_buf *buf, *b;
1114+
11121115
int err = 0;
11131116

11141117
if (!fl->sctx)
@@ -1172,6 +1175,13 @@ static int fastrpc_internal_invoke(struct fastrpc_user *fl, u32 kernel,
11721175
fastrpc_context_put(ctx);
11731176
}
11741177

1178+
if (err == -ERESTARTSYS) {
1179+
list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
1180+
list_del(&buf->node);
1181+
list_add_tail(&buf->node, &fl->cctx->invoke_interrupted_mmaps);
1182+
}
1183+
}
1184+
11751185
if (err)
11761186
dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err);
11771187

@@ -2278,6 +2288,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
22782288
dev_set_drvdata(&rpdev->dev, data);
22792289
dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32));
22802290
INIT_LIST_HEAD(&data->users);
2291+
INIT_LIST_HEAD(&data->invoke_interrupted_mmaps);
22812292
spin_lock_init(&data->lock);
22822293
idr_init(&data->ctx_idr);
22832294
data->domain_id = domain_id;
@@ -2302,6 +2313,7 @@ static void fastrpc_notify_users(struct fastrpc_user *user)
23022313
static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
23032314
{
23042315
struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev);
2316+
struct fastrpc_buf *buf, *b;
23052317
struct fastrpc_user *user;
23062318
unsigned long flags;
23072319

@@ -2316,6 +2328,9 @@ static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
23162328
if (cctx->secure_fdevice)
23172329
misc_deregister(&cctx->secure_fdevice->miscdev);
23182330

2331+
list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
2332+
list_del(&buf->node);
2333+
23192334
if (cctx->remote_heap)
23202335
fastrpc_buf_free(cctx->remote_heap);
23212336

0 commit comments

Comments
 (0)