All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Kaitao Cheng" <kaitao.cheng@linux.dev>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v2 10/14] spi: tegra210-quad: Open-code message transfer walk
Date: Tue, 09 Jun 2026 06:57:22 +0000	[thread overview]
Message-ID: <20260609065722.EAD4B1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260609063855.95710-1-kaitao.cheng@linux.dev>

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

Pre-existing issues:
- [High] Hardware Chip Select (CS) is left asserted indefinitely if the final message transfer is absorbed as a dummy transfer.
- [High] DMA memory mapping leak on error paths in `tegra_qspi_start_dma_based_transfer`.
- [High] DMA memory mapping leak upon transfer timeout or hardware error.
- [High] DMA maps memory beyond the end of the SPI transfer buffer when using packed DMA transfers.
- [High] Unconditional DMA unmap on error path in `tegra_qspi_dma_map_xfer`.
--

commit dedc4ce6598360fa2a4de3d4413aaecfda3051a4
Author: Kaitao Cheng <chengkaitao@kylinos.cn>

spi: tegra210-quad: Open-code message transfer walk

This commit converts the list_for_each_entry() loop in
tegra_qspi_non_combined_seq_xfer() to an open-coded for-loop. This
preserves semantics when consuming the next transfer in the loop body,
preparing the code for future list iterator updates.

> diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
> index 588a929a97850..102562893d227 100644
> --- a/drivers/spi/spi-tegra210-quad.c
> +++ b/drivers/spi/spi-tegra210-quad.c
> @@ -1309,7 +1309,9 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
>  	if (tqspi->soc_data->supports_tpm)
>  		val &= ~QSPI_TPM_WAIT_POLL_EN;
>  	tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG);
> -	list_for_each_entry(transfer, &msg->transfers, transfer_list) {
> +	for (transfer = list_first_entry(&msg->transfers, typeof(*transfer), transfer_list);
> +	     !list_entry_is_head(transfer, &msg->transfers, transfer_list);
> +	     transfer = list_next_entry(transfer, transfer_list)) {
>  		struct spi_transfer *xfer = transfer;
>  		u8 dummy_bytes = 0;
>  		u32 cmd1;

[Severity: High]
This is a pre-existing issue, but does this logic fail to deactivate the
chip select if the final transfer is absorbed as a dummy transfer?

In tegra_qspi_non_combined_seq_xfer(), if the final SPI transfer in the
message is a dummy transfer, the loop pointer advances to it, effectively
consuming it into the current xfer:

    if (next_xfer->dummy_data) {
        ...
        transfer = next_xfer;
    }

When checking if CS should be deactivated at the end of the loop body,
the code uses xfer instead of the updated transfer pointer:

    if (list_is_last(&xfer->transfer_list, &msg->transfers)) {
        if (!xfer->cs_change) {
            tegra_qspi_transfer_end(spi);
            ...
        }
    } else if (xfer->cs_change) {
        ...

Since xfer is the second-to-last transfer, list_is_last() evaluates to
false. The code falls through to the else branch, and if cs_change is
false, tegra_qspi_transfer_end() is skipped.

The loop then terminates, leaving the hardware chip select asserted
indefinitely. Could this corrupt subsequent bus communications?

[Severity: High]
This is a pre-existing issue, but do we leak DMA memory mappings if a
transfer times out or encounters a hardware error?

Looking at tegra_qspi_non_combined_seq_xfer(), if the transfer times out,
tegra_qspi_handle_timeout() confirms the timeout, stops the DMA engine
channels, and jumps to complete_xfer:

    if (tqspi->is_curr_dma_xfer)
        tegra_qspi_dma_stop(tqspi);
    ...
    goto complete_xfer;

Similarly, if a hardware error is detected, we also jump to complete_xfer:

    if (tqspi->tx_status || tqspi->rx_status) {
        ...
        goto complete_xfer;
    }

In both paths, the code exits without calling tegra_qspi_dma_unmap_xfer().
Are these DMA mappings permanently leaked?

[Severity: High]
This isn't a bug introduced by this patch, but does
tegra_qspi_start_dma_based_transfer() leak DMA memory mappings on its
error paths?

When tqspi->is_packed is true, tegra_qspi_dma_map_xfer() successfully
maps the TX and RX DMA buffers.

If any subsequent DMA setup operations fail (like dmaengine_slave_config(),
tegra_qspi_start_tx_dma(), or tegra_qspi_start_rx_dma()), the function
returns the error directly:

    ret = dmaengine_slave_config(tqspi->rx_dma_chan, &dma_sconfig);
    if (ret < 0) {
        dev_err(tqspi->dev, "failed DMA slave config: %d\n", ret);
        return ret;
    }

The caller tegra_qspi_non_combined_seq_xfer() then propagates the error
and exits, never calling tegra_qspi_dma_unmap_xfer().

Does this permanently leak the DMA mapped memory and IOMMU space?

[Severity: High]
This is a pre-existing issue, but does the DMA mapping calculation risk
crossing an unmapped physical page boundary?

In tegra_qspi_dma_map_xfer(), when tqspi->is_packed is true, the mapped
length is artificially inflated to a multiple of 4:

    len = DIV_ROUND_UP(tqspi->curr_dma_words * tqspi->bytes_per_word, 4) * 4;

    if (t->tx_buf) {
        t->tx_dma = dma_map_single(tqspi->tx_dma_dev, (void *)tx_buf,
                                   len, DMA_TO_DEVICE);

Because the original client-provided buffer might be exactly t->len bytes
long, mapping beyond its exact length could cross into restricted or
unallocated physical memory.

Could this trigger an IOMMU fault or a kernel panic?

[Severity: High]
This isn't a bug introduced by this patch, but does the error path in
tegra_qspi_dma_map_xfer() unconditionally unmap the TX buffer even when
it was never mapped?

If t->tx_buf is NULL during a read-only transfer, the TX buffer mapping
is correctly skipped.

However, if the subsequent dma_map_single() for t->rx_buf fails, the
error handling block unmaps tx_dma without checking:

    if (dma_mapping_error(tqspi->rx_dma_dev, t->rx_dma)) {
        dma_unmap_single(tqspi->tx_dma_dev, t->tx_dma, len, DMA_TO_DEVICE);
        return -ENOMEM;
    }

Since t->tx_buf was NULL, t->tx_dma was never mapped by this function.

Could unmapping it here violate the DMA API contract, potentially
unmapping page 0 from the IOMMU or corrupting DMA tracking state?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260609064122.95825-1-kaitao.cheng@linux.dev?part=10

  parent reply	other threads:[~2026-06-09  6:57 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-09  6:13 [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Kaitao Cheng
2026-06-09  6:13 ` [PATCH v2 01/14] drbd: Open-code transfer log list walk Kaitao Cheng
2026-06-09  6:53   ` sashiko-bot
2026-06-09  6:13 ` [PATCH v2 02/14] firewire: core: Open-code topology " Kaitao Cheng
2026-06-09  6:53   ` sashiko-bot
2026-06-09  6:25 ` [PATCH v2 03/14] drm/bridge: Open-code bridge chain list walks Kaitao Cheng
2026-06-09  6:25   ` [PATCH v2 04/14] drm/i915/gt: Open-code active timeline walk Kaitao Cheng
2026-06-09  7:00     ` Andy Shevchenko
2026-06-09  6:25   ` [PATCH v2 05/14] drm/i915: Open-code DFS dependency list walk Kaitao Cheng
2026-06-09  6:25   ` [PATCH v2 06/14] drm/ttm: Open-code reservation " Kaitao Cheng
2026-06-09  6:51     ` sashiko-bot
2026-06-09  6:25   ` [PATCH v2 07/14] spi: fsi: Open-code message transfer walk Kaitao Cheng
2026-06-09  7:02     ` Andy Shevchenko
2026-06-09  6:25   ` [PATCH v2 08/14] spi: stm32-ospi: " Kaitao Cheng
2026-06-09  6:57     ` sashiko-bot
2026-06-09  6:25   ` [PATCH v2 09/14] spi: stm32-qspi: " Kaitao Cheng
2026-06-09  6:55     ` sashiko-bot
2026-06-09  6:38 ` [PATCH v2 10/14] spi: tegra210-quad: " Kaitao Cheng
2026-06-09  6:38   ` [PATCH v2 11/14] locking/locktorture: Open-code ww mutex list walk Kaitao Cheng
2026-06-09  6:54     ` sashiko-bot
2026-06-09  6:38   ` [PATCH v2 12/14] locking/ww_mutex: Open-code stress reorder " Kaitao Cheng
2026-06-09  6:57   ` sashiko-bot [this message]
2026-06-09  6:41 ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk Kaitao Cheng
2026-06-09  6:41   ` [PATCH v2 14/14] list: Cache cursors in entry iterators Kaitao Cheng
2026-06-09  6:59     ` sashiko-bot
2026-06-09  6:55   ` [PATCH v2 13/14] ASoC: dapm: Open-code widget invalidation walk sashiko-bot
2026-06-09  6:47 ` [PATCH v2 00/14] list: Prepare entry iterators to cache cursor state Andy Shevchenko
2026-06-09  7:05   ` Andy Shevchenko
2026-06-09 10:33 ` Christian König

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=20260609065722.EAD4B1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kaitao.cheng@linux.dev \
    --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.