[PATCH 4/6] nvme: Add a quirk for page aligned admin queue buffers

From: Sven Peter

Date: Thu Aug 06 2026 - 11:29:59 EST


Apple controllers seem to require any queue buffers on the admin queue
to be aligned to the NVMe controller page size. Weirdly, this constraint
does not apply to the i/o queue where any alignment is fine. This has
always been required on pre-M1 controllers and is required starting with
macOS 15 firmware or post-M4 controllers again. On M1/M2/M3 we only got
away with this because there was a chicken bit to disable this
requirement. Let's add a quirk that enforces this alignment.

Signed-off-by: Sven Peter <sven@xxxxxxxxxx>
---
drivers/nvme/host/core.c | 5 ++++-
drivers/nvme/host/nvme.h | 7 +++++++
2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 453c1f0b2dd0..b76f4e4d8850 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2071,7 +2071,10 @@ static void nvme_set_ctrl_limits(struct nvme_ctrl *ctrl,
lim->max_integrity_segments = ctrl->max_integrity_segments;
lim->virt_boundary_mask = ctrl->ops->get_virt_boundary(ctrl, is_admin);
lim->max_segment_size = UINT_MAX;
- lim->dma_alignment = 3;
+ if (is_admin && (ctrl->quirks & NVME_QUIRK_ADMIN_PAGE_ALIGN))
+ lim->dma_alignment = NVME_CTRL_PAGE_SIZE - 1;
+ else
+ lim->dma_alignment = 3;
}

static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id,
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 824651cc898d..957ded0c6f53 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -178,6 +178,11 @@ enum nvme_quirks {
* Align dma pool segment size to 512 bytes
*/
NVME_QUIRK_DMAPOOL_ALIGN_512 = (1 << 22),
+
+ /*
+ * Admin queue DMA buffers must be page aligned
+ */
+ NVME_QUIRK_ADMIN_PAGE_ALIGN = (1 << 23),
};

static inline char *nvme_quirk_name(enum nvme_quirks q)
@@ -229,6 +234,8 @@ static inline char *nvme_quirk_name(enum nvme_quirks q)
return "broken_msi";
case NVME_QUIRK_DMAPOOL_ALIGN_512:
return "dmapool_align_512";
+ case NVME_QUIRK_ADMIN_PAGE_ALIGN:
+ return "admin_page_align";
}

return "unknown";

--
2.55.0