[RFC PATCH v2] remoteproc: xlnx: initialize mailbox work before requesting channels
From: Runyu Xiao
Date: Thu Jul 16 2026 - 22:31:28 EST
zynqmp_r5_setup_mbox() installs zynqmp_r5_mb_rx_cb() as the mailbox RX
callback before requesting the mailbox channels, but initializes
ipi->mbox_work only after both channels have been requested. Once the RX
channel is active, a notification delivered before the late INIT_WORK()
would make the callback queue an uninitialized work item.
Initialize the work item before requesting channels. Also drain the work
before freeing the mailbox state, after the channels have been released so
no new callbacks can queue it.
This issue was found by our static analysis tool and then confirmed by
manual review of the mailbox setup sequence. The callback is published
before the channel requests complete, so the work item should be ready
before the mailbox provider can invoke it.
A QEMU PoC modeled a mailbox notification delivered after the RX callback
became reachable but before the delayed INIT_WORK(). DEBUG_OBJECTS reported
queueing an uninitialized work item from the zynqmp_r5_setup_mbox() path.
This is sent as an RFC because the practical trigger depends on the ZynqMP
IPI mailbox provider and firmware delivery timing. If the provider cannot
invoke the RX callback until after setup returns, this is a defensive
lifecycle cleanup rather than a reachable race on current systems.
Fixes: 5dfb28c257b7 ("remoteproc: xilinx: Add mailbox channels for rpmsg")
Signed-off-by: Runyu Xiao <runyu.xiao@xxxxxxxxxx>
---
Changes in v2:
- Follow Tanmay's suggestion and keep zynqmp_r5_setup_mbox() taking the
child device pointer. Do not move the r5_core assignment in this patch.
- Only move INIT_WORK() before channel requests and drain the work in
zynqmp_r5_free_mbox().
drivers/remoteproc/xlnx_r5_remoteproc.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 3349d1877751..e36918b8d234 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -279,6 +279,8 @@ static struct mbox_info *zynqmp_r5_setup_mbox(struct device *cdev)
if (!ipi)
return NULL;
+ INIT_WORK(&ipi->mbox_work, handle_event_notified);
+
mbox_cl = &ipi->mbox_cl;
mbox_cl->rx_callback = zynqmp_r5_mb_rx_cb;
mbox_cl->tx_block = false;
@@ -305,8 +307,6 @@ static struct mbox_info *zynqmp_r5_setup_mbox(struct device *cdev)
return NULL;
}
- INIT_WORK(&ipi->mbox_work, handle_event_notified);
-
return ipi;
}
@@ -325,6 +325,8 @@ static void zynqmp_r5_free_mbox(struct mbox_info *ipi)
ipi->rx_chan = NULL;
}
+ cancel_work_sync(&ipi->mbox_work);
+
kfree(ipi);
}
--
2.34.1