Re: [PATCH RFT 2/3] firmware: exynos-acpm: Count number of commands in acpm_xfer
From: Tudor Ambarus <tudor.ambarus@linaro.org>
Date: 2026-02-19 10:27:42
Also in:
linux-hardening, linux-samsung-soc, lkml, llvm
On 2/14/26 2:39 PM, Krzysztof Kozlowski wrote:
Struct acpm_xfer holds two buffers with u32 commands - rxd and txd - and counts their size by rxlen and txlen. "len" suffix is here ambiguous, so could mean length of the buffer or length of commands, and these are not the same since each command is u32. Rename these to rxcnt and txcnt, and change their usage to count the number of commands in each buffer. This will have a benafit of allowing to use __counted_by_ptr later.
^typo, benefit.quoted hunk ↗ jump to hunk
Signed-off-by: Krzysztof Kozlowski <redacted> --- drivers/firmware/samsung/exynos-acpm-dvfs.c | 8 ++++---- drivers/firmware/samsung/exynos-acpm-pmic.c | 14 +++++++------- drivers/firmware/samsung/exynos-acpm.c | 12 +++++++----- drivers/firmware/samsung/exynos-acpm.h | 4 ++-- 4 files changed, 20 insertions(+), 18 deletions(-)diff --git a/drivers/firmware/samsung/exynos-acpm-dvfs.c b/drivers/firmware/samsung/exynos-acpm-dvfs.c index 1c5b2b143bcc..55ec6ad9d87e 100644 --- a/drivers/firmware/samsung/exynos-acpm-dvfs.c +++ b/drivers/firmware/samsung/exynos-acpm-dvfs.c@@ -25,11 +25,11 @@ static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen, { xfer->acpm_chan_id = acpm_chan_id; xfer->txd = cmd; - xfer->txlen = cmdlen; + xfer->txcnt = cmdlen; if (response) { xfer->rxd = cmd; - xfer->rxlen = cmdlen; + xfer->rxcnt = cmdlen; } }@@ -50,7 +50,7 @@ int acpm_dvfs_set_rate(const struct acpm_handle *handle, u32 cmd[4]; acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate); - acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false); + acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, false); return acpm_do_xfer(handle, &xfer); }@@ -70,7 +70,7 @@ unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle, int ret; acpm_dvfs_init_get_rate_cmd(cmd, clk_id); - acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true); + acpm_dvfs_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true); ret = acpm_do_xfer(handle, &xfer); if (ret)diff --git a/drivers/firmware/samsung/exynos-acpm-pmic.c b/drivers/firmware/samsung/exynos-acpm-pmic.c index 44265db34ae6..26a9024d8ed8 100644 --- a/drivers/firmware/samsung/exynos-acpm-pmic.c +++ b/drivers/firmware/samsung/exynos-acpm-pmic.c@@ -63,8 +63,8 @@ static void acpm_pmic_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen, { xfer->txd = cmd; xfer->rxd = cmd; - xfer->txlen = cmdlen; - xfer->rxlen = cmdlen; + xfer->txcnt = cmdlen; + xfer->rxcnt = cmdlen; xfer->acpm_chan_id = acpm_chan_id; }@@ -86,7 +86,7 @@ int acpm_pmic_read_reg(const struct acpm_handle *handle, int ret; acpm_pmic_init_read_cmd(cmd, type, reg, chan); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret)@@ -119,7 +119,7 @@ int acpm_pmic_bulk_read(const struct acpm_handle *handle, return -EINVAL; acpm_pmic_init_bulk_read_cmd(cmd, type, reg, chan, count); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret)@@ -159,7 +159,7 @@ int acpm_pmic_write_reg(const struct acpm_handle *handle, int ret; acpm_pmic_init_write_cmd(cmd, type, reg, chan, value); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret)@@ -199,7 +199,7 @@ int acpm_pmic_bulk_write(const struct acpm_handle *handle, return -EINVAL; acpm_pmic_init_bulk_write_cmd(cmd, type, reg, chan, count, buf); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret)@@ -229,7 +229,7 @@ int acpm_pmic_update_reg(const struct acpm_handle *handle, int ret; acpm_pmic_init_update_cmd(cmd, type, reg, chan, value, mask); - acpm_pmic_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id); + acpm_pmic_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id); ret = acpm_do_xfer(handle, &xfer); if (ret)diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/samsung/exynos-acpm.c index 0cb269c70460..242745e8394c 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c@@ -205,7 +205,7 @@ static void acpm_get_saved_rx(struct acpm_chan *achan, rx_seqnum = FIELD_GET(ACPM_PROTOCOL_SEQNUM, rx_data->cmd[0]); if (rx_seqnum == tx_seqnum) { - memcpy(xfer->rxd, rx_data->cmd, xfer->rxlen); + memcpy(xfer->rxd, rx_data->cmd, xfer->rxcnt * sizeof(*xfer->rxd)); clear_bit(rx_seqnum - 1, achan->bitmap_seqnum); } }@@ -259,7 +259,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) if (rx_data->response) { if (rx_seqnum == tx_seqnum) { __ioread32_copy(xfer->rxd, addr, - xfer->rxlen / 4); + xfer->rxcnt);
now __ioread32_copy fits on a single line, without bypassing 80 chars
quoted hunk ↗ jump to hunk
rx_set = true; clear_bit(seqnum, achan->bitmap_seqnum); } else {@@ -270,7 +270,7 @@ static int acpm_get_rx(struct acpm_chan *achan, const struct acpm_xfer *xfer) * after the response is copied to the request. */ __ioread32_copy(rx_data->cmd, addr, - xfer->rxlen / 4); + xfer->rxcnt); } } else { clear_bit(seqnum, achan->bitmap_seqnum);@@ -425,7 +425,9 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) achan = &acpm->chans[xfer->acpm_chan_id]; - if (!xfer->txd || xfer->txlen > achan->mlen || xfer->rxlen > achan->mlen) + if (!xfer->txd || (xfer->txcnt * sizeof(*xfer->txd) > achan->mlen)) + return -EINVAL; + if (xfer->rxcnt * sizeof(*xfer->rxd) > achan->mlen) return -EINVAL;
how about:
if (!xfer->txd ||
(xfer->txcnt * sizeof(*xfer->txd) > achan->mlen) ||
(xfer->rxcnt * sizeof(*xfer->rxd) > achan->mlen))
return -EINVAL;
quoted hunk ↗ jump to hunk
if (!achan->poll_completion) {@@ -448,7 +450,7 @@ int acpm_do_xfer(const struct acpm_handle *handle, const struct acpm_xfer *xfer) /* Write TX command. */ __iowrite32_copy(achan->tx.base + achan->mlen * tx_front, - xfer->txd, xfer->txlen / 4); + xfer->txd, xfer->txcnt); /* Advance TX front. */ writel(idx, achan->tx.front);diff --git a/drivers/firmware/samsung/exynos-acpm.h b/drivers/firmware/samsung/exynos-acpm.h index 2d14cb58f98c..422fbcac7284 100644 --- a/drivers/firmware/samsung/exynos-acpm.h +++ b/drivers/firmware/samsung/exynos-acpm.h@@ -10,8 +10,8 @@ struct acpm_xfer { const u32 *txd; u32 *rxd; - size_t txlen; - size_t rxlen; + size_t txcnt; + size_t rxcnt; unsigned int acpm_chan_id; };