Skip to content

Commit

Permalink
misc: fastrpc: Avoid free of DMA buffer in interrupt context
Browse files Browse the repository at this point in the history
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 <thierry.escande@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Thierry Escande authored and Greg Kroah-Hartman committed Mar 27, 2019
1 parent 34bf9ce commit 8e7389c
Showing 1 changed file with 17 additions and 1 deletion.
18 changes: 17 additions & 1 deletion drivers/misc/fastrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ struct fastrpc_invoke_ctx {
struct kref refcount;
struct list_head node; /* list of ctxs */
struct completion work;
struct work_struct put_work;
struct fastrpc_msg msg;
struct fastrpc_user *fl;
struct fastrpc_remote_arg *rpra;
Expand Down Expand Up @@ -311,6 +312,14 @@ static void fastrpc_context_put(struct fastrpc_invoke_ctx *ctx)
kref_put(&ctx->refcount, fastrpc_context_free);
}

static void fastrpc_context_put_wq(struct work_struct *work)
{
struct fastrpc_invoke_ctx *ctx =
container_of(work, struct fastrpc_invoke_ctx, put_work);

fastrpc_context_put(ctx);
}

static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
struct fastrpc_user *user, u32 kernel, u32 sc,
struct fastrpc_invoke_args *args)
Expand Down Expand Up @@ -345,6 +354,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
ctx->tgid = user->tgid;
ctx->cctx = cctx;
init_completion(&ctx->work);
INIT_WORK(&ctx->put_work, fastrpc_context_put_wq);

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

ctx->retval = rsp->retval;
complete(&ctx->work);
fastrpc_context_put(ctx);

/*
* The DMA buffer associated with the context cannot be freed in
* interrupt context so schedule it through a worker thread to
* avoid a kernel BUG.
*/
schedule_work(&ctx->put_work);

return 0;
}
Expand Down

0 comments on commit 8e7389c

Please sign in to comment.