From: David Laight <david.laight.linux@gmail.com>
To: Alvin Lim <alvinwylim@gmail.com>
Cc: linux-ide@vger.kernel.org, Damien Le Moal <dlemoal@kernel.org>,
Niklas Cassel <cassel@kernel.org>,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] ata: ahci: force 32-bit DMA for ASMedia ASM1166
Date: Sun, 21 Jun 2026 13:48:09 +0100 [thread overview]
Message-ID: <20260621134809.7b1b2e3f@pumpkin> (raw)
In-Reply-To: <20260621100844.1224301-1-alvinwylim@gmail.com>
On Sun, 21 Jun 2026 18:08:44 +0800
Alvin Lim <alvinwylim@gmail.com> wrote:
> The ASMedia ASM1166 SATA controller (1b21:1166) advertises 64-bit DMA
> support (AHCI CAP.S64A), but on systems with the IOMMU enabled - where it
> can be handed DMA addresses above 4 GB - it silently corrupts data in
> transit.
That seems wrong.
If any iommu is disabled the sata cotroller will be passed the memory's
physical address which is very likely to be over 4G.
So the controller seems to support 64bit addresses - as advertised.
But with the iommu enabled the addresses the controller needs to use are
different from the physical address - so the controller will almost
certainly see sub 4G addresses for buffers above 4G.
(The iommu probably allocates 32bit PCIe addresses for all buffers so that
it doesn't have to worry about targets that only support 32bit addresses.)
It seems more likely that the wrong addresses are ending up in the host
side of the iommu and using bounce buffers fixes that.
Using the wrong addresses is likely to lead to major kernel memory
corruptions.
Mixing up physical addresses and dma addresses, assuming that memory
from dma_alloc_coherent() is physically contiguous, or just losing the
high bits of the physical address passed to the iommu seem more likely.
David
> Reads return different, wrong data on each access. SMART is clean,
> there are no SATA link resets and no MCE is raised, so the corruption is
> invisible until it surfaces as filesystem metadata errors (XFS EUCLEAN)
> or, on Ceph, mass scrub errors across multiple independent filesystems at
> once - i.e. host-level, not filesystem-level.
>
> This is the same failure mode already quirked for other controllers that
> falsely claim working 64-bit DMA. See commit 105c42566a55 ("ata: ahci:
> force 32-bit DMA for JMicron JMB582/JMB585") and commit 20730e9b2778
> ("ahci: add 43-bit DMA address quirk for ASMedia ASM1061 controllers").
> The ASM1166 currently maps to plain board_ahci with no DMA limit.
>
> Limit the ASM1166 to 32-bit DMA. 32-bit is the guaranteed-correct lower
> bound; the only cost is extra SWIOTLB bounce-buffering on transfers above
> 4 GB, negligible for storage. A future change can widen it to the
> controller's true addressable width if characterised. Until this lands the
> only workarounds are disabling the IOMMU (amd_iommu=off / intel_iommu=off)
> or using an HBA.
>
> Reproduced on an AOOSTAR WTR MAX (AMD Ryzen 7 PRO 8845HS) whose six SATA
> bays all hang off one ASM1166: with the IOMMU on, six concurrent
> 'dd ... | md5sum' of the same large file return six different sums; with
> amd_iommu=off they are identical, and a full Ceph deep-scrub of a 5.4 TiB
> / 1.43M-object pool re-reads end-to-end with zero scrub errors.
>
> Add a board_ahci_32bit_dma board type (mirroring board_ahci_43bit_dma)
> and point the ASM1166 entry at it.
>
> Fixes: 3bf614106094 ("ata: ahci: add identifiers for ASM2116 series adapters")
> Cc: stable@vger.kernel.org
> Assisted-by: Claude:claude-opus-4.8
> Signed-off-by: Alvin Lim <alvinwylim@gmail.com>
> ---
> drivers/ata/ahci.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
> index 58f512f8952a..895956c2ca15 100644
> --- a/drivers/ata/ahci.c
> +++ b/drivers/ata/ahci.c
> @@ -48,6 +48,7 @@ enum {
> enum board_ids {
> /* board IDs by feature in alphabetical order */
> board_ahci,
> + board_ahci_32bit_dma,
> board_ahci_43bit_dma,
> board_ahci_ign_iferr,
> board_ahci_no_debounce_delay,
> @@ -132,6 +133,13 @@ static const struct ata_port_info ahci_port_info[] = {
> .udma_mask = ATA_UDMA6,
> .port_ops = &ahci_ops,
> },
> + [board_ahci_32bit_dma] = {
> + AHCI_HFLAGS (AHCI_HFLAG_32BIT_ONLY),
> + .flags = AHCI_FLAG_COMMON,
> + .pio_mask = ATA_PIO4,
> + .udma_mask = ATA_UDMA6,
> + .port_ops = &ahci_ops,
> + },
> [board_ahci_43bit_dma] = {
> AHCI_HFLAGS (AHCI_HFLAG_43BIT_ONLY),
> .flags = AHCI_FLAG_COMMON,
> @@ -1559,7 +1567,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
> }, {
> /* ASM1166 */
> PCI_VDEVICE(ASMEDIA, 0x1166),
> - .driver_data = board_ahci,
> + .driver_data = board_ahci_32bit_dma,
> }, {
> /*
> * Samsung SSDs found on some macbooks. NCQ times out if MSI is
>
> base-commit: 322008f87f917e2217eeac386a9410945092eb2e
next prev parent reply other threads:[~2026-06-21 12:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-21 10:08 [PATCH] ata: ahci: force 32-bit DMA for ASMedia ASM1166 Alvin Lim
2026-06-21 12:48 ` David Laight [this message]
[not found] ` <CA+CYLR6Rg-3brg9yCMAKJDr7t=mtu4vP0+aMFs+JhLPWtQxOYA@mail.gmail.com>
2026-06-21 21:57 ` David Laight
2026-06-22 11:31 ` Damien Le Moal
2026-06-22 13:02 ` David Laight
2026-06-22 13:19 ` Niklas Cassel
2026-06-22 15:02 ` David Laight
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=20260621134809.7b1b2e3f@pumpkin \
--to=david.laight.linux@gmail.com \
--cc=alvinwylim@gmail.com \
--cc=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/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