diff options
| author | Sven Peter <sven@kernel.org> | 2026-08-06 17:27:36 +0200 |
|---|---|---|
| committer | Keith Busch <kbusch@kernel.org> | 2026-08-11 08:53:27 -0700 |
| commit | 69d22a6b2f6984200d92dac689f8b00cc3d7d736 (patch) | |
| tree | a92f7f50363404962be7d505ddb7132e0014aee8 /drivers/nvme/host | |
| parent | cc0fec9b42cfbc69d70cb4c4b616408a7037b445 (diff) | |
| download | linux-next-69d22a6b2f6984200d92dac689f8b00cc3d7d736.tar.gz linux-next-69d22a6b2f6984200d92dac689f8b00cc3d7d736.zip | |
nvme: Add a quirk for page aligned admin queue buffers
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.
Tested-by: Joshua Peisach <jpeisach@ubuntu.com>
Tested-by: Janne Grunau <j@jannau.net>
Tested-by: Nick Chan <towinchenmi@gmail.com>
Signed-off-by: Sven Peter <sven@kernel.org>
Diffstat (limited to 'drivers/nvme/host')
| -rw-r--r-- | drivers/nvme/host/core.c | 5 | ||||
| -rw-r--r-- | drivers/nvme/host/nvme.h | 7 |
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a59abd770aff..1322c678f4eb 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2089,7 +2089,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 862464301d01..28cec87e4427 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"; |
