On Wed, May 06, 2026 at 10:31:04AM +0530, Mukesh Ojha wrote: > Replace the open-coded resource table iteration loop in > rproc_handle_resources() with the rsc_table_for_each_entry() helper. > > The remoteproc-specific dispatch logic (vendor resource handling via > rproc_handle_rsc(), RSC_LAST bounds check, handler table lookup) is > moved into a local callback rproc_handle_rsc_entry(), keeping the > iteration mechanics in one canonical place. > > The callback receives the payload offset within the table so that > handlers which write back into the resource table (e.g. > rproc_handle_carveout() recording a dynamically allocated address via > rsc_offset) continue to work correctly. > > No functional change. > > Signed-off-by: Mukesh Ojha <[email protected]> > --- > drivers/remoteproc/remoteproc_core.c | 81 +++++++++++++--------------- > include/linux/rsc_table.h | 53 ++++++++++++++++++ > 2 files changed, 91 insertions(+), 43 deletions(-) >
Reviewed-by: Mathieu Poirier <[email protected]> > diff --git a/drivers/remoteproc/remoteproc_core.c > b/drivers/remoteproc/remoteproc_core.c > index b087ed21858a..f003be006b1b 100644 > --- a/drivers/remoteproc/remoteproc_core.c > +++ b/drivers/remoteproc/remoteproc_core.c > @@ -1011,60 +1011,55 @@ static rproc_handle_resource_t > rproc_loading_handlers[RSC_LAST] = { > [RSC_VDEV] = rproc_handle_vdev, > }; > > -/* handle firmware resource entries before booting the remote processor */ > -static int rproc_handle_resources(struct rproc *rproc, > - rproc_handle_resource_t handlers[RSC_LAST]) > +struct rproc_rsc_cb_data { > + struct rproc *rproc; > + rproc_handle_resource_t *handlers; > +}; > + > +static int rproc_handle_rsc_entry(u32 type, void *rsc, int offset, > + int avail, void *data) > { > + struct rproc_rsc_cb_data *d = data; > + struct rproc *rproc = d->rproc; > struct device *dev = &rproc->dev; > rproc_handle_resource_t handler; > - int ret = 0, i; > - > - if (!rproc->table_ptr) > - return 0; > + int ret; > > - for (i = 0; i < rproc->table_ptr->num; i++) { > - int offset = rproc->table_ptr->offset[i]; > - struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset; > - int avail = rproc->table_sz - offset - sizeof(*hdr); > - void *rsc = (void *)hdr + sizeof(*hdr); > + dev_dbg(dev, "rsc: type %d\n", type); > > - /* make sure table isn't truncated */ > - if (avail < 0) { > - dev_err(dev, "rsc table is truncated\n"); > - return -EINVAL; > - } > - > - dev_dbg(dev, "rsc: type %d\n", hdr->type); > + if (type >= RSC_VENDOR_START && type <= RSC_VENDOR_END) { > + ret = rproc_handle_rsc(rproc, type, rsc, offset, avail); > + if (ret == RSC_HANDLED) > + return 0; > + if (ret < 0) > + return ret; > + dev_warn(dev, "unsupported vendor resource %d\n", type); > + return 0; > + } > > - if (hdr->type >= RSC_VENDOR_START && > - hdr->type <= RSC_VENDOR_END) { > - ret = rproc_handle_rsc(rproc, hdr->type, rsc, > - offset + sizeof(*hdr), avail); > - if (ret == RSC_HANDLED) > - continue; > - else if (ret < 0) > - break; > + if (type >= RSC_LAST) { > + dev_warn(dev, "unsupported resource %d\n", type); > + return 0; > + } > > - dev_warn(dev, "unsupported vendor resource %d\n", > - hdr->type); > - continue; > - } > + handler = d->handlers[type]; > + if (!handler) > + return 0; > > - if (hdr->type >= RSC_LAST) { > - dev_warn(dev, "unsupported resource %d\n", hdr->type); > - continue; > - } > + return handler(rproc, rsc, offset, avail); > +} > > - handler = handlers[hdr->type]; > - if (!handler) > - continue; > +/* handle firmware resource entries before booting the remote processor */ > +static int rproc_handle_resources(struct rproc *rproc, > + rproc_handle_resource_t handlers[RSC_LAST]) > +{ > + struct rproc_rsc_cb_data d = { .rproc = rproc, .handlers = handlers }; > > - ret = handler(rproc, rsc, offset + sizeof(*hdr), avail); > - if (ret) > - break; > - } > + if (!rproc->table_ptr) > + return 0; > > - return ret; > + return rsc_table_for_each_entry(rproc->table_ptr, rproc->table_sz, > + &rproc->dev, rproc_handle_rsc_entry, > &d); > } > > static int rproc_prepare_subdevices(struct rproc *rproc) > diff --git a/include/linux/rsc_table.h b/include/linux/rsc_table.h > index c32c8b6cd2a7..c6d6d553d8f1 100644 > --- a/include/linux/rsc_table.h > +++ b/include/linux/rsc_table.h > @@ -303,4 +303,57 @@ struct fw_rsc_vdev { > struct fw_rsc_vdev_vring vring[]; > } __packed; > > +/** > + * rsc_table_for_each_entry() - iterate over all entries in a resource table > + * @table: pointer to the resource table > + * @table_sz: total size of the table buffer in bytes > + * @dev: device used for error logging > + * @cb: callback invoked for each entry: > + * @type - value from enum fw_resource_type > + * @rsc - pointer to the entry payload (past struct > fw_rsc_hdr) > + * @offset - byte offset of the payload within the table; > callers > + * that write back into the table (e.g. to record a > + * dynamically allocated address) use this to locate > the > + * entry for later update > + * @avail - bytes available in the payload > + * @data - caller-supplied private pointer > + * Return 0 to continue iteration, non-zero to stop. > + * @data: private pointer forwarded to @cb on every call > + * > + * Iterates over every resource entry in @table, performing the standard > + * truncation check, and invokes @cb for each one. Iteration stops on the > + * first non-zero return from @cb or on a malformed table. > + * > + * Returns 0 after a complete iteration, -EINVAL if the table is truncated, > + * or the first non-zero value returned by @cb. > + */ > +static inline int rsc_table_for_each_entry(struct resource_table *table, > + size_t table_sz, > + struct device *dev, > + int (*cb)(u32 type, void *rsc, > + int offset, int avail, > + void *data), > + void *data) { > + int i, ret; > + > + for (i = 0; i < table->num; i++) { > + int offset = table->offset[i]; > + struct fw_rsc_hdr *hdr = (void *)table + offset; > + int avail = table_sz - offset - sizeof(*hdr); > + int rsc_offset = offset + sizeof(*hdr); > + void *rsc = (void *)hdr + sizeof(*hdr); > + > + if (avail < 0) { > + dev_err(dev, "rsc table is truncated\n"); > + return -EINVAL; > + } > + > + ret = cb(hdr->type, rsc, rsc_offset, avail, data); > + if (ret) > + return ret; > + } > + > + return 0; > +} > + > #endif /* RSC_TABLE_H */ > -- > 2.53.0 >

