* [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports
@ 2026-04-23 14:19 Tudor Ambarus
2026-04-23 14:19 ` [PATCH 1/4] firmware: samsung: acpm: Fix cross-thread RX length corruption Tudor Ambarus
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
Fixes for bugs that were identified by sashiko when proposing the
GS101 ACPM TMU addition:
https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
Tudor Ambarus (4):
firmware: samsung: acpm: Fix cross-thread RX length corruption
firmware: samsung: acpm: Fix sequence number leak and infinite loop
firmware: samsung: acpm: Fix mailbox channel leak on probe error
firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR
drivers/firmware/samsung/exynos-acpm-dvfs.c | 3 ++
drivers/firmware/samsung/exynos-acpm.c | 32 +++++++++++++++-------
.../linux/firmware/samsung/exynos-acpm-protocol.h | 3 +-
3 files changed, 27 insertions(+), 11 deletions(-)
---
base-commit: 2e68039281932e6dc37718a1ea7cbb8e2cda42e6
change-id: 20260423-acpm-fixes-sashiko-reports-ae28b6ed5581
Best regards,
--
Tudor Ambarus <tudor.ambarus@linaro.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] firmware: samsung: acpm: Fix cross-thread RX length corruption
2026-04-23 14:19 [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports Tudor Ambarus
@ 2026-04-23 14:19 ` Tudor Ambarus
2026-04-23 14:19 ` [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop Tudor Ambarus
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
Sashiko identified a cross-thread RX length corruption bug when
reviewing the thermal addition to ACPM [1].
When multiple threads concurrently send IPC requests, the ACPM polling
mechanism can encounter responses belonging to other threads. To drain
the queue, the driver saves these concurrent responses into an internal
cache (`rx_data->cmd`) to be retrieved later by the owning thread.
Previously, the driver incorrectly used `xfer->rxcnt` (the expected
receive length of the *current* polling thread) when copying data for
*other* threads into this cache. If the threads expected responses of
different lengths, this resulted in buffer underflows (leading to reads
of uninitialized memory) or potential buffer overflows.
Fix this by replacing the boolean `response` flag in
`struct acpm_rx_data` with `rxcnt`, caching the exact expected receive
length for each specific transaction during transfer preparation. Use
this cached length when saving concurrent responses.
Consequently, ensure that `xfer->rxcnt` is explicitly zeroed in driver
helpers (e.g., `acpm_dvfs_set_xfer`) for fire-and-forget messages to
prevent uninitialized stack garbage from being interpreted as a massive
expected receive length.
Cc: stable@vger.kernel.org
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/exynos-acpm-dvfs.c | 3 +++
drivers/firmware/samsung/exynos-acpm.c | 15 ++++++++-------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c
index 06bdf62dea1f..fdea7aa24ca0 100644
--- a/drivers/firmware/samsung/exynos-acpm-dvfs.c
+++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c
@@ -31,6 +31,9 @@ static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
if (response) {
xfer->rxcnt = cmdlen;
xfer->rxd = cmd;
+ } else {
+ xfer->rxcnt = 0;
+ xfer->rxd = NULL;
}
}
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index 16c46ed60837..e95edc350efa 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -104,12 +104,12 @@ struct acpm_queue {
*
* @cmd: pointer to where the data shall be saved.
* @n_cmd: number of 32-bit commands.
- * @response: true if the client expects the RX data.
+ * @rxcnt: expected length of the response in 32-bit words.
*/
struct acpm_rx_data {
u32 *cmd;
size_t n_cmd;
- bool response;
+ size_t rxcnt;
};
#define ACPM_SEQNUM_MAX 64
@@ -199,7 +199,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan,
const struct acpm_rx_data *rx_data = &achan->rx_data[tx_seqnum - 1];
u32 rx_seqnum;
- if (!rx_data->response)
+ if (!rx_data->rxcnt)
return;
rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]);
@@ -256,7 +256,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
seqnum = rx_seqnum - 1;
rx_data = &achan->rx_data[seqnum];
- if (rx_data->response) {
+ if (rx_data->rxcnt) {
if (rx_seqnum == tx_seqnum) {
__ioread32_copy(xfer->rxd, addr, xfer->rxcnt);
rx_set = true;
@@ -268,7 +268,8 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer)
* clear yet the bitmap. It will be cleared
* after the response is copied to the request.
*/
- __ioread32_copy(rx_data->cmd, addr, xfer->rxcnt);
+ __ioread32_copy(rx_data->cmd, addr,
+ rx_data->rxcnt);
}
} else {
clear_bit(seqnum, achan->bitmap_seqnum);
@@ -380,8 +381,8 @@ static void acpm_prepare_xfer(struct acpm_chan *achan,
/* Clear data for upcoming responses */
rx_data = &achan->rx_data[achan->seqnum - 1];
memset(rx_data->cmd, 0, sizeof(*rx_data->cmd) * rx_data->n_cmd);
- if (xfer->rxd)
- rx_data->response = true;
+ /* zero means no response expected */
+ rx_data->rxcnt = xfer->rxcnt;
/* Flag the index based on seqnum. (seqnum: 1~63, bitmap: 0~62) */
set_bit(achan->seqnum - 1, achan->bitmap_seqnum);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop
2026-04-23 14:19 [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports Tudor Ambarus
2026-04-23 14:19 ` [PATCH 1/4] firmware: samsung: acpm: Fix cross-thread RX length corruption Tudor Ambarus
@ 2026-04-23 14:19 ` Tudor Ambarus
2026-04-27 13:06 ` Tudor Ambarus
2026-04-23 14:19 ` [PATCH 3/4] firmware: samsung: acpm: Fix mailbox channel leak on probe error Tudor Ambarus
2026-04-23 14:19 ` [PATCH 4/4] firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR Tudor Ambarus
3 siblings, 1 reply; 6+ messages in thread
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
Sashiko identified a sequence number leak and a possible infinite loop
[1].
ACPM IPC sequence numbers are tracked via a 64-bit bitmap
(`bitmap_seqnum`) to manage concurrent transactions. A bit is set when
a sequence number is allocated in `acpm_prepare_xfer()`.
Previously, if a transfer timed out during RX polling, or if the
underlying hardware mailbox failed to send the message via
`mbox_send_message()`, the allocated sequence number bit was never
cleared.
As these transient errors accumulate, all 63 available sequence numbers
could eventually be leaked. Once the bitmap is full, the next call to
`acpm_prepare_xfer()` would enter an infinite `while` loop attempting
to find a free sequence number, permanently deadlocking the CPU.
Fix this by ensuring the sequence number bit is explicitly cleared on
all error paths:
1. In `acpm_do_xfer()`, clear the bit if the mailbox transmission
fails.
2. In `acpm_dequeue_by_polling()`, clear the bit if the queue read fails
or if the response times out.
Cc: stable@vger.kernel.org
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/exynos-acpm.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index e95edc350efa..a9baed5762d5 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -311,8 +311,10 @@ static int acpm_dequeue_by_polling(struct acpm_chan *achan,
timeout = ktime_add_us(ktime_get(), ACPM_POLL_TIMEOUT_US);
do {
ret = acpm_get_rx(achan, xfer);
- if (ret)
+ if (ret) {
+ clear_bit(seqnum - 1, achan->bitmap_seqnum);
return ret;
+ }
if (!test_bit(seqnum - 1, achan->bitmap_seqnum))
return 0;
@@ -324,6 +326,8 @@ static int acpm_dequeue_by_polling(struct acpm_chan *achan,
dev_err(dev, "Timeout! ch:%u s:%u bitmap:%lx.\n",
achan->id, seqnum, achan->bitmap_seqnum[0]);
+ clear_bit(seqnum - 1, achan->bitmap_seqnum);
+
return -ETIME;
}
@@ -455,8 +459,10 @@ int acpm_do_xfer(struct acpm_handle *handle, const struct acpm_xfer *xfer)
writel(idx, achan->tx.front);
ret = mbox_send_message(achan->chan, (void *)&msg);
- if (ret < 0)
+ if (ret < 0) {
+ clear_bit(achan->seqnum - 1, achan->bitmap_seqnum);
return ret;
+ }
mbox_client_txdone(achan->chan, 0);
}
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] firmware: samsung: acpm: Fix mailbox channel leak on probe error
2026-04-23 14:19 [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports Tudor Ambarus
2026-04-23 14:19 ` [PATCH 1/4] firmware: samsung: acpm: Fix cross-thread RX length corruption Tudor Ambarus
2026-04-23 14:19 ` [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop Tudor Ambarus
@ 2026-04-23 14:19 ` Tudor Ambarus
2026-04-23 14:19 ` [PATCH 4/4] firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR Tudor Ambarus
3 siblings, 0 replies; 6+ messages in thread
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
Sashiko identified the leak at [1].
The ACPM driver allocates hardware mailbox channels using
`mbox_request_channel()` during `acpm_channels_init()`. However, the
driver lacked a `.remove` callback and did not free these channels on
subsequent error paths inside `acpm_probe()`.
Consequently, if a later step in the probe function failed (e.g.,
`platform_device_register_data()` returning an error), the mailbox
channels were permanently leaked. This prevented the driver from ever
successfully re-probing on a transient `-EPROBE_DEFER`.
Fix this by modifying `acpm_free_mbox_chans()` to match the `devres`
action signature and wrapping it with `devm_add_action_or_reset()`.
This hooks the channel cleanup directly into the device's managed
resource lifecycle, ensuring the channels are properly freed on probe
failures or driver unbind.
Cc: stable@vger.kernel.org
Fixes: a88927b534ba ("firmware: add Exynos ACPM protocol driver")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
drivers/firmware/samsung/exynos-acpm.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c
index a9baed5762d5..896fbdc2700e 100644
--- a/drivers/firmware/samsung/exynos-acpm.c
+++ b/drivers/firmware/samsung/exynos-acpm.c
@@ -535,8 +535,9 @@ static int acpm_achan_alloc_cmds(struct acpm_chan *achan)
* acpm_free_mbox_chans() - free mailbox channels.
* @acpm: pointer to driver data.
*/
-static void acpm_free_mbox_chans(struct acpm_info *acpm)
+static void acpm_free_mbox_chans(void *data)
{
+ struct acpm_info *acpm = data;
int i;
for (i = 0; i < acpm->num_chans; i++)
@@ -658,6 +659,10 @@ static int acpm_probe(struct platform_device *pdev)
if (ret)
return ret;
+ ret = devm_add_action_or_reset(dev, acpm_free_mbox_chans, acpm);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to add mbox free action.\n");
+
acpm_setup_ops(acpm);
platform_set_drvdata(pdev, acpm);
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR
2026-04-23 14:19 [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports Tudor Ambarus
` (2 preceding siblings ...)
2026-04-23 14:19 ` [PATCH 3/4] firmware: samsung: acpm: Fix mailbox channel leak on probe error Tudor Ambarus
@ 2026-04-23 14:19 ` Tudor Ambarus
3 siblings, 0 replies; 6+ messages in thread
From: Tudor Ambarus @ 2026-04-23 14:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, Tudor Ambarus, stable
Sashiko identified a potential NULL pointer dereference [1].
The dummy stub implementation for devm_acpm_get_by_node() returns NULL
when CONFIG_EXYNOS_ACPM_PROTOCOL is disabled.
However, the active implementation of this function returns an ERR_PTR
on failure, and the consumer driver checks the return value using
IS_ERR(). Because IS_ERR(NULL) evaluates to false, returning NULL from
the stub tricks consumer drivers into treating the NULL return as a
valid handle. Subsequent attempts to access handle->ops result in a
fatal NULL pointer dereference.
Fix this by returning ERR_PTR(-ENODEV) in the disabled configuration
to correctly propagate the disabled state and match the API contract.
Cc: stable@vger.kernel.org
Fixes: 6837c006d4e7 ("firmware: exynos-acpm: add empty method to allow compile test")
Closes: https://sashiko.dev/#/patchset/20260420-acpm-tmu-v3-0-3dc8e93f0b26%40linaro.org [1]
Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
---
include/linux/firmware/samsung/exynos-acpm-protocol.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/include/linux/firmware/samsung/exynos-acpm-protocol.h
index 13f17dc4443b..d4db2796a6fb 100644
--- a/include/linux/firmware/samsung/exynos-acpm-protocol.h
+++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h
@@ -8,6 +8,7 @@
#ifndef __EXYNOS_ACPM_PROTOCOL_H
#define __EXYNOS_ACPM_PROTOCOL_H
+#include <linux/err.h>
#include <linux/types.h>
struct acpm_handle;
@@ -57,7 +58,7 @@ struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
static inline struct acpm_handle *devm_acpm_get_by_node(struct device *dev,
struct device_node *np)
{
- return NULL;
+ return ERR_PTR(-ENODEV);
}
#endif
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop
2026-04-23 14:19 ` [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop Tudor Ambarus
@ 2026-04-27 13:06 ` Tudor Ambarus
0 siblings, 0 replies; 6+ messages in thread
From: Tudor Ambarus @ 2026-04-27 13:06 UTC (permalink / raw)
To: Krzysztof Kozlowski, Alim Akhtar
Cc: linux-kernel, linux-samsung-soc, linux-arm-kernel, peter.griffin,
andre.draszik, jyescas, kernel-team, stable
Hi!
I need to drop this patch, as it can cause silent data corruption.
Will send a v2 dropping this patch and adding a few more fixes for bugs
identified by sashiko.
Cheers,
ta
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-27 13:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-23 14:19 [PATCH 0/4] firmware: samsung: acpm: Various fixes for sashiko bug reports Tudor Ambarus
2026-04-23 14:19 ` [PATCH 1/4] firmware: samsung: acpm: Fix cross-thread RX length corruption Tudor Ambarus
2026-04-23 14:19 ` [PATCH 2/4] firmware: samsung: acpm: Fix sequence number leak and infinite loop Tudor Ambarus
2026-04-27 13:06 ` Tudor Ambarus
2026-04-23 14:19 ` [PATCH 3/4] firmware: samsung: acpm: Fix mailbox channel leak on probe error Tudor Ambarus
2026-04-23 14:19 ` [PATCH 4/4] firmware: samsung: acpm: Fix dummy stubs to return ERR_PTR Tudor Ambarus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox