From: Arthur Husband <artmoty@gmail.com>
To: linux-ide@vger.kernel.org
Cc: artmoty@gmail.com
Subject: [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585
Date: Thu, 2 Apr 2026 22:02:22 -0700 [thread overview]
Message-ID: <20260403050225.50186-1-artmoty@gmail.com> (raw)
The JMicron JMB585 (and JMB582) SATA controllers advertise 64-bit DMA
support via the S64A bit in the AHCI CAP register, but their 64-bit DMA
implementation is defective. Under sustained I/O, DMA transfers targeting
addresses above 4GB silently corrupt data — writes land at incorrect
memory addresses with no errors logged.
This has been confirmed on multiple platforms (Minisforum N5 Pro,
Raspberry Pi, Unraid, Proxmox, TrueNAS) and is consistent with the
controller truncating or mishandling upper address bits during 64-bit
DMA transactions.
The failure pattern is identical to the ASMedia ASM1062 (commit
edb96a15dc18), which also falsely advertised 64-bit DMA and was fixed
with AHCI_HFLAG_32BIT_ONLY.
On the Minisforum N5 Pro specifically, the combination of the JMB585's
broken 64-bit DMA with the AMD Family 1Ah (Strix Point) IOMMU causes
silent data corruption that is only detectable via checksumming
filesystems (BTRFS/ZFS scrub). The corruption occurs when 32-bit IOVA
space is exhausted and the kernel transparently switches to 64-bit DMA
addresses.
Add device-specific PCI ID entries for the JMB582 (0x0582) and JMB585
(0x0585) before the generic JMicron class match, using a new board type
that combines AHCI_HFLAG_IGN_IRQ_IF_ERR (preserving existing behavior)
with AHCI_HFLAG_32BIT_ONLY to force 32-bit DMA masks.
Investigation and patch development assisted by Claude (Anthropic AI).
Signed-off-by: Arthur Husband <artmoty@gmail.com>
---
drivers/ata/ahci.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index XXXXXXX..XXXXXXX 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -51,6 +51,7 @@ enum board_ids {
board_ahci,
board_ahci_43bit_dma,
board_ahci_ign_iferr,
+ board_ahci_jmb585,
board_ahci_no_debounce_delay,
board_ahci_no_msi,
/*
@@ -115,6 +116,14 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
},
+ /* JMicron JMB582/585: 64-bit DMA is broken, force 32-bit */
+ [board_ahci_jmb585] = {
+ AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR |
+ AHCI_HFLAG_32BIT_ONLY),
+ .flags = AHCI_FLAG_COMMON,
+ .pio_mask = ATA_PIO4,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &ahci_ops,
+ },
[board_ahci_no_debounce_delay] = {
.flags = AHCI_FLAG_COMMON,
.link_flags = ATA_LFLAG_NO_DEBOUNCE_DELAY,
@@ -XXX,7 +XXX,12 @@ static const struct pci_device_id ahci_pci_tbl[] = {
...
- /* JMicron 360/1/3/5/6, match class to avoid IDE function */
+ /* JMicron JMB582/585: force 32-bit DMA (broken 64-bit implementation) */
+ { PCI_VDEVICE(JMICRON, 0x0582), board_ahci_jmb585 },
+ { PCI_VDEVICE(JMICRON, 0x0585), board_ahci_jmb585 },
+
+ /* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
--
next reply other threads:[~2026-04-03 5:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-03 5:02 Arthur Husband [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-04-03 5:04 [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585 Arthur Husband
2026-04-03 7:02 ` Damien Le Moal
2026-04-03 8:12 ` Niklas Cassel
2026-04-03 8:19 ` Niklas Cassel
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=20260403050225.50186-1-artmoty@gmail.com \
--to=artmoty@gmail.com \
--cc=linux-ide@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