[PATCH AUTOSEL 6.18-5.10] firmware: imx: scu-irq: Init workqueue before request mbox channel
Sasha Levin
sashal at kernel.org
Tue Dec 9 19:48:58 PST 2025
From: Peng Fan <peng.fan at nxp.com>
[ Upstream commit 81fb53feb66a3aefbf6fcab73bb8d06f5b0c54ad ]
With mailbox channel requested, there is possibility that interrupts may
come in, so need to make sure the workqueue is initialized before
the queue is scheduled by mailbox rx callback.
Reviewed-by: Frank Li <Frank.Li at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
LLM Generated explanations, may be completely bogus:
## Analysis Summary
### What the Bug Is
This commit fixes a classic **initialization race condition** in the
i.MX SCU IRQ driver. The problem is:
1. `mbox_request_channel_byname(cl, "gip3")` is called, which sets up a
mailbox channel with `imx_scu_irq_callback` as the receive callback
2. Once the channel is established, interrupts from the System
Controller Unit (SCU) can trigger the callback **at any time**
3. The callback (`imx_scu_irq_callback` at line 175-178) calls
`schedule_work(&imx_sc_irq_work)`
4. **But** `INIT_WORK(&imx_sc_irq_work, ...)` was being called **after**
the mailbox channel was requested
If an interrupt arrives in the window between
`mbox_request_channel_byname()` and `INIT_WORK()`, it would schedule an
uninitialized work struct, leading to undefined behavior, crashes, or
memory corruption in the workqueue subsystem.
### The Fix
The fix is trivially correct: move `INIT_WORK()` to **before**
`mbox_request_channel_byname()`. This ensures the work struct is
properly initialized before any callback can possibly use it.
### Bug Origin
The bug was introduced in commit `851826c7566e9` ("firmware: imx: enable
imx scu general irq function") in kernel v5.2-rc1 when this driver was
first created. The initialization order was wrong from the very
beginning.
### Stable Kernel Criteria Assessment
| Criterion | Assessment |
|-----------|------------|
| Obviously correct | ✅ Yes - classic "initialize before use" pattern |
| Fixes real bug | ✅ Yes - race condition causing potential crashes |
| Small and contained | ✅ Yes - moves one line of code |
| No new features | ✅ Correct - purely a fix |
| Tested | ✅ Has Reviewed-by from NXP engineer |
| Low risk | ✅ Cannot introduce regressions |
### Risk vs. Benefit
- **Risk**: Extremely low - the work struct must be initialized before
use regardless of when the first interrupt arrives; moving
initialization earlier cannot break anything
- **Benefit**: Prevents crashes on i.MX SoC platforms (used in embedded
systems, automotive, IoT devices) where early interrupts could trigger
the race
### Dependencies
None - this is a self-contained single-line reordering fix that should
apply cleanly to any kernel with this driver (5.2+).
### Conclusion
This is an ideal stable backport candidate. It fixes a real
initialization race condition that can cause crashes, the fix is
obviously correct (a single line moved earlier in the initialization
sequence), it's minimal and surgical, and it affects real users of i.MX
SoC platforms. The only missing element is an explicit `Cc:
stable at vger.kernel.org` tag, but the fix clearly meets all stable kernel
rules.
**YES**
drivers/firmware/imx/imx-scu-irq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c
index 6125cccc9ba79..53bde775a1bf6 100644
--- a/drivers/firmware/imx/imx-scu-irq.c
+++ b/drivers/firmware/imx/imx-scu-irq.c
@@ -214,6 +214,8 @@ int imx_scu_enable_general_irq_channel(struct device *dev)
cl->dev = dev;
cl->rx_callback = imx_scu_irq_callback;
+ INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler);
+
/* SCU general IRQ uses general interrupt channel 3 */
ch = mbox_request_channel_byname(cl, "gip3");
if (IS_ERR(ch)) {
@@ -223,8 +225,6 @@ int imx_scu_enable_general_irq_channel(struct device *dev)
return ret;
}
- INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler);
-
if (!of_parse_phandle_with_args(dev->of_node, "mboxes",
"#mbox-cells", 0, &spec))
i = of_alias_get_id(spec.np, "mu");
--
2.51.0
More information about the linux-arm-kernel
mailing list