diff options
author | Arnaud Pouliquen <arnaud.pouliquen@foss.st.com> | 2023-03-31 19:06:34 +0300 |
---|---|---|
committer | Mathieu Poirier <mathieu.poirier@linaro.org> | 2023-04-03 20:03:50 +0300 |
commit | 35bdafda40cc343ad2ba2cce105eba03a70241cc (patch) | |
tree | baaf3c7a1283bc2b15189fe9181fe17fb6c6220c /drivers/remoteproc | |
parent | 8666071391f473bfb1c0935576e3bf9c94b04f4e (diff) | |
download | linux-35bdafda40cc343ad2ba2cce105eba03a70241cc.tar.xz |
remoteproc: stm32_rproc: Add mutex protection for workqueue
The workqueue may execute late even after remoteproc is stopped or
stopping, some resources (rpmsg device and endpoint) have been
released in rproc_stop_subdevices(), then rproc_vq_interrupt()
accessing these resources will cause kernel dump.
Call trace:
virtqueue_add_inbuf
virtqueue_add_inbuf
rpmsg_recv_single
rpmsg_recv_done
vring_interrupt
stm32_rproc_mb_vq_work
process_one_work
worker_thread
kthread
Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@foss.st.com>
Link: https://lore.kernel.org/r/20230331160634.3113031-1-arnaud.pouliquen@foss.st.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Diffstat (limited to 'drivers/remoteproc')
-rw-r--r-- | drivers/remoteproc/stm32_rproc.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index 23c1690b8d73..8746cbb1f168 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -291,8 +291,16 @@ static void stm32_rproc_mb_vq_work(struct work_struct *work) struct stm32_mbox *mb = container_of(work, struct stm32_mbox, vq_work); struct rproc *rproc = dev_get_drvdata(mb->client.dev); + mutex_lock(&rproc->lock); + + if (rproc->state != RPROC_RUNNING) + goto unlock_mutex; + if (rproc_vq_interrupt(rproc, mb->vq_id) == IRQ_NONE) dev_dbg(&rproc->dev, "no message found in vq%d\n", mb->vq_id); + +unlock_mutex: + mutex_unlock(&rproc->lock); } static void stm32_rproc_mb_callback(struct mbox_client *cl, void *data) |