public inbox for linux-ide@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585
@ 2026-04-03  5:02 Arthur Husband
  0 siblings, 0 replies; 10+ messages in thread
From: Arthur Husband @ 2026-04-03  5:02 UTC (permalink / raw)
  To: linux-ide; +Cc: artmoty

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 },

--

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585
@ 2026-04-03  5:04 Arthur Husband
  2026-04-03  7:02 ` Damien Le Moal
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Arthur Husband @ 2026-04-03  5:04 UTC (permalink / raw)
  To: linux-ide; +Cc: dlemoal, cassel, artmoty

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 },

--

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585
  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
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Damien Le Moal @ 2026-04-03  7:02 UTC (permalink / raw)
  To: Arthur Husband, linux-ide; +Cc: cassel

On 4/3/26 14:04, Arthur Husband wrote:
> 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).

We do not do advertisement for commercial software. So please drop this.

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

Please move this entry down in the chipset specific section of the enum.

Other than this, looks OK to me. Thanks for the detailed commit message.

>  	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 },
> 
> --


-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585
  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
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Niklas Cassel @ 2026-04-03  8:12 UTC (permalink / raw)
  To: Arthur Husband; +Cc: linux-ide, dlemoal

On Thu, Apr 02, 2026 at 10:04:18PM -0700, Arthur Husband wrote:
> 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.

This does not make sense to me (probably because it is AI generated).

What is a platform here? Rasperry Pi is a SBC, TrueNAS is a Linux distro
based on Debian.

I would just drop this whole paragraph.


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

Please use the normal kernel style to reference commits, i.e.:
"commit '12 character SHA1' (description)"

git --no-pager show -s --abbrev-commit --abbrev=12 --pretty=format:"%h (\"%s\")%n"

Also, the SHA1 you are referencing does not exist in mainline.

Most likely you are thinking of:
commit 20730e9b2778 ("ahci: add 43-bit DMA address quirk for ASMedia
ASM1061 controllers")

However, this commit uses flag AHCI_HFLAG_43BIT_ONLY
(and not AHCI_HFLAG_32BIT_ONLY as claimed by AI).


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

We don't usually mention out of tree filesystems (ZFS) in our commit logs.


Thank you for the patch!


Kind regards,
Niklas

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585
  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
  2026-04-03 19:17 ` [PATCH v2] ata: " Arthur Husband
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Niklas Cassel @ 2026-04-03  8:19 UTC (permalink / raw)
  To: Arthur Husband; +Cc: linux-ide, dlemoal

Hello Arthur,

Please also prefix your subject with "ata: "
(I know that we have not always been consistent with this historically.)

i.e.
ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585


