From: sashiko-bot@kernel.org
To: "Vijendar Mukunda" <Vijendar.Mukunda@amd.com>
Cc: linux-sound@vger.kernel.org
Subject: Re: [PATCH 2/4] ASoC: SOF: amd: guard adata->sdw dereferences with NULL check in IRQ handler
Date: Sat, 07 Nov 2026 18:11:38 +0000 [thread overview]
Message-ID: <sashiko-outbox-203155@kernel.org> (raw)
In-Reply-To: <20261107175339.3547918-3-Vijendar.Mukunda@amd.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] ASoC: SOF: amd: NULL dereference of adata->sdw->pdev[i] in
acp_irq_handler()
- [Low] ASoC: SOF: amd: inaccurate teardown claim and missing Fixes tag
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [Medium] soundwire: amd: memory and platform device leaks in
sdw_amd_probe() [1]
--
commit 920e1ff1deb60367eb67bae9d4d4b5880a64d07f
Author: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
> ASoC: SOF: amd: guard adata->sdw dereferences with NULL check in IRQ handler
>
> The ACP external IRQ handler is registered before sdw_amd_probe() assigns
> adata->sdw, so a stray interrupt in the probe window could reach the
> adata->sdw->pdev[i] dereference with adata->sdw still NULL.
>
> The same window exists on the teardown side: after sdw_amd_exit() frees
> the context but before adata->sdw is cleared by the caller.
>
> Add NULL checks for adata->sdw in acp_irq_handler() before dereferencing
> ->pdev[0] and ->pdev[1], and in amd_sof_handle_acp70_sdw_wake_event() for
> the same reason. The interrupt-status register write that acknowledges the
> IRQ is kept outside the guard so the hardware bit is always cleared
> regardless of whether the SoundWire context is live.
>
> Fixes: 96eb81851012 ("ASoC: SOF: amd: add interrupt handling for SoundWire manager devices")
> Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
[Severity: Low]
Is the teardown window description in the second paragraph accurate? In
amd_sof_sdw_exit(), sdw_amd_exit(acp_data->sdw) frees the context before
acp_data->sdw = NULL runs, so adata->sdw is still non-NULL during that
interval and an if (adata->sdw) check cannot guard it; teardown is safe
instead because callers invoke free_irq(sdev->ipc_irq, sdev) before calling
amd_sof_sdw_exit().
Also, since the unguarded adata->sdw dereferences in
amd_sof_handle_acp70_sdw_wake_event() were introduced by a later commit,
should this include:
Fixes: 1f41bf67bfe3 ("ASoC: SOF: amd: add soundwire wake irq handling")
> diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c
> index 86e2402b8ffd2..623e016f38b83 100644
> --- a/sound/soc/sof/amd/acp.c
> +++ b/sound/soc/sof/amd/acp.c
> @@ -478,16 +478,20 @@ static void amd_sof_handle_acp70_sdw_wake_event(struct acp_dev_data *adata)
> struct amd_sdw_manager *amd_manager;
>
> if (adata->acp70_sdw0_wake_event) {
> - amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
> - if (amd_manager)
> - pm_request_resume(amd_manager->dev);
> + if (adata->sdw) {
> + amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
> + if (amd_manager)
> + pm_request_resume(amd_manager->dev);
> + }
> adata->acp70_sdw0_wake_event = 0;
> }
>
> if (adata->acp70_sdw1_wake_event) {
> - amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
> - if (amd_manager)
> - pm_request_resume(amd_manager->dev);
> + if (adata->sdw) {
> + amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
> + if (amd_manager)
> + pm_request_resume(amd_manager->dev);
> + }
> adata->acp70_sdw1_wake_event = 0;
> }
> }
> @@ -579,10 +583,12 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
>
> val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat);
> if (val & ACP_SDW0_IRQ_MASK) {
> - amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
> snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat, ACP_SDW0_IRQ_MASK);
> - if (amd_manager)
> - schedule_work(&amd_manager->amd_sdw_irq_thread);
> + if (adata->sdw) {
> + amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
> + if (amd_manager)
> + schedule_work(&amd_manager->amd_sdw_irq_thread);
> + }
> irq_flag = 1;
> }
>
> @@ -608,11 +614,13 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
> if (desc->ext_intr_stat1) {
> val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat1);
> if (val & ACP_SDW1_IRQ_MASK) {
> - amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
> snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1,
> ACP_SDW1_IRQ_MASK);
> - if (amd_manager)
> - schedule_work(&amd_manager->amd_sdw_irq_thread);
> + if (adata->sdw) {
> + amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
> + if (amd_manager)
> + schedule_work(&amd_manager->amd_sdw_irq_thread);
> + }
> irq_flag = 1;
> }
[Severity: Medium]
Can adata->sdw->pdev[0] or adata->sdw->pdev[1] still be NULL here when
adata->sdw is non-NULL?
In sdw_amd_probe_controller(), ctx->pdev[index] is only populated for links
set in link_mask:
drivers/soundwire/amd_init.c:sdw_amd_probe_controller() {
...
for (index = 0; index < count; index++) {
if (!(link_mask & BIT(index)))
continue;
...
ctx->pdev[index] = platform_device_register_full(&pdevinfo[index]);
...
}
On single-link configurations where only one SoundWire manager is active,
the unused link's pdev[i] remains NULL while adata->sdw is non-NULL.
Passing &adata->sdw->pdev[i]->dev to dev_get_drvdata() on a stray interrupt
or wake event for the unpopulated link will cause a NULL pointer dereference
in hard IRQ context, unlike the sibling ACP7x handlers in this file (such
as sof_acp7x_handle_sdw_manager_irq()) which check adata->sdw->pdev[instance]
before calling dev_get_drvdata().
[Severity: Medium]
This problem wasn't introduced by this patch, but in the same SoundWire
probe path [1], does a failure in sdw_amd_startup() leak the
sdw_amd_ctx memory and platform devices allocated by
sdw_amd_probe_controller(), as well as adata->dmic_dev in
amd_sof_acp_probe()?
drivers/soundwire/amd_init.c:sdw_amd_probe() {
*sdw_ctx = sdw_amd_probe_controller(res);
if (!*sdw_ctx)
return -ENODEV;
return sdw_amd_startup(*sdw_ctx);
}
sound/soc/sof/amd/acp.c:amd_sof_acp_probe() {
...
adata->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec",
PLATFORM_DEVID_NONE, NULL, 0);
...
ret = amd_sof_sdw_probe(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: SoundWire probe error\n");
free_irq(sdev->ipc_irq, sdev);
return ret;
}
...
unregister_dev:
platform_device_unregister(adata->dmic_dev);
return ret;
}
When sdw_amd_startup() fails, sdw_amd_probe() returns without unregistering
the ctx->pdev[index] devices or freeing ctx, and amd_sof_acp_probe()
returns directly after free_irq() instead of jumping to unregister_dev to
unregister adata->dmic_dev.
[1] https://sashiko.dev/#/bug/linux-3af16781-2451-4877-8594-c12800a7bba5
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261107175339.3547918-1-Vijendar.Mukunda@amd.com?part=2
next prev parent reply other threads:[~2026-11-07 18:11 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 17:52 [PATCH 0/4] ASoC: amd: fix IRQ handler races in AMD SoundWire drivers Vijendar Mukunda
2026-11-07 17:52 ` [PATCH 1/4] ASoC: amd: ps: guard adata->sdw dereferences with NULL check in IRQ handler Vijendar Mukunda
2026-11-07 18:12 ` sashiko-bot
2026-11-07 18:33 ` Mukunda,Vijendar
2026-11-07 17:52 ` [PATCH 2/4] ASoC: SOF: amd: " Vijendar Mukunda
2026-11-07 18:11 ` sashiko-bot [this message]
2026-11-07 17:52 ` [PATCH 3/4] ASoC: SOF: amd: guard SDW IRQ work scheduling with interrupt_enabled flag Vijendar Mukunda
2026-11-07 18:08 ` sashiko-bot
2026-11-07 18:15 ` Mukunda,Vijendar
2026-11-08 1:25 ` kernel test robot
2026-11-08 4:13 ` Mukunda,Vijendar
2026-11-08 11:08 ` kernel test robot
2026-11-08 11:44 ` Mukunda,Vijendar
2026-11-07 17:52 ` [PATCH 4/4] ASoC: amd: ps: " Vijendar Mukunda
2026-11-07 18:12 ` sashiko-bot
2026-11-07 18:52 ` Mukunda,Vijendar
2026-11-08 4:16 ` kernel test robot
2026-11-07 19:39 ` [PATCH 0/4] ASoC: amd: fix IRQ handler races in AMD SoundWire drivers Mukunda,Vijendar
2026-11-07 19:46 ` Mukunda,Vijendar
2026-11-09 14:56 ` Mark Brown
2026-11-11 16:05 ` Mukunda,Vijendar
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-203155@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=Vijendar.Mukunda@amd.com \
--cc=linux-sound@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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