All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Srinivas Kandagatla" <srinivas.kandagatla@oss.qualcomm.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v2 2/3] soundwire: qcom: add multi-master support
Date: Thu, 01 Oct 2026 10:02:32 +0000	[thread overview]
Message-ID: <20261001100233.1EDB11F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20261001093806.634862-3-srinivas.kandagatla@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] soundwire: qcom: use-after-free in qcom_swrm_multi_master_setup due to lockless drvdata access
- [High] soundwire: qcom: out-of-bounds MMIO access due to unchecked port_num underflow
- [High] soundwire: qcom: clock double-disable and unclocked access risk in remove path
- [Medium] soundwire: qcom: interface clock leaked for dependent multi-master device
--

commit c7571d3da0c003125e279a9926c2184e7157d267
Author: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
soundwire: qcom: add multi-master support

This commit adds support for v3.1.0+ Qualcomm SoundWire IPs that are paired
to expose one logical bus with more than two DATA lanes. It introduces a
multi-master mode where one primary IP owns SWR_CLK and handles commands,
while the dependent IP provides data lanes only. A device link enforces
unbind ordering between the two controllers.

> diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
> index 35ffffd541bd1..767147a6635dc 100644
> --- a/drivers/soundwire/qcom.c
> +++ b/drivers/soundwire/qcom.c
[ ... ]
> @@ -1040,9 +1051,41 @@ static int qcom_swrm_pre_bank_switch(struct sdw_bus *bus)
[ ... ]
> +static struct qcom_swrm_ctrl *
> +qcom_swrm_port_target(struct qcom_swrm_ctrl *ctrl, u8 port_num, u32 *reg)
> +{
> +	u8 lane = ctrl->pconfig[port_num].lane_control;
> +
> +	if (ctrl->peer_ctrl && lane >= ctrl->peer_first_lane &&
> +	    lane < ctrl->peer_first_lane + ctrl->num_peer_lanes) {
> +		*reg -= ctrl->peer_dpn_offset;

[Severity: High]
Is there a risk of an integer underflow here resulting in an out-of-bounds
MMIO access?

If the device tree maps a logical port (port_num) where the computed register
address is smaller than the offset parameter passed via
qcom,multi-master-peer, *reg would underflow.

This wrapped address would then be used in reg_write, writing directly to
out-of-bounds MMIO. Does this subtraction require bounds checking?

> +		return ctrl->peer_ctrl;
> +	}
> +	return ctrl;
> +}
[ ... ]
> @@ -1562,6 +1610,73 @@ static int swrm_reg_show(struct seq_file *s_file, void *data)
[ ... ]
> +static int qcom_swrm_multi_master_setup(struct qcom_swrm_ctrl *ctrl)
> +{
> +	struct of_phandle_args args;
> +	struct qcom_swrm_ctrl *peer;
> +	struct platform_device *pdev;
> +	u32 offset;
> +	int ret;
[ ... ]
> +	pdev = of_find_device_by_node(args.np);
> +	of_node_put(args.np);
> +	if (!pdev)
> +		return -EPROBE_DEFER;
[ ... ]
> +	peer = platform_get_drvdata(pdev);
> +	if (!peer || !peer->is_dependent) {

[Severity: High]
Can evaluating peer->is_dependent here lead to a use-after-free?

platform_get_drvdata(pdev) is called without holding device_lock(&pdev->dev).
If a concurrent sysfs unbind occurs on the peer device, devres could free the
qcom_swrm_ctrl structure right before dev_set_drvdata(dev, NULL) is called
in the driver core teardown.

This creates a window where peer points to freed memory when evaluating
peer->is_dependent.

> +		ret = -EPROBE_DEFER;
> +		goto out;
> +	}
[ ... ]
> @@ -1689,6 +1817,16 @@ static int qcom_swrm_probe(struct platform_device *pdev)
[ ... ]
> +	if (of_property_match_string(dev->of_node, "qcom,multi-master-mode", "dependent") >= 0) {
> +		ctrl->is_dependent = true;
> +		dev_dbg(dev,
> +			"Qualcomm SoundWire multi-master dependent v%x.%x.%x registered (%u lanes)\n",
> +			(ctrl->version >> 24) & 0xff,
> +			(ctrl->version >> 16) & 0xff,
> +			ctrl->version & 0xffff, ctrl->num_lanes);
> +		return 0;

[Severity: Medium]
Does this early return permanently strand the interface clock in a powered-on
state?

Because probe returns 0 early for dependent devices, it bypasses
pm_runtime_enable(). Since probe already called
clk_prepare_enable(ctrl->hclk), the clock is never disabled as
swrm_runtime_suspend will never be invoked for the dependent device.

If the clock is shared with the primary device, the dependent's reference
keeps the physical clock constantly on.

> +	}
> +
>  	ret = sdw_bus_master_add(&ctrl->bus, dev, dev->fwnode);
[ ... ]
> @@ -1733,7 +1886,21 @@ static void qcom_swrm_remove(struct platform_device *pdev)
>  {
>  	struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(&pdev->dev);
>  
> -	sdw_bus_master_delete(&ctrl->bus);
> +	/* delete bus before dropping peer_ctrl; in-flight ops deref it */
> +	if (!ctrl->is_dependent)
> +		sdw_bus_master_delete(&ctrl->bus);
> +
> +	if (ctrl->is_primary && ctrl->peer_ctrl) {
> +		struct qcom_swrm_ctrl *peer = ctrl->peer_ctrl;
> +
> +		peer->reg_write(peer,
> +				peer->reg_layout[SWRM_REG_INTERRUPT_CPU_EN], 0);

[Severity: High]
Does this risk unclocked hardware access or unbalanced clock disables?

qcom_swrm_remove executes these teardown writes and the subsequent
clk_disable_unprepare without first calling pm_runtime_get_sync(ctrl->dev).
Since the driver core may call remove while the device is runtime suspended
(where swrm_runtime_suspend has already disabled hclk), writing to peer
registers during this suspended state may cause interconnect stalls.

Furthermore, clk_disable_unprepare(ctrl->hclk) gets called twice, causing a
clock underflow warning from the clock framework.

> +		/* disable peer SWRM; releases shared SWR_CLK */
> +		peer->reg_write(peer, SWRM_COMP_CFG_ADDR, 0);
> +		peer->peer_ctrl = NULL;
> +		ctrl->peer_ctrl = NULL;
> +	}
> +
>  	clk_disable_unprepare(ctrl->hclk);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261001093806.634862-1-srinivas.kandagatla@oss.qualcomm.com?part=2

  reply	other threads:[~2026-10-01 10:02 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01  9:38 [PATCH v2 0/3] soundwire: qcom: add multi-master support Srinivas Kandagatla
2026-10-01  9:38 ` [PATCH v2 1/3] dt-bindings: soundwire: qcom: describe multi-master Srinivas Kandagatla
2026-10-01  9:38 ` [PATCH v2 2/3] soundwire: qcom: add multi-master support Srinivas Kandagatla
2026-10-01 10:02   ` sashiko-bot [this message]
2026-10-01 10:53   ` Pierre-Louis Bossart
2026-10-01 11:06     ` Srinivas Kandagatla
2026-10-02  7:36       ` Pierre-Louis Bossart
2026-10-03  7:41       ` Vinod Koul
2026-10-01  9:38 ` [PATCH v2 3/3] soundwire: qcom: program MM_SYNC for multi-master Srinivas Kandagatla

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=20261001100233.1EDB11F000FF@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=srinivas.kandagatla@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.