All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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 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.