Skip to content

Commit 8e7389c

Browse files
Thierry Escandegregkh
authored andcommitted
misc: fastrpc: Avoid free of DMA buffer in interrupt context
When the remote DSP invocation is interrupted by the user, the associated DMA buffer can be freed in interrupt context causing a kernel BUG. This patch adds a worker thread associated to the fastrpc context. It is scheduled in the rpmsg callback to decrease its refcount out of the interrupt context. Fixes: c68cfb7 ("misc: fastrpc: Add support for context Invoke method") Signed-off-by: Thierry Escande <[email protected]> Signed-off-by: Srinivas Kandagatla <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 34bf9ce commit 8e7389c

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/misc/fastrpc.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ struct fastrpc_invoke_ctx {
149149
struct kref refcount;
150150
struct list_head node; /* list of ctxs */
151151
struct completion work;
152+
struct work_struct put_work;
152153
struct fastrpc_msg msg;
153154
struct fastrpc_user *fl;
154155
struct fastrpc_remote_arg *rpra;
@@ -311,6 +312,14 @@ static void fastrpc_context_put(struct fastrpc_invoke_ctx *ctx)
311312
kref_put(&ctx->refcount, fastrpc_context_free);
312313
}
313314

315+
static void fastrpc_context_put_wq(struct work_struct *work)
316+
{
317+
struct fastrpc_invoke_ctx *ctx =
318+
container_of(work, struct fastrpc_invoke_ctx, put_work);
319+
320+
fastrpc_context_put(ctx);
321+
}
322+
314323
static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
315324
struct fastrpc_user *user, u32 kernel, u32 sc,
316325
struct fastrpc_invoke_args *args)
@@ -345,6 +354,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
345354
ctx->tgid = user->tgid;
346355
ctx->cctx = cctx;
347356
init_completion(&ctx->work);
357+
INIT_WORK(&ctx->put_work, fastrpc_context_put_wq);
348358

349359
spin_lock(&user->lock);
350360
list_add_tail(&ctx->node, &user->pending);
@@ -1349,7 +1359,13 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
13491359

13501360
ctx->retval = rsp->retval;
13511361
complete(&ctx->work);
1352-
fastrpc_context_put(ctx);
1362+
1363+
/*
1364+
* The DMA buffer associated with the context cannot be freed in
1365+
* interrupt context so schedule it through a worker thread to
1366+
* avoid a kernel BUG.
1367+
*/
1368+
schedule_work(&ctx->put_work);
13531369

13541370
return 0;
13551371
}

0 commit comments

Comments
 (0)