remoteproc: cleanup shared carveout and resource-table helpers
Subsystems (5)
v3 cover remoteproc: cleanup shared carveout and resource-table helpers
This series is a preparatory remoteproc cleanup split out from review of the AMD BRAM-based remoteproc series.
During review, there was a request to move the duplicated plain ioremap_wc()/iounmap() carveout callbacks into common code and to factor the "missing resource table is OK" ELF parsing path into a common helper as well. There was also a request to send that cleanup as its own patchset first, with the AMD BRAM series respun afterwards on top once this cleanup is merged.
This version keeps the same overall cleanup goals as v2, but reworks the optional resource-table pieces based on follow-up review:
- reshape the optional resource-table helper in patch 4 into the thin parse_fw() wrapper form suggested on the thread
- switch the patch 5 clients over to that helper shape directly,
without post-helper rproc->table_ptr checks
- keep the driver-local parse_fw() wrappers and their existing log messages and severity choices
- retain as much of the existing per-driver parse_fw() logic and code placement as possible while moving the missing-table handling through the shared helper
This series now does that in five patches:
1. add common subsystem-private callbacks for the exact-match wc-ioremap carveout case
2. switch the in-tree exact-match users over to those callbacks
3. mark carveouts mapped through the shared wc-ioremap helper as iomem so the framework uses the proper I/O accessors
4. add a common helper for drivers that treat a missing ELF resource table as optional while keeping per-driver logging decisions local
5. switch the matching in-tree drivers over to that helper while keeping thin local parse_fw() wrappers
For the carveout map/unmap cleanup, this series covers the exact-match users called out in review: xlnx_r5_remoteproc, rcar_rproc, st_remoteproc, stm32_rproc, imx_rproc, and imx_dsp_rproc. The zynqmp R5 TCM mapping path is left alone because it also clears the mapped memory and is not an exact match.
For the optional resource-table handling, this series converts xlnx_r5_remoteproc, rcar_rproc, stm32_rproc, imx_rproc, and imx_dsp_rproc. st_remoteproc is intentionally left unchanged because its parse_fw() callback also builds carveouts and is therefore not a direct match for the helper introduced here.
Changes in v3:
- rework patch 4 so the optional resource-table helper matches the thin-wrapper form suggested in review
- note that patch 4 still triggers a checkpatch --strict warning for the flow-control macro form, but that implementation follows the maintainer's review suggestion for the thin parse_fw() wrapper shape
- update patch 5 to use that helper shape directly in the client parse_fw() callbacks
- drop the post-helper rproc->table_ptr checks from the converted drivers
- keep the converted parse_fw() wrappers otherwise close to their existing structure and placement
- test xlnx_r5_remoteproc on the latest tree with firmware images both with and without an ELF resource table
Changes in v2:
- split the mem->is_iomem change out into a separate patch
- add a common error message on ioremap_wc() failure
- drop logging from the optional resource-table helper
- keep driver-local parse_fw() wrappers to preserve per-platform missing-resource-table logging policy
Ben Levinsky (5):
remoteproc: add common wc-ioremap carveout callbacks
remoteproc: switch exact-match drivers to wc-ioremap callbacks
remoteproc: mark wc-ioremap carveouts as iomem
remoteproc: add helper for optional ELF resource tables
remoteproc: switch drivers to optional resource-table helper
drivers/remoteproc/imx_dsp_rproc.c | 41 +++----------- drivers/remoteproc/imx_rproc.c | 40 ++------------ drivers/remoteproc/rcar_rproc.c | 41 ++------------ drivers/remoteproc/remoteproc_internal.h | 38 +++++++++++++ drivers/remoteproc/st_remoteproc.c | 31 +---------- drivers/remoteproc/stm32_rproc.c | 39 ++----------- drivers/remoteproc/xlnx_r5_remoteproc.c | 70 +++++------------------- 7 files changed, 73 insertions(+), 227 deletions(-)
Signature · 1 line
2.34.1
PATCH v3 1/5 remoteproc: add common wc-ioremap carveout callbacks
Several remoteproc drivers open-code the same ioremap_wc() and iounmap() callbacks for carveout mappings. Add subsystem-private helpers in remoteproc_internal.h so those drivers can share the same implementation.
Keep this change behavior-neutral. The helper now emits a common error message on ioremap_wc() failure, but leaves mem->is_iomem handling to a follow-on patch so that the behavioral change can be justified separately.
--- drivers/remoteproc/remoteproc_internal.h | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
drivers/remoteproc/remoteproc_internal.h +26 -0
@@ -14,6 +14,7 @@#include <linux/irqreturn.h> #include <linux/firmware.h> +#include <linux/io.h> struct rproc ;
@@ -122,6 +123,31 @@ rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);void rproc_add_rvdev (struct rproc *rproc,struct rproc_vdev *rvdev);void rproc_remove_rvdev (struct rproc_vdev *rvdev); +static inline int rproc_mem_entry_ioremap_wc (struct rproc *rproc, +struct rproc_mem_entry *mem) +{ +void __iomem *va; + + va =ioremap_wc (mem->dma, mem->len); +if (!va) { +dev_err (&rproc->dev,"Unable to map memory region: %pa+%zx\n" , + &mem->dma, mem->len); +return -ENOMEM ; + } + + mem->va = (__force void *)va; + +return 0 ; +} + +static inline int rproc_mem_entry_iounmap (struct rproc *rproc, +struct rproc_mem_entry *mem) +{ +iounmap ((__force __iomem void *)mem->va); + +return 0 ; +} +static inline int rproc_prepare_device (struct rproc *rproc) {if (rproc->ops->prepare)
Signature · 1 line
2.34.1
[email protected]
AI reviewRe: [PATCH v3 1/5] remoteproc: add common wc-ioremap carveout callbacks
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The error message in `rproc_mem_entry_ioremap_wc` uses the `%pa` format specifier for a…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The error message in rproc_mem_entry_ioremap_wc uses the %pa format specifier for a dma_addr_t pointer instead of the correct %pad specifier. --
commit 49a6ae6c09ebb61591d4b795ceaf406223e63c34
Author: Ben Levinsky <[email protected]>
remoteproc: add common wc-ioremap carveout callbacks
This commit adds common subsystem-private helpers to avoid open-coding carveout mapping callbacks in various remoteproc drivers. The change centralizes the ioremap_wc and iounmap operations along with their error logging.
Quoted 3 lines
drivers/remoteproc/remoteproc_internal.h +0
-0
[ ... ]
drivers/remoteproc/remoteproc_internal.h rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...); · line 134
Quoted 13 lines
drivers/remoteproc/remoteproc_internal.h +9
-0@@ -122,6 +123,31 @@ rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);void rproc_add_rvdev (struct rproc *rproc,struct rproc_vdev *rvdev);void rproc_remove_rvdev (struct rproc_vdev *rvdev); +static inline int rproc_mem_entry_ioremap_wc (struct rproc *rproc, +struct rproc_mem_entry *mem) +{ +void __iomem *va; + + va =ioremap_wc (mem->dma, mem->len); +if (!va) { +dev_err (&rproc->dev,"Unable to map memory region: %pa+%zx\n" , + &mem->dma, mem->len);
[Severity: Medium]
Does this format specifier match the variable type?
The %pa specifier expects a phys_addr_t pointer, but &mem->dma is a dma_addr_t pointer. If phys_addr_t and dma_addr_t have different sizes (for example, 64-bit DMA and 32-bit physical addresses on a 32-bit system), vsprintf could read the wrong number of bytes and potentially print unrelated data in the error log.
Should this use %pad instead to properly format the dma_addr_t pointer?
Quoted 7 lines
drivers/remoteproc/remoteproc_internal.h +7
-0+return -ENOMEM ; + } + + mem->va = (__force void *)va; + +return 0 ; +}
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
PATCH v3 2/5 remoteproc: switch exact-match drivers to wc-ioremap callbacks
In reply to Ben LevinskyReplace the exact-match carveout map and unmap callbacks in the existing remoteproc drivers with the common wc-ioremap helpers. This covers xlnx_r5_remoteproc, rcar_rproc, st_remoteproc, stm32_rproc, imx_rproc, and imx_dsp_rproc.
Leave the zynqmp R5 TCM callbacks alone because they also clear the mapped memory and are therefore not exact matches for the shared helpers.
--- drivers/remoteproc/imx_dsp_rproc.c | 36 ++++--------------- drivers/remoteproc/imx_rproc.c | 32 ++--------------- drivers/remoteproc/rcar_rproc.c | 33 ++--------------- drivers/remoteproc/st_remoteproc.c | 31 ++-------------- drivers/remoteproc/stm32_rproc.c | 33 ++--------------- drivers/remoteproc/xlnx_r5_remoteproc.c | 47 +++---------------------- 6 files changed, 18 insertions(+), 194 deletions(-)
drivers/remoteproc/imx_dsp_rproc.c +6 -30
@@ -644,32 +644,6 @@ static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)mbox_free_channel (priv->rxdb_ch); } -static int imx_dsp_rproc_mem_alloc (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -struct device *dev = rproc->dev.parent; -void *va; - - va =ioremap_wc (mem->dma, mem->len); -if (!va) { -dev_err (dev,"Unable to map memory region: %pa+%zx\n" , - &mem->dma, mem->len); -return -ENOMEM ; - } - - mem->va = va; - -return 0 ; -} - -static int imx_dsp_rproc_mem_release (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -iounmap (mem->va); - -return 0 ; -} -/** * imx_dsp_rproc_add_carveout() - request mailbox channels * @priv: private data pointer
@@ -700,8 +674,10 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)/* Register memory region */ mem =rproc_mem_entry_init (dev,NULL , (dma_addr_t )att->sa, - att->size, da, imx_dsp_rproc_mem_alloc, - imx_dsp_rproc_mem_release,"dsp_mem" ); + att->size, da, + rproc_mem_entry_ioremap_wc, + rproc_mem_entry_iounmap, +"dsp_mem" );if (mem)rproc_coredump_add_segment (rproc, da, att->size);
@@ -732,8 +708,8 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)/* Register memory region */ mem =rproc_mem_entry_init (dev,NULL , (dma_addr_t )res.start,resource_size (&res), da, - imx_dsp_rproc_mem_alloc, - imx_dsp_rproc_mem_release, + rproc_mem_entry_ioremap_wc, + rproc_mem_entry_iounmap,"%.*s" ,strchrnul (res.name,'@' ) - res.name, res.name);if (!mem)return -ENOMEM ;
drivers/remoteproc/imx_rproc.c +2 -30
@@ -600,35 +600,6 @@ static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *ireturn va; } -static int imx_rproc_mem_alloc (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -struct device *dev = rproc->dev.parent; -void *va; - -dev_dbg (dev,"map memory: %p+%zx\n" , &mem->dma, mem->len); - va =ioremap_wc (mem->dma, mem->len); -if (IS_ERR_OR_NULL (va)) { -dev_err (dev,"Unable to map memory region: %p+%zx\n" , - &mem->dma, mem->len); -return -ENOMEM ; - } - -/* Update memory entry va */ - mem->va = va; - -return 0 ; -} - -static int imx_rproc_mem_release (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -dev_dbg (rproc->dev.parent,"unmap memory: %pa\n" , &mem->dma); -iounmap (mem->va); - -return 0 ; -} -static int imx_rproc_sm_lmm_prepare (struct rproc *rproc) {struct imx_rproc *priv = rproc->priv;
@@ -692,7 +663,8 @@ static int imx_rproc_prepare(struct rproc *rproc)/* Register memory region */ mem =rproc_mem_entry_init (priv->dev,NULL , (dma_addr_t )res.start,resource_size (&res), da, - imx_rproc_mem_alloc, imx_rproc_mem_release, + rproc_mem_entry_ioremap_wc, + rproc_mem_entry_iounmap,"%.*s" ,strchrnul (res.name,'@' ) - res.name, res.name);if (!mem)
drivers/remoteproc/rcar_rproc.c +2 -31
@@ -19,35 +19,6 @@ struct rcar_rproc {struct reset_control *rst; }; -static int rcar_rproc_mem_alloc (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -struct device *dev = &rproc->dev; -void *va; - -dev_dbg (dev,"map memory: %pa+%zx\n" , &mem->dma, mem->len); - va =ioremap_wc (mem->dma, mem->len); -if (!va) { -dev_err (dev,"Unable to map memory region: %pa+%zx\n" , - &mem->dma, mem->len); -return -ENOMEM ; - } - -/* Update memory entry va */ - mem->va = va; - -return 0 ; -} - -static int rcar_rproc_mem_release (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -dev_dbg (&rproc->dev,"unmap memory: %pa\n" , &mem->dma); -iounmap (mem->va); - -return 0 ; -} -static int rcar_rproc_prepare (struct rproc *rproc) {struct device *dev = rproc->dev.parent;
@@ -73,8 +44,8 @@ static int rcar_rproc_prepare(struct rproc *rproc) mem =rproc_mem_entry_init (dev,NULL , res.start,resource_size (&res), da, - rcar_rproc_mem_alloc, - rcar_rproc_mem_release, + rproc_mem_entry_ioremap_wc, + rproc_mem_entry_iounmap, res.name);if (!mem)
drivers/remoteproc/st_remoteproc.c +2 -29
@@ -88,33 +88,6 @@ static void st_rproc_kick(struct rproc *rproc, int vqid)dev_err (dev,"failed to send message via mbox: %d\n" , ret); } -static int st_rproc_mem_alloc (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -struct device *dev = rproc->dev.parent; -void *va; - - va =ioremap_wc (mem->dma, mem->len); -if (!va) { -dev_err (dev,"Unable to map memory region: %pa+%zx\n" , - &mem->dma, mem->len); -return -ENOMEM ; - } - -/* Update memory entry va */ - mem->va = va; - -return 0 ; -} - -static int st_rproc_mem_release (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -iounmap (mem->va); - -return 0 ; -} -static int st_rproc_parse_fw (struct rproc *rproc,const struct firmware *fw) {struct device *dev = rproc->dev.parent;
@@ -138,8 +111,8 @@ static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) mem =rproc_mem_entry_init (dev,NULL , (dma_addr_t )res.start,resource_size (&res), res.start, - st_rproc_mem_alloc, - st_rproc_mem_release, + rproc_mem_entry_ioremap_wc, + rproc_mem_entry_iounmap,"%.*s" ,strchrnul (res.name,'@' ) - res.name, res.name);
drivers/remoteproc/stm32_rproc.c +2 -31
@@ -113,35 +113,6 @@ static int stm32_rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da)return -EINVAL ; } -static int stm32_rproc_mem_alloc (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -struct device *dev = rproc->dev.parent; -void *va; - -dev_dbg (dev,"map memory: %pad+%zx\n" , &mem->dma, mem->len); - va = (__force void *)ioremap_wc (mem->dma, mem->len); -if (IS_ERR_OR_NULL (va)) { -dev_err (dev,"Unable to map memory region: %pad+0x%zx\n" , - &mem->dma, mem->len); -return -ENOMEM ; - } - -/* Update memory entry va */ - mem->va = va; - -return 0 ; -} - -static int stm32_rproc_mem_release (struct rproc *rproc, -struct rproc_mem_entry *mem) -{ -dev_dbg (rproc->dev.parent,"unmap memory: %pa\n" , &mem->dma); -iounmap ((__force __iomem void *)mem->va); - -return 0 ; -} -static int stm32_rproc_of_memory_translations (struct platform_device *pdev,struct stm32_rproc *ddata) {
@@ -237,8 +208,8 @@ static int stm32_rproc_prepare(struct rproc *rproc) mem =rproc_mem_entry_init (dev,NULL , (dma_addr_t )res.start,resource_size (&res), da, - stm32_rproc_mem_alloc, - stm32_rproc_mem_release, + rproc_mem_entry_ioremap_wc, + rproc_mem_entry_iounmap,"%.*s" ,strchrnul (res.name,'@' ) - res.name, res.name);if (mem)
drivers/remoteproc/xlnx_r5_remoteproc.c +4 -43
65 lines not on this page · raw message
Signature · 1 line
2.34.1
[email protected]
AI reviewRe: [PATCH v3 2/5] remoteproc: switch exact-match drivers to wc-ioremap callbacks
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The error logging in the `rproc_mem_entry_ioremap_wc` helper uses the `%pa` format specifier for…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The error logging in the rproc_mem_entry_ioremap_wc helper uses the %pa format specifier for a dma_addr_t pointer instead of %pad. --
commit 06feb3b32004ed7bd1d29e99430abd615d6b4449
Author: Ben Levinsky <[email protected]>
remoteproc: switch exact-match drivers to wc-ioremap callbacks
Replace the exact-match carveout map and unmap callbacks in the existing remoteproc drivers with the common wc-ioremap helpers. This covers xlnx_r5_remoteproc, rcar_rproc, st_remoteproc, stm32_rproc, imx_rproc, and imx_dsp_rproc.
Leave the zynqmp R5 TCM callbacks alone because they also clear the mapped memory and are therefore not exact matches for the shared helpers.
Quoted 4 lines
drivers/remoteproc/stm32_rproc.c +0
-0
[ ... ]
drivers/remoteproc/stm32_rproc.c static int stm32_rproc_prepare(struct rproc *rproc) · line 211
Quoted 7 lines
drivers/remoteproc/stm32_rproc.c +1
-2@@ -237,8 +208,8 @@ static int stm32_rproc_prepare(struct rproc *rproc) mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)res.start, resource_size(&res), da, - stm32_rproc_mem_alloc, - stm32_rproc_mem_release, + rproc_mem_entry_ioremap_wc,
[Severity: Medium]
Does replacing the stm32 callback with the common helper regress its error logging?
The original stm32_rproc_mem_alloc() function correctly used %pad for mem->dma:
dev_err(dev, "Unable to map memory region: %pad+0x%zx\n",
&mem->dma, mem->len);However, the new rproc_mem_entry_ioremap_wc() helper uses %pa:
dev_err(&rproc->dev, "Unable to map memory region: %pa+%zx\n",
&mem->dma, mem->len);Since mem->dma is a dma_addr_t, and %pa expects a phys_addr_t *, could this result in reading the wrong number of bytes on platforms where sizeof(dma_addr_t) != sizeof(phys_addr_t)?
This could combine the dma and adjacent len fields, printing a garbage address in the log.
Quoted 4 lines
drivers/remoteproc/stm32_rproc.c +1
-0+ rproc_mem_entry_iounmap,"%.*s" ,strchrnul (res.name,'@' ) - res.name, res.name);if (mem)
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
PATCH v3 3/5 remoteproc: mark wc-ioremap carveouts as iomem
In reply to Ben LevinskyCarveouts registered through the shared wc-ioremap helper are backed by I/O memory, but rproc_da_to_va() only reports that to its callers when mem->is_iomem is set on the carveout.
Without that flag, the remoteproc ELF loader and coredump paths can fall back to normal memcpy()/memset() accessors instead of the I/O helpers used for iomapped memory.
Mark shared wc-ioremap carveouts as iomem so the framework uses the proper memcpy_toio(), memset_io(), and memcpy_fromio() accessors for these regions.
--- drivers/remoteproc/remoteproc_internal.h | 1 + 1 file changed, 1 insertion(+)
drivers/remoteproc/remoteproc_internal.h +1 -0
@@ -136,6 +136,7 @@ static inline int rproc_mem_entry_ioremap_wc(struct rproc *rproc, } mem->va = (__force void *)va; + mem->is_iomem = true;return 0 ; }
Signature · 1 line
2.34.1
[email protected]
AI reviewRe: [PATCH v3 3/5] remoteproc: mark wc-ioremap carveouts as iomem
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [Critical] An integer overflow in rproc_da_to_va() allows a bounds-check bypass, leading to potential out-of-bounds reads and writes.
- [High] The rproc->crash_handler work item is not properly cancelled during remoteproc teardown, leading to a Use-After-Free if a crash is reported concurrently with device removal.
- [High] The debugfs interfaces for carveout memories and resource tables lack proper locking, allowing them to race with device shutdown and access freed memory. --
commit b14fc453ddda30168961d2bedbde273d3521e254
Author: Ben Levinsky <[email protected]>
remoteproc: mark wc-ioremap carveouts as iomem
Carveouts registered through the shared wc-ioremap helper are backed by I/O memory, but rproc_da_to_va() only reports that to its callers when mem->is_iomem is set on the carveout. This patch marks shared wc-ioremap carveouts as iomem so the framework uses the proper I/O memory accessors.
drivers/remoteproc/remoteproc_internal.h static inline int rproc_mem_entry_ioremap_wc(struct rproc *rproc, · line 142
Quoted 12 lines
drivers/remoteproc/remoteproc_internal.h +1
-0@@ -136,6 +136,7 @@ static inline int rproc_mem_entry_ioremap_wc(struct rproc *rproc, } mem->va = (__force void *)va; + mem->is_iomem = true;return 0 ; }
While reviewing this, I noticed a few pre-existing issues in the remoteproc core.
drivers/remoteproc/remoteproc_core.c:rproc_alloc() {
...
INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work);
...
}
[Severity: High]
This is a pre-existing issue, but is there a missing cancellation for the crash_handler work item during teardown?
During device removal, rproc_del() and rproc_free() are called, ultimately triggering rproc_type_release() to free the rproc object via kfree(rproc).
The framework does not appear to call cancel_work_sync(&rproc->crash_handler) during this teardown sequence.
If a hardware interrupt reports a crash right before or during device unbinding, could the pending work item execute rproc_crash_handler_work() after the rproc struct has been freed, resulting in a use-after-free?
drivers/remoteproc/remoteproc_debugfs.c:rproc_carveouts_show() {
struct rproc *rproc = seq->private;
struct rproc_mem_entry *carveout;
list_for_each_entry(carveout, &rproc->carveouts, node) {
seq_puts(seq, "Carveout memory entry:\n");...
}
[Severity: High]
This isn't a bug introduced by this patch, but does this list traversal lack proper locking?
The rproc_carveouts_show() function traverses the rproc->carveouts list without holding rproc->lock or using RCU primitives.
Concurrently, rproc_shutdown() can be triggered (e.g., via a sysfs write to the state file), which executes rproc_resource_cleanup(). This removes entries from the rproc->carveouts list and calls kfree() on them.
If a user reads the debugfs file while a shutdown is in progress, could the concurrent list mutation cause the debugfs read to dereference a freed pointer, leading to a use-after-free?
drivers/remoteproc/remoteproc_core.c:rproc_da_to_va() {
...
list_for_each_entry(carveout, &rproc->carveouts, node) {
int offset = da - carveout->da;
...
/* try next carveout if da is too large */
if (offset + len > carveout->len)
continue;...
}
[Severity: Critical]
This is a pre-existing issue, but does this bounds check protect against integer overflow?
Since offset is an int and len is a size_t, could an extremely large len (e.g., SIZE_MAX) provided by malformed firmware cause offset + len to overflow the size_t type and wrap around to a small value?
This could cause the bounds check to evaluate to false, bypassing the protection and returning a valid pointer inside the carveout.
When rproc_elf_load_segments() uses this returned pointer, could it execute memcpy() or memset() with massively overflowed lengths, resulting in an out-of-bounds write?
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3
PATCH v3 4/5 remoteproc: add helper for optional ELF resource tables
In reply to Ben LevinskyAdd a helper macro around rproc_elf_load_rsc_table() for thin parse_fw() wrappers that treat a missing ELF resource table as optional while keeping per-driver logging decisions local to the caller of rproc_elf_load_rsc_table_optional().
--- drivers/remoteproc/remoteproc_internal.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/remoteproc/remoteproc_internal.h +11 -0
@@ -149,6 +149,17 @@ static inline int rproc_mem_entry_iounmap(struct rproc *rproc,return 0 ; } +#define rproc_elf_load_rsc_table_optional (rproc, fw, dev_func, fmt, ...) \ + ({ \ + int ret = rproc_elf_load_rsc_table(rproc, fw); \ + if (ret == -EINVAL) { \ + dev_func(&rproc->dev, fmt, ##__VA_ARGS__); \ + return 0; \ + } else { \ + return ret; \ + } \ + }) +static inline int rproc_prepare_device (struct rproc *rproc) {if (rproc->ops->prepare)
Signature · 1 line
2.34.1
[email protected]
AI reviewRe: [PATCH v3 4/5] remoteproc: add helper for optional ELF resource tables
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] The macro `rproc_elf_load_rsc_table_optional` hides `return` statements inside a GNU C statement…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The macro rproc_elf_load_rsc_table_optional hides return statements inside a GNU C statement expression, forcing the caller to return immediately and creating dead code. --
commit 97ca173b9ba2ed2c419cbe1a3f62d02db6f033c0
Author: Ben Levinsky <[email protected]>
remoteproc: add helper for optional ELF resource tables
This commit introduces a helper macro around rproc_elf_load_rsc_table. It is designed for drivers that treat a missing ELF resource table as optional while allowing the caller to maintain local logging control.
drivers/remoteproc/remoteproc_internal.h static inline int rproc_mem_entry_iounmap(struct rproc *rproc, · line 157
Quoted 13 lines
drivers/remoteproc/remoteproc_internal.h +6
-0@@ -149,6 +149,17 @@ static inline int rproc_mem_entry_iounmap(struct rproc *rproc,return 0 ; } +#define rproc_elf_load_rsc_table_optional (rproc, fw, dev_func, fmt, ...) \ + ({ \ + int ret = rproc_elf_load_rsc_table(rproc, fw); \ + if (ret == -EINVAL) { \ + dev_func(&rproc->dev, fmt, ##__VA_ARGS__); \ + return 0; \
[Severity: Medium]
Does this macro hide control flow in a way that forces the caller to return unexpectedly?
Using explicit return statements inside a GNU C statement expression does not yield a value to the expression itself. Instead, it forces the function invoking the macro to return immediately.
If callers use this macro as though it evaluates to a return code, any trailing statements in the caller will become unreachable dead code. Additionally, if a calling function acquires a lock or allocates memory before using this macro, the hidden return would skip the cleanup path and cause a resource leak.
Would it be safer to replace this macro with a standard inline function, or change the statement expression to evaluate to the integer value rather than forcing an explicit return?
Quoted 4 lines
drivers/remoteproc/remoteproc_internal.h +4
-0+ }else { \ +return ret; \ + } \ + })
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4
PATCH v3 5/5 remoteproc: switch drivers to optional resource-table helper
In reply to Ben LevinskyUse the shared optional resource-table helper in the remoteproc drivers that already treat a missing resource table as non-fatal:xlnx_r5_remoteproc, rcar_rproc, stm32_rproc, imx_rproc, and imx_dsp_rproc.
Keep thin local parse_fw() wrappers in each driver so the helper only centralizes the return-value handling while each platform retains control over whether the missing-table case is logged and at what severity.
--- drivers/remoteproc/imx_dsp_rproc.c | 5 ++--- drivers/remoteproc/imx_rproc.c | 8 ++------ drivers/remoteproc/rcar_rproc.c | 8 ++------ drivers/remoteproc/stm32_rproc.c | 6 ++---- drivers/remoteproc/xlnx_r5_remoteproc.c | 23 +++++++++-------------- 5 files changed, 17 insertions(+), 33 deletions(-)
drivers/remoteproc/imx_dsp_rproc.c +2 -3
@@ -956,9 +956,8 @@ static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc, const struct firstatic int imx_dsp_rproc_parse_fw (struct rproc *rproc,const struct firmware *fw) { -if (rproc_elf_load_rsc_table (rproc, fw)) -dev_warn (&rproc->dev,"no resource table found for this firmware\n" ); - +rproc_elf_load_rsc_table_optional (rproc, fw, dev_warn, +"no resource table found for this firmware\n" );return 0 ; }
drivers/remoteproc/imx_rproc.c +2 -6
@@ -682,12 +682,8 @@ static int imx_rproc_prepare(struct rproc *rproc)static int imx_rproc_parse_fw (struct rproc *rproc,const struct firmware *fw) { -int ret; - - ret =rproc_elf_load_rsc_table (rproc, fw); -if (ret) -dev_info (&rproc->dev,"No resource table in elf\n" ); - +rproc_elf_load_rsc_table_optional (rproc, fw, dev_info, +"No resource table in elf\n" );return 0 ; }
drivers/remoteproc/rcar_rproc.c +2 -6
@@ -57,12 +57,8 @@ static int rcar_rproc_prepare(struct rproc *rproc)static int rcar_rproc_parse_fw (struct rproc *rproc,const struct firmware *fw) { -int ret; - - ret =rproc_elf_load_rsc_table (rproc, fw); -if (ret) -dev_info (&rproc->dev,"No resource table in elf\n" ); - +rproc_elf_load_rsc_table_optional (rproc, fw, dev_info, +"No resource table in elf\n" );return 0 ; }
drivers/remoteproc/stm32_rproc.c +2 -4
@@ -234,9 +234,8 @@ static int stm32_rproc_prepare(struct rproc *rproc)static int stm32_rproc_parse_fw (struct rproc *rproc,const struct firmware *fw) { -if (rproc_elf_load_rsc_table (rproc, fw)) -dev_warn (&rproc->dev,"no resource table found for this firmware\n" ); - +rproc_elf_load_rsc_table_optional (rproc, fw, dev_warn, +"no resource table found for this firmware\n" );return 0 ; }
@@ -928,4 +927,3 @@ MODULE_DESCRIPTION("STM32 Remote Processor Control Driver");MODULE_AUTHOR ("Ludovic Barre <[email protected]>" );MODULE_AUTHOR ("Fabien Dessenne <[email protected]>" );MODULE_LICENSE ("GPL v2" ); -
drivers/remoteproc/xlnx_r5_remoteproc.c +9 -14
@@ -675,20 +675,15 @@ static int add_tcm_banks(struct rproc *rproc)*/ static int zynqmp_r5_parse_fw (struct rproc *rproc,const struct firmware *fw) { -int ret; - - ret =rproc_elf_load_rsc_table (rproc, fw); -if (ret == -EINVAL ) { -/* -* resource table only required for IPC. -* if not present, this is not necessarily an error; -* for example, loading r5 hello world application -* so simply inform user and keep going. -*/ -dev_info (&rproc->dev,"no resource table found.\n" ); - ret =0 ; - } -return ret; +/* +* resource table only required for IPC. +* if not present, this is not necessarily an error; +* for example, loading r5 hello world application +* so simply inform user and keep going. +*/ +rproc_elf_load_rsc_table_optional (rproc, fw, dev_info, +"no resource table found.\n" ); +return 0 ; }/**
Signature · 1 line
2.34.1
[email protected]
AI reviewRe: [PATCH v3 5/5] remoteproc: switch drivers to optional resource-table helper
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [Medium] The `rproc_elf_load_rsc_table_optional` macro hides unconditional function returns, making the…
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The rproc_elf_load_rsc_table_optional macro hides unconditional function returns, making the trailing return 0; in all calling functions unreachable.
- [Medium] Undocumented change in error propagation for multiple drivers which previously ignored non-EINVAL errors.
--
commit 9602dbc4d243a49c62f52f899683404a0f547124
Author: Ben Levinsky <[email protected]>
remoteproc: switch drivers to optional resource-table helper
This commit updates several remoteproc drivers to use the new shared rproc_elf_load_rsc_table_optional() helper for handling optional resource tables.
Quoted 4 lines
Keep thin local
parse_fw()wrappers in each driver so the helper only centralizes the return-value handling while each platform retains control over whether the missing-table case is logged and at what severity.
[Severity: Medium]
Is this description entirely accurate? Prior to this patch, drivers like imx_dsp_rproc and rcar_rproc completely ignored all errors from rproc_elf_load_rsc_table() and unconditionally returned 0.
The new rproc_elf_load_rsc_table_optional() macro propagates non--EINVAL errors (such as -ENOMEM). While this propagation is likely a functional improvement, it is a behavior change for these drivers rather than just centralizing the return-value handling. Should this change in error propagation be explicitly documented in the commit message?
Quoted 5 lines
drivers/remoteproc/imx_dsp_rproc.c +0
-0
drivers/remoteproc/imx_dsp_rproc.c static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc, const struct fir · line 961
Quoted 9 lines
drivers/remoteproc/imx_dsp_rproc.c +2
-3@@ -956,9 +956,8 @@ static int imx_dsp_rproc_elf_load_segments(struct rproc *rproc, const struct firstatic int imx_dsp_rproc_parse_fw (struct rproc *rproc,const struct firmware *fw) { -if (rproc_elf_load_rsc_table (rproc, fw)) -dev_warn (&rproc->dev,"no resource table found for this firmware\n" ); - +rproc_elf_load_rsc_table_optional (rproc, fw, dev_warn, +"no resource table found for this firmware\n" );return 0 ;
[Severity: Medium]
Does this leave the trailing 'return 0;' unreachable?
Looking at the definition of rproc_elf_load_rsc_table_optional() in drivers/remoteproc/remoteproc_internal.h:
#define rproc_elf_load_rsc_table_optional(rproc, fw, dev_func, fmt, ...) \
({ \
int ret = rproc_elf_load_rsc_table(rproc, fw); \
if (ret == -EINVAL) { \
dev_func(&rproc->dev, fmt, ##__VA_ARGS__); \
return 0; \
} else { \
return ret; \
} \
})Because the macro uses explicit return statements within the statement expression, it exits the enclosing function entirely. This hides the control flow and renders the trailing 'return 0;' dead code in every driver modified by this patch.
[ ... ]
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=5
Hi Ben,
Quoted 11 lines
For the carveout map/unmap cleanup, this series covers the exact-match users called out in review:
xlnx_r5_remoteproc,rcar_rproc,st_remoteproc,stm32_rproc,imx_rproc, andimx_dsp_rproc. The zynqmp R5 TCM mapping path is left alone because it also clears the mapped memory and is not an exact match.For the optional resource-table handling, this series converts
xlnx_r5_remoteproc,rcar_rproc,stm32_rproc,imx_rproc, andimx_dsp_rproc.st_remoteprocis intentionally left unchanged because itsparse_fw()callback also builds carveouts and is therefore not a direct match for the helper introduced here.
Thank you for this work, much appreciated! I want to test the changes to the Renesas R-Car driver but can only do so early next week due to travels. I hope I have time for review comments earlier, though.
Thanks and happy hacking,
Wolfram
Mathieu Poirier
maintainerGood morning,
Quoted 76 lines · Ben Levinsky
This series is a preparatory remoteproc cleanup split out from review of the AMD BRAM-based remoteproc series.
During review, there was a request to move the duplicated plain ioremap_wc()/iounmap() carveout callbacks into common code and to factor the "missing resource table is OK" ELF parsing path into a common helper as well. There was also a request to send that cleanup as its own patchset first, with the AMD BRAM series respun afterwards on top once this cleanup is merged.
This version keeps the same overall cleanup goals as v2, but reworks the optional resource-table pieces based on follow-up review:
- reshape the optional resource-table helper in patch 4 into the thin
parse_fw()wrapper form suggested on the thread
- switch the patch 5 clients over to that helper shape directly,without post-helper rproc->table_ptr checks- keep the driver-local
parse_fw()wrappers and their existing log messages and severity choices
- retain as much of the existing per-driverparse_fw()logic and code placement as possible while moving the missing-table handling through the shared helperThis series now does that in five patches:
1. add common subsystem-private callbacks for the exact-match wc-ioremap carveout case
2. switch the in-tree exact-match users over to those callbacks
3. mark carveouts mapped through the shared wc-ioremap helper as iomem so the framework uses the proper I/O accessors
4. add a common helper for drivers that treat a missing ELF resource table as optional while keeping per-driver logging decisions local
5. switch the matching in-tree drivers over to that helper while keeping thin localparse_fw()wrappersFor the carveout map/unmap cleanup, this series covers the exact-match users called out in review:
xlnx_r5_remoteproc,rcar_rproc,st_remoteproc,stm32_rproc,imx_rproc, andimx_dsp_rproc. The zynqmp R5 TCM mapping path is left alone because it also clears the mapped memory and is not an exact match.For the optional resource-table handling, this series converts
xlnx_r5_remoteproc,rcar_rproc,stm32_rproc,imx_rproc, andimx_dsp_rproc.st_remoteprocis intentionally left unchanged because itsparse_fw()callback also builds carveouts and is therefore not a direct match for the helper introduced here.Changes in v3:
- rework patch 4 so the optional resource-table helper matches the thin-wrapper form suggested in review
- note that patch 4 still triggers a checkpatch --strict warning for the flow-control macro form, but that implementation follows the maintainer's review suggestion for the thinparse_fw()wrapper shape
- update patch 5 to use that helper shape directly in the clientparse_fw()callbacks
- drop the post-helperrproc->table_ptrchecks from the converted drivers
- keep the convertedparse_fw()wrappers otherwise close to their existing structure and placement
- testxlnx_r5_remoteprocon the latest tree with firmware images both with and without an ELF resource tableChanges in v2:
- split themem->is_iomemchange out into a separate patch
- add a common error message onioremap_wc()failure
- drop logging from the optional resource-table helper
- keep driver-localparse_fw()wrappers to preserve per-platform missing-resource-table logging policyBen Levinsky (5):
remoteproc: add common wc-ioremap carveout callbacks
remoteproc: switch exact-match drivers to wc-ioremap callbacks
remoteproc: mark wc-ioremap carveouts as iomem
remoteproc: add helper for optional ELF resource tables
remoteproc: switch drivers to optional resource-table helper
Quoted 7 lines
drivers/remoteproc/imx_dsp_rproc.c | 41 +++----------- drivers/remoteproc/imx_rproc.c | 40 ++------------ drivers/remoteproc/rcar_rproc.c | 41 ++------------ drivers/remoteproc/remoteproc_internal.h | 38 +++++++++++++ drivers/remoteproc/st_remoteproc.c | 31 +---------- drivers/remoteproc/stm32_rproc.c | 39 ++----------- drivers/remoteproc/xlnx_r5_remoteproc.c | 70 +++++-------------------
This set looks good to me. I am fine with the checkpatch warning on the macro - given the redundancy it avoids, I think it can be tolerated.
Wolfram has already indicated he wanted to test these changes - Arnaud, Daniel and Peng, please do the same for your platforms.
Thanks,
Mathieu
Quoted 4 lines
7 files changed, 73 insertions(+), 227 deletions(-)Signature · 1 line
2.34.1
Peng Fan
Tested-byQuoted 87 lines · Mathieu Poirier
Good morning,
Quoted 76 lines · Ben Levinsky
This series is a preparatory remoteproc cleanup split out from review of the AMD BRAM-based remoteproc series.
During review, there was a request to move the duplicated plain ioremap_wc()/iounmap() carveout callbacks into common code and to factor the "missing resource table is OK" ELF parsing path into a common helper as well. There was also a request to send that cleanup as its own patchset first, with the AMD BRAM series respun afterwards on top once this cleanup is merged.
This version keeps the same overall cleanup goals as v2, but reworks the optional resource-table pieces based on follow-up review:
- reshape the optional resource-table helper in patch 4 into the thin
parse_fw()wrapper form suggested on the thread
- switch the patch 5 clients over to that helper shape directly,without post-helper rproc->table_ptr checks- keep the driver-local
parse_fw()wrappers and their existing log messages and severity choices
- retain as much of the existing per-driverparse_fw()logic and code placement as possible while moving the missing-table handling through the shared helperThis series now does that in five patches:
1. add common subsystem-private callbacks for the exact-match wc-ioremap carveout case
2. switch the in-tree exact-match users over to those callbacks
3. mark carveouts mapped through the shared wc-ioremap helper as iomem so the framework uses the proper I/O accessors
4. add a common helper for drivers that treat a missing ELF resource table as optional while keeping per-driver logging decisions local
5. switch the matching in-tree drivers over to that helper while keeping thin localparse_fw()wrappersFor the carveout map/unmap cleanup, this series covers the exact-match users called out in review:
xlnx_r5_remoteproc,rcar_rproc,st_remoteproc,stm32_rproc,imx_rproc, andimx_dsp_rproc. The zynqmp R5 TCM mapping path is left alone because it also clears the mapped memory and is not an exact match.For the optional resource-table handling, this series converts
xlnx_r5_remoteproc,rcar_rproc,stm32_rproc,imx_rproc, andimx_dsp_rproc.st_remoteprocis intentionally left unchanged because itsparse_fw()callback also builds carveouts and is therefore not a direct match for the helper introduced here.Changes in v3:
- rework patch 4 so the optional resource-table helper matches the thin-wrapper form suggested in review
- note that patch 4 still triggers a checkpatch --strict warning for the flow-control macro form, but that implementation follows the maintainer's review suggestion for the thinparse_fw()wrapper shape
- update patch 5 to use that helper shape directly in the clientparse_fw()callbacks
- drop the post-helperrproc->table_ptrchecks from the converted drivers
- keep the convertedparse_fw()wrappers otherwise close to their existing structure and placement
- testxlnx_r5_remoteprocon the latest tree with firmware images both with and without an ELF resource tableChanges in v2:
- split themem->is_iomemchange out into a separate patch
- add a common error message onioremap_wc()failure
- drop logging from the optional resource-table helper
- keep driver-localparse_fw()wrappers to preserve per-platform missing-resource-table logging policyBen Levinsky (5):
remoteproc: add common wc-ioremap carveout callbacks
remoteproc: switch exact-match drivers to wc-ioremap callbacks
remoteproc: mark wc-ioremap carveouts as iomem
remoteproc: add helper for optional ELF resource tables
remoteproc: switch drivers to optional resource-table helperQuoted 7 lines
drivers/remoteproc/imx_dsp_rproc.c | 41 +++----------- drivers/remoteproc/imx_rproc.c | 40 ++------------ drivers/remoteproc/rcar_rproc.c | 41 ++------------ drivers/remoteproc/remoteproc_internal.h | 38 +++++++++++++ drivers/remoteproc/st_remoteproc.c | 31 +---------- drivers/remoteproc/stm32_rproc.c | 39 ++----------- drivers/remoteproc/xlnx_r5_remoteproc.c | 70 +++++-------------------
Quoted 5 lines
This set looks good to me. I am fine with the checkpatch warning on the macro - given the redundancy it avoids, I think it can be tolerated.
Wolfram has already indicated he wanted to test these changes - Arnaud, Daniel and Peng, please do the same for your platforms.
Quoted 8 lines
Thanks,
MathieuQuoted 4 lines
7 files changed, 73 insertions(+), 227 deletions(-)Signature · 1 line
2.34.1
Quoted 3 lines
Wolfram has already indicated he wanted to test these changes - Arnaud, Daniel and Peng, please do the same for your platforms.
Testing is more involved than I expected. Didn't work out this week. I'll keep trying for next week. But it may end up the week after that.
Applied.
Thanks,
Mathieu
Quoted 87 lines · Ben Levinsky
This series is a preparatory remoteproc cleanup split out from review of the AMD BRAM-based remoteproc series.
During review, there was a request to move the duplicated plain ioremap_wc()/iounmap() carveout callbacks into common code and to factor the "missing resource table is OK" ELF parsing path into a common helper as well. There was also a request to send that cleanup as its own patchset first, with the AMD BRAM series respun afterwards on top once this cleanup is merged.
This version keeps the same overall cleanup goals as v2, but reworks the optional resource-table pieces based on follow-up review:
- reshape the optional resource-table helper in patch 4 into the thin
parse_fw()wrapper form suggested on the thread
- switch the patch 5 clients over to that helper shape directly,without post-helper rproc->table_ptr checks- keep the driver-local
parse_fw()wrappers and their existing log messages and severity choices
- retain as much of the existing per-driverparse_fw()logic and code placement as possible while moving the missing-table handling through the shared helperThis series now does that in five patches:
1. add common subsystem-private callbacks for the exact-match wc-ioremap carveout case
2. switch the in-tree exact-match users over to those callbacks
3. mark carveouts mapped through the shared wc-ioremap helper as iomem so the framework uses the proper I/O accessors
4. add a common helper for drivers that treat a missing ELF resource table as optional while keeping per-driver logging decisions local
5. switch the matching in-tree drivers over to that helper while keeping thin localparse_fw()wrappersFor the carveout map/unmap cleanup, this series covers the exact-match users called out in review:
xlnx_r5_remoteproc,rcar_rproc,st_remoteproc,stm32_rproc,imx_rproc, andimx_dsp_rproc. The zynqmp R5 TCM mapping path is left alone because it also clears the mapped memory and is not an exact match.For the optional resource-table handling, this series converts
xlnx_r5_remoteproc,rcar_rproc,stm32_rproc,imx_rproc, andimx_dsp_rproc.st_remoteprocis intentionally left unchanged because itsparse_fw()callback also builds carveouts and is therefore not a direct match for the helper introduced here.Changes in v3:
- rework patch 4 so the optional resource-table helper matches the thin-wrapper form suggested in review
- note that patch 4 still triggers a checkpatch --strict warning for the flow-control macro form, but that implementation follows the maintainer's review suggestion for the thinparse_fw()wrapper shape
- update patch 5 to use that helper shape directly in the clientparse_fw()callbacks
- drop the post-helperrproc->table_ptrchecks from the converted drivers
- keep the convertedparse_fw()wrappers otherwise close to their existing structure and placement
- testxlnx_r5_remoteprocon the latest tree with firmware images both with and without an ELF resource tableChanges in v2:
- split themem->is_iomemchange out into a separate patch
- add a common error message onioremap_wc()failure
- drop logging from the optional resource-table helper
- keep driver-localparse_fw()wrappers to preserve per-platform missing-resource-table logging policyBen Levinsky (5):
remoteproc: add common wc-ioremap carveout callbacks
remoteproc: switch exact-match drivers to wc-ioremap callbacks
remoteproc: mark wc-ioremap carveouts as iomem
remoteproc: add helper for optional ELF resource tables
remoteproc: switch drivers to optional resource-table helperdrivers/remoteproc/imx_dsp_rproc.c | 41 +++----------- drivers/remoteproc/imx_rproc.c | 40 ++------------ drivers/remoteproc/rcar_rproc.c | 41 ++------------ drivers/remoteproc/remoteproc_internal.h | 38 +++++++++++++ drivers/remoteproc/st_remoteproc.c | 31 +---------- drivers/remoteproc/stm32_rproc.c | 39 ++----------- drivers/remoteproc/xlnx_r5_remoteproc.c | 70 +++++------------------- 7 files changed, 73 insertions(+), 227 deletions(-)Signature · 1 line
2.34.1