Kind regards,
Niklas

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585
  2026-04-03  5:04 [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585 Arthur Husband
                   ` (2 preceding siblings ...)
  2026-04-03  8:19 ` Niklas Cassel
@ 2026-04-03 19:17 ` Arthur Husband
  2026-04-05  6:38   ` Damien Le Moal
  2026-04-03 22:53 ` Arthur Husband
  2026-04-06 20:11 ` [PATCH v3] " Arthur Husband
  5 siblings, 1 reply; 10+ messages in thread
From: Arthur Husband @ 2026-04-03 19:17 UTC (permalink / raw)
  To: linux-ide; +Cc: dlemoal, cassel, artmoty

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.

The failure pattern is similar to the ASMedia ASM1061 (commit
2073d0e9b2778 ("ahci: add 43-bit DMA address quirk for ASMedia ASM1061
controllers")), which also falsely advertised full 64-bit DMA support.
However, the JMB585 requires a stricter 32-bit DMA mask rather than
43-bit, as corruption occurs with any address above 4GB.

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.

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 IDs for specific chipsets in alphabetical order */
 	board_ahci_al,
 	board_ahci_avn,
+	board_ahci_jmb585,
 	board_ahci_mcp65,
 	board_ahci_mcp77,
 	board_ahci_mcp89,
@@ -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 },

--

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2] ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585
  2026-04-03  5:04 [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585 Arthur Husband
                   ` (3 preceding siblings ...)
  2026-04-03 19:17 ` [PATCH v2] ata: " Arthur Husband
@ 2026-04-03 22:53 ` Arthur Husband
  2026-04-06  7:30   ` Niklas Cassel
  2026-04-06 20:11 ` [PATCH v3] " Arthur Husband
  5 siblings, 1 reply; 10+ messages in thread
From: Arthur Husband @ 2026-04-03 22:53 UTC (permalink / raw)
  To: linux-ide; +Cc: dlemoal, cassel, artmoty

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.

The failure pattern is similar to the ASMedia ASM1061 (commit
2073d0e9b2778 ("ahci: add 43-bit DMA address quirk for ASMedia ASM1061
controllers")), which also falsely advertised full 64-bit DMA support.
However, the JMB585 requires a stricter 32-bit DMA mask rather than
43-bit, as corruption occurs with any address above 4GB.

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.

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 IDs for specific chipsets in alphabetical order */
 	board_ahci_al,
 	board_ahci_avn,
+	board_ahci_jmb585,
 	board_ahci_mcp65,
 	board_ahci_mcp77,
 	board_ahci_mcp89,
@@ -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 },

--

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585
  2026-04-03 19:17 ` [PATCH v2] ata: " Arthur Husband
@ 2026-04-05  6:38   ` Damien Le Moal
  0 siblings, 0 replies; 10+ messages in thread
From: Damien Le Moal @ 2026-04-05  6:38 UTC (permalink / raw)
  To: Arthur Husband, linux-ide; +Cc: cassel

On 2026/04/03 21:17, Arthur Husband wrote:
> 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.
> 
> The failure pattern is similar to the ASMedia ASM1061 (commit
> 2073d0e9b2778 ("ahci: add 43-bit DMA address quirk for ASMedia ASM1061
> controllers")), which also falsely advertised full 64-bit DMA support.
> However, the JMB585 requires a stricter 32-bit DMA mask rather than
> 43-bit, as corruption occurs with any address above 4GB.
> 
> 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.
> 
> Signed-off-by: Arthur Husband <artmoty@gmail.com>

Looks OK to me.

Reviewed-by: Damien Le Moal <dlemoal@kernel.org>

-- 
Damien Le Moal
Western Digital Research

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585
  2026-04-03 22:53 ` Arthur Husband
@ 2026-04-06  7:30   ` Niklas Cassel
  0 siblings, 0 replies; 10+ messages in thread
From: Niklas Cassel @ 2026-04-06  7:30 UTC (permalink / raw)
  To: Arthur Husband; +Cc: linux-ide, dlemoal

Hello Arthur,

On Fri, Apr 03, 2026 at 03:53:14PM -0700, Arthur Husband wrote:
> 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.
> 
> The failure pattern is similar to the ASMedia ASM1061 (commit
> 2073d0e9b2778 ("ahci: add 43-bit DMA address quirk for ASMedia ASM1061
> controllers")), which also falsely advertised full 64-bit DMA support.
> However, the JMB585 requires a stricter 32-bit DMA mask rather than
> 43-bit, as corruption occurs with any address above 4GB.
> 
> 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.
> 
> Signed-off-by: Arthur Husband <artmoty@gmail.com>
> ---

You have sent two different V2 patches, however both of them fail to apply:

error: patch fragment without header at line 18: @@ -115,6 +116,14 @@ static const struct ata_port_info ahci_port_info[] = {
error: could not build fake ancestor
Patch failed at 0001 ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585


>  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

I think the problem is that you have index XXXXXXX..XXXXXXX.

The XXXXXXX should be pre- and post-image blob object SHA1s, e.g.:
index ad798e5246b49..3b65df914ebbe 100644

Please use git-format-patch to generate your patch and send a V3.


Kind regards,
Niklas

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3] ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585
  2026-04-03  5:04 [PATCH] ahci: force 32-bit DMA for JMicron JMB582/JMB585 Arthur Husband
                   ` (4 preceding siblings ...)
  2026-04-03 22:53 ` Arthur Husband
@ 2026-04-06 20:11 ` Arthur Husband
  5 siblings, 0 replies; 10+ messages in thread
From: Arthur Husband @ 2026-04-06 20:11 UTC (permalink / raw)
  To: linux-ide; +Cc: dlemoal, cassel, artmoty

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.

The failure pattern is similar to the ASMedia ASM1061 (commit
2073d0e9b2778 ("ahci: add 43-bit DMA address quirk for ASMedia ASM1061
controllers")), which also falsely advertised full 64-bit DMA support.
However, the JMB585 requires a stricter 32-bit DMA mask rather than
43-bit, as corruption occurs with any address above 4GB.

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.

Signed-off-by: Arthur Husband <artmoty@gmail.com>
---
 drivers/ata/ahci.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 931d008..1d73a53 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -68,6 +68,7 @@ enum board_ids {
 	/* board IDs for specific chipsets in alphabetical order */
 	board_ahci_al,
 	board_ahci_avn,
+	board_ahci_jmb585,
 	board_ahci_mcp65,
 	board_ahci_mcp77,
 	board_ahci_mcp89,
@@ -212,6 +213,15 @@ static const struct ata_port_info ahci_port_info[] = {
 		.udma_mask	= ATA_UDMA6,
 		.port_ops	= &ahci_avn_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_mcp65] = {
 		AHCI_HFLAGS	(AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
 				 AHCI_HFLAG_YES_NCQ),
@@ -439,6 +449,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
 	/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */
 	{ PCI_VDEVICE(INTEL, 0x4b63), board_ahci_pcs_quirk }, /* Elkhart Lake AHCI */
 
+	/* 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 },
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-04-06 20:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2026-04-03 19:17 ` [PATCH v2] ata: " Arthur Husband
2026-04-05  6:38   ` Damien Le Moal
2026-04-03 22:53 ` Arthur Husband
2026-04-06  7:30   ` Niklas Cassel
2026-04-06 20:11 ` [PATCH v3] " Arthur Husband
  -- strict thread matches above, loose matches on Subject: below --
2026-04-03  5:02 [PATCH] " Arthur Husband

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox