From: sashiko-bot@kernel.org
To: "Vinayak Katoch" <vinayak.katoch@oss.qualcomm.com>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v6 1/3] misc: fastrpc: iterate CB nodes manually instead of of_platform_populate
Date: Wed, 21 Oct 2026 10:18:03 +0000 [thread overview]
Message-ID: <sashiko-outbox-180091@kernel.org> (raw)
In-Reply-To: <20261021-dup-sessions-v6-1-578ab52ba66c@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] misc: fastrpc: double of_node_put() in fastrpc_cb_devices_create()
- [High] misc: fastrpc: missing DMA and IOMMU setup in fastrpc_cb_devices_create()
- [High] misc: fastrpc: premature misc_register() before fastrpc_cb_devices_create()
--
commit 17aff65cbac844472a8706f83a0e300c3444f667
Author: Vinayak Katoch <vinayak.katoch@oss.qualcomm.com>
misc: fastrpc: iterate CB nodes manually instead of of_platform_populate
This commit replaces of_platform_populate() and the separate
fastrpc_cb_driver platform driver with manual iteration over child DT nodes
in fastrpc_cb_devices_create() and cleanup in fastrpc_cb_devices_destroy()
so context banks are initialized synchronously during fastrpc_rpmsg_probe().
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index af18ff1992eed..caa479f304c1c 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
[ ... ]
> @@ -2389,37 +2388,51 @@ static int fastrpc_cb_probe(struct platform_device *pdev)
> return 0;
> }
>
> -static void fastrpc_cb_remove(struct platform_device *pdev)
> +static void fastrpc_cb_devices_destroy(struct rpmsg_device *rpdev)
> {
> - struct fastrpc_channel_ctx *cctx = dev_get_drvdata(pdev->dev.parent);
> - struct fastrpc_session_ctx *sess = dev_get_drvdata(&pdev->dev);
> + struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev);
> + struct device *rdev = &rpdev->dev;
> unsigned long flags;
> int i;
>
> spin_lock_irqsave(&cctx->lock, flags);
> - for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) {
> - if (cctx->session[i].sid == sess->sid) {
> - cctx->session[i].valid = false;
> - cctx->sesscount--;
> - }
> - }
> + for (i = 0; i < cctx->sesscount; i++)
> + cctx->session[i].valid = false;
> spin_unlock_irqrestore(&cctx->lock, flags);
> +
> + device_for_each_child_reverse(rdev, NULL, of_platform_device_destroy);
> }
>
> -static const struct of_device_id fastrpc_match_table[] = {
> - { .compatible = "qcom,fastrpc-compute-cb" },
> - { }
> -};
> +static int fastrpc_cb_devices_create(struct rpmsg_device *rpdev)
> +{
> + struct device *rdev = &rpdev->dev;
> + struct platform_device *pdev;
> + struct device_node *np;
> + int err;
>
> -static struct platform_driver fastrpc_cb_driver = {
> - .probe = fastrpc_cb_probe,
> - .remove = fastrpc_cb_remove,
> - .driver = {
> - .name = "qcom,fastrpc-cb",
> - .of_match_table = fastrpc_match_table,
> - .suppress_bind_attrs = true,
> - },
> -};
> + for_each_available_child_of_node(rdev->of_node, np) {
> + if (!of_device_is_compatible(np, "qcom,fastrpc-compute-cb")) {
> + of_node_put(np);
> + continue;
> + }
[Severity: High]
Won't calling of_node_put(np) before continue in fastrpc_cb_devices_create()
cause a double-put on np when an available child node is not compatible with
"qcom,fastrpc-compute-cb"?
for_each_available_child_of_node() advances by calling
of_get_next_available_child() -> of_get_next_status_child() in
drivers/of/base.c:
of_node_put(prev);
raw_spin_unlock_irqrestore(&devtree_lock, flags);
return next;
Because the loop increment expression dereferences prev->sibling and
automatically calls of_node_put(prev) on each step, dropping the reference on
np explicitly before continue underflows the struct device_node reference
count and can lead to a use-after-free.
> +
> + pdev = of_platform_device_create(np, NULL, rdev);
> + if (!pdev) {
> + of_node_put(np);
> + fastrpc_cb_devices_destroy(rpdev);
> + return -ENODEV;
> + }
> +
> + err = fastrpc_cb_init(pdev);
> + if (err) {
> + of_node_put(np);
> + fastrpc_cb_devices_destroy(rpdev);
> + return err;
> + }
> + }
> +
> + return 0;
> +}
[Severity: High]
With fastrpc_cb_driver removed, how are DMA and IOMMU configuration and
probe deferral handled for the context bank platform devices created in
fastrpc_cb_devices_create()?
Previously, binding each qcom,fastrpc-compute-cb device to fastrpc_cb_driver
went through really_probe() in drivers/base/dd.c, which checked supplier
links via device_links_check_suppliers(dev), set dev->driver, and called
platform_dma_configure() in drivers/base/platform.c:
if (is_of_node(fwnode)) {
ret = of_dma_configure(dev, to_of_node(fwnode), true);
} else if (is_acpi_device_node(fwnode)) {
attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
ret = acpi_dma_configure(dev, attr);
}
/* @dev->driver may not be valid when we're called from the IOMMU layer */
if (ret || !drv || to_platform_driver(drv)->driver_managed_dma)
return ret;
ret = iommu_device_use_default_domain(dev);
Without a bound platform_driver or an explicit of_dma_configure() call in
fastrpc_cb_devices_create() or fastrpc_cb_init(), pdev->dev.driver is always
NULL:
1. Because the iommus property resides on the child compute-cb DT nodes
rather than the parent rpmsg node, fw_devlink only creates proxy
sync_state links on rdev. During of_platform_device_create() ->
device_add(), iommu_init_device() in drivers/iommu/iommu.c calls
dev->bus->dma_configure(dev) with dev->driver == NULL and ignores its
return value. If the SMMU has not probed yet and of_iommu_configure()
returns -EPROBE_DEFER in of_dma_configure_id() (drivers/of/device.c), it
returns early before arch_setup_dma_ops(dev, coherent), yet
fastrpc_cb_init() still succeeds and marks sess->valid = true with
unconfigured DMA ops and no IOMMU translation. A subsequent
bus_iommu_probe() replay of of_dma_configure_id() also overwrites
*dev->dma_mask with the 32-bit coherent_dma_mask, clobbering the 34-bit
mask set via dma_set_mask() in fastrpc_cb_init().
2. When CONFIG_IOMMU_API is disabled, iommu_bus_notifier is not registered
and of_dma_configure() is never called on pdev->dev at all.
3. Even when the SMMU has already probed, platform_dma_configure() returns
before calling iommu_device_use_default_domain(dev) because dev->driver
is NULL (leaving group->owner_cnt at 0 while fastrpc performs DMA
allocations and dma_buf mappings on sess->dev), and managed supplier
device links to pdev->dev remain unactivated because
device_links_driver_bound() never runs.
> @@ -2639,7 +2652,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
> data->rpdev = rpdev;
> dev_set_drvdata(&rpdev->dev, data);
>
> - err = of_platform_populate(rdev->of_node, NULL, NULL, rdev);
> + err = fastrpc_cb_devices_create(rpdev);
> if (err)
> goto err_deregister_fdev;
>
[Severity: High]
Could calling fastrpc_cb_devices_create() after fastrpc_device_register() in
fastrpc_rpmsg_probe() still expose partially initialized sessions to
userspace and trigger a use-after-free on failure?
Earlier in fastrpc_rpmsg_probe(), fastrpc_device_register() calls
misc_register() before data->refcount, data->users, data->lock, data->ctx_idr,
and data->rpdev are initialized, and before fastrpc_cb_devices_create(rpdev)
is called (as well as before ADSP duplicate session creation in "misc:
fastrpc: move ADSP duplicate session creation to the driver"). Inside
fastrpc_cb_init(), sess->valid = true and cctx->sesscount++ are also published
under cctx->lock before dma_set_mask() is executed:
sess = &cctx->session[cctx->sesscount++];
sess->used = false;
sess->valid = true;
sess->dev = dev;
sess->sid = sid;
...
spin_unlock_irqrestore(&cctx->lock, flags);
rc = dma_set_mask(dev, DMA_BIT_MASK(dma_bits));
if (rc) {
dev_err(dev, "%u-bit DMA enable failed\n", dma_bits);
return rc;
}
Because the miscdevices are already registered while
fastrpc_cb_devices_create() iterates over the DT child nodes, a concurrent
fastrpc_device_open() -> fastrpc_session_alloc() can still observe zero or a
partial set of sessions, or acquire an earlier session and take a reference
on data via fastrpc_channel_ctx_get(cctx).
Unlike of_platform_populate() which previously returned 0 even if child
device creation failed, if dma_set_mask() fails or a later CB node fails in
of_platform_device_create() or fastrpc_cb_init(), fastrpc_cb_devices_create()
destroys the CB platform devices and fastrpc_rpmsg_probe() jumps to
err_deregister_fdev -> err_free_data: kfree(data), freeing data while an open
file descriptor still holds references to fl->cctx and fl->sctx->dev. Should
fastrpc_device_register() be called only after cctx and all CB sessions have
been fully initialized?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261021-dup-sessions-v6-0-578ab52ba66c@oss.qualcomm.com?part=1
next prev parent reply other threads:[~2026-10-21 10:18 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 9:25 [PATCH v6 0/3] misc: fastrpc: fix ADSP duplicate session creation Vinayak Katoch
2026-10-21 9:25 ` [PATCH v6 1/3] misc: fastrpc: iterate CB nodes manually instead of of_platform_populate Vinayak Katoch
2026-10-21 10:18 ` sashiko-bot [this message]
2026-10-21 9:25 ` [PATCH v6 2/3] misc: fastrpc: move ADSP duplicate session creation to the driver Vinayak Katoch
2026-10-21 9:44 ` sashiko-bot
2026-10-21 9:25 ` [PATCH v6 3/3] dt-bindings: misc: qcom,fastrpc: deprecate qcom,nsessions Vinayak Katoch
2026-10-21 9:41 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-180091@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vinayak.katoch@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox