All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: phucduc.bui@gmail.com
Cc: conor+dt@kernel.org, robh@kernel.org, devicetree@vger.kernel.org,
	wsa+renesas@sang-engineering.com
Subject: Re: [PATCH v5 05/11] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown
Date: Tue, 09 Jun 2026 01:59:25 +0000	[thread overview]
Message-ID: <20260609015926.5112C1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260609013107.5995-6-phucduc.bui@gmail.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] The newly added `fsi_stream_is_working()` checks introduce a Time-of-Check to Time-of-Use (TOCTOU) race condition with clock shutdown.

Pre-existing issues:
- [Critical] A pre-existing TOCTOU race condition in PIO transfers causes a NULL pointer dereference because `fsi_stream_is_working()` releases the lock before `io->substream` is accessed.
- [Critical] The DMA transfer handler lacks a stream active check, leading to a fatal NULL pointer dereference if triggered by a shared port interrupt when the stream is stopped.
- [High] The fix fails to add stream activity checks to the PIO data transfer paths called earlier in the same IRQ handler, leaving an active path that still unconditionally triggers system hangs.
--

commit 1b9901efffc6b2d06494ae90af04665e436adbb6
Author: bui duc phuc <phucduc.bui@gmail.com>

ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown

This commit attempts to fix system hangs caused by in-flight IRQs accessing
hardware registers after the SPU clock is disabled. It introduces checks
using fsi_stream_is_working() to return early from IRQ handlers if no
streams are active.

> diff --git a/sound/soc/renesas/fsi.c b/sound/soc/renesas/fsi.c
> --- a/sound/soc/renesas/fsi.c
> +++ b/sound/soc/renesas/fsi.c
> @@ -470,6 +470,10 @@ static int fsi_get_current_fifo_samples(struct fsi_priv *fsi,
>  
>  static void fsi_count_fifo_err(struct fsi_priv *fsi)
>  {
> +	if (!fsi_stream_is_working(fsi, &fsi->playback) &&
> +	    !fsi_stream_is_working(fsi, &fsi->capture))
> +		return;
> +

[Severity: High]
Does this introduce a Time-of-Check to Time-of-Use race condition?

fsi_stream_is_working() acquires and immediately releases master->lock.
If snd_pcm_stop executes concurrently on another CPU right after this check
returns true, it will call fsi_stream_quit() and fsi_hw_shutdown(), setting
substream = NULL and disabling the hardware clocks.

Would the interrupted CPU then proceed to access hardware registers
(like fsi_reg_read(fsi, DOFF_ST) below) with the clocks disabled, resulting
in the exact system hang this patch was intended to fix?

[Severity: High]
This is a pre-existing issue, but the patch missed it while attempting
to fix the exact same issue. In fsi_interrupt(), before
fsi_count_fifo_err() is reached, the driver calls fsi_stream_transfer()
which routes to fsi_pio_push() or fsi_pio_pop().

Both functions immediately calculate sample space by calling
fsi_get_current_fifo_samples(), which unconditionally performs bare
register reads before any stream activity check is performed:

fsi_get_current_fifo_samples() {
        ...
        status = is_play ?
                fsi_reg_read(fsi, DOFF_ST) :
                fsi_reg_read(fsi, DIFF_ST);
        ...
}

Will an in-flight IRQ therefore access disabled hardware registers during
the PIO transfer phase, bypassing the intended mitigations?

[Severity: Critical]
This is a pre-existing issue, but does a race condition in PIO transfers
cause a NULL pointer dereference because fsi_stream_is_working() releases
the lock before io->substream is accessed?

fsi_pio_transfer() calls fsi_stream_is_working() to ensure the stream is
active. fsi_stream_is_working() safely verifies io->substream under
master->lock but releases the lock immediately.

fsi_pio_transfer() then proceeds to call fsi_pio_get_area() locklessly,
which unconditionally dereferences io->substream->runtime:

fsi_pio_transfer() {
        if (!fsi_stream_is_working(fsi, io))
                return -EINVAL;

        buf = fsi_pio_get_area(fsi, io);
        ...
}

fsi_pio_get_area() {
        struct snd_pcm_runtime *runtime = io->substream->runtime;
        ...
}

If an ALSA SNDRV_PCM_TRIGGER_STOP command executes fsi_stream_quit()
concurrently on another CPU, setting io->substream = NULL, will this
sequence interleave precisely to cause a NULL pointer dereference?

[Severity: Critical]
This is a pre-existing issue, but does the DMA transfer handler lack a
stream active check, leading to a NULL pointer dereference?

When an FSI port is configured with DMA for playback and PIO for capture,
they share the same hardware interrupt line and fsi_interrupt handler.
If the playback stream is stopped, its hardware FIFO remains empty,
continuously asserting the playback data request bit in the shared
int_st register.

The fsi_interrupt handler reads the raw int_st register without applying
software masks and unconditionally routes to fsi_stream_transfer():

fsi_interrupt() {
        ...
        if (int_st & AB_IO(1, AO_SHIFT))
                fsi_stream_transfer(&master->fsia.playback);
        ...
}

The DMA handler fsi_dma_transfer() is invoked without verifying if the
stream is actively working. It immediately calls fsi_get_dai(io->substream).
Since the playback stream is stopped, io->substream is NULL.

Does this result in an immediate NULL pointer dereference in
asoc_substream_to_rtd()?

>  	u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
>  	u32 istatus = fsi_reg_read(fsi, DIFF_ST);
>  
> @@ -681,6 +685,10 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
>  	u32 data = 0;
>  	struct fsi_master *master = fsi_get_master(fsi);
>  
> +	if (!fsi_stream_is_working(fsi, &fsi->playback) &&
> +	    !fsi_stream_is_working(fsi, &fsi->capture))
> +		return;
> +

[Severity: High]
Does this also introduce a Time-of-Check to Time-of-Use race condition?

The stream status is checked and the lock is dropped before clearing the
interrupt status locklessly via fsi_core_mask_set(). Could a concurrent
stream stop and clock shutdown occur between the check and the hardware
access, causing a regression?

>  	data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback));
>  	data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture));

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260609013107.5995-1-phucduc.bui@gmail.com?part=5

  reply	other threads:[~2026-06-09  1:59 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09  1:30 [PATCH v5 00/11] ASoC: renesas: fsi: Fix system hang by adding SPU clock phucduc.bui
2026-06-09  1:30 ` [PATCH v5 01/11] ASoC: dt-bindings: renesas,fsi: add support multiple clocks phucduc.bui
2026-06-09  1:41   ` sashiko-bot
2026-06-09  6:54   ` Krzysztof Kozlowski
2026-06-09  8:11     ` Bui Duc Phuc
2026-06-09  8:17       ` Krzysztof Kozlowski
2026-06-09  8:42         ` Bui Duc Phuc
2026-06-09  8:54           ` Krzysztof Kozlowski
2026-06-09  9:05             ` Bui Duc Phuc
2026-06-09  1:30 ` [PATCH v5 02/11] ARM: dts: renesas: r8a7740: Add clocks for FSI phucduc.bui
2026-06-09  1:30 ` [PATCH v5 03/11] ASoC: renesas: fsi: Fix trigger stop ordering phucduc.bui
2026-06-09  1:43   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 04/11] ASoC: renesas: fsi: Move fsi_stream_is_working() phucduc.bui
2026-06-09  1:44   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 05/11] ASoC: renesas: fsi: Fix register access from in-flight IRQ after shutdown phucduc.bui
2026-06-09  1:59   ` sashiko-bot [this message]
2026-06-09  1:31 ` [PATCH v5 06/11] ASoC: renesas: fsi: Move fsi_clk_init() phucduc.bui
2026-06-09  1:46   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 07/11] ASoC: renesas: fsi: Use devm_clk_get_optional() for optional clocks phucduc.bui
2026-06-09  1:31 ` [PATCH v5 08/11] ASoC: renesas: fsi: refactor clock initialization phucduc.bui
2026-06-09  1:43   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 09/11] ASoC: renesas: fsi: Add SPU clock support phucduc.bui
2026-06-09  1:47   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 10/11] ASoC: renesas: fsi: add fsi_clk_prepare/unprepare() phucduc.bui
2026-06-09  1:51   ` sashiko-bot
2026-06-09  1:31 ` [PATCH v5 11/11] ASoC: renesas: fsi: Add SPU clock control in hw_startup/shutdown phucduc.bui
2026-06-09  1:50   ` sashiko-bot
2026-06-09  6:57 ` [PATCH v5 00/11] ASoC: renesas: fsi: Fix system hang by adding SPU clock Kuninori Morimoto
2026-06-09  9:49   ` Bui Duc Phuc

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=20260609015926.5112C1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=phucduc.bui@gmail.com \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=wsa+renesas@sang-engineering.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.