Skip to content

nvme: Increase the NVMe controller register size to 0x4000 to match spec requirements for MLBAR.#126

Merged
luqmana merged 3 commits intomasterfrom
luqmana/nvme-up-bar-size
May 2, 2022
Merged

nvme: Increase the NVMe controller register size to 0x4000 to match spec requirements for MLBAR.#126
luqmana merged 3 commits intomasterfrom
luqmana/nvme-up-bar-size

Conversation

@luqmana
Copy link
Copy Markdown
Contributor

@luqmana luqmana commented May 2, 2022

The NVMe spec implies [1] a minimum size of 0x4000 for the controller register space. Windows thus expects BAR0 & !(0x4000 - 1) == BAR0 & !0xF to hold true. Which is all fine and well except Propolis sets the size to 0x2000 meaning we end up in this failing scenario where BAR0 = 0xFEDFE004 and so the above relation no longer holds true.

TL;DR: propolis set the NVMe controller register space to half the size it should at least be.

[1] Bits 13:04 should be set to 0.

See NVMe 1.0e Section 2.1.10 Offset 10h: MLBAR (BAR0) - Memory Register Base Address, lower 32 bits:

Bits Type Reset Description
31:14 RW 0h Base Address (BA): Base address of register memory space. For controllers that support a larger number of doorbell registers or have vendor specific space following the doorbell registers, more bits are allowed to be RO such that more memory space is consumed.
13:04 RO 0h Reserved

luqmana added 2 commits May 1, 2022 15:15
…pec requirements for MLBAR.

With that, we can boot successfully on Windows now with an NVMe boot
drive!
Copy link
Copy Markdown
Contributor

@pfmooney pfmooney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find

Comment thread propolis/src/hw/nvme/mod.rs Outdated
@luqmana luqmana merged commit 2129d16 into master May 2, 2022
@luqmana luqmana deleted the luqmana/nvme-up-bar-size branch May 2, 2022 19:57
spdk-bot pushed a commit to spdk/spdk that referenced this pull request Apr 16, 2026
Windows stornvme.sys masks the NVMe BAR0 value with 0xFFFFC000
inside NVMeHwFindAdapter, enforcing the NVMe 1.0e section 2.1.10
MLBAR requirement that bits 13:04 be reserved. This effectively
requires BAR0 to be at least 16 KB so that PCI places it on a
16 KB aligned boundary.

With the default NVMF_VFIO_USER_MAX_QPAIRS_PER_CTRLR (512), the
computed NVME_REG_BAR0_SIZE is 0x2000 (8 KB). PCI is free to
place the BAR on an 8 KB aligned address that the mask then
corrupts; NVMeHwFindAdapter returns SP_RETURN_BAD_CONFIG with
fault text "MLBAR/MUBAR is not valid", surfacing as Windows
Code 10 (STATUS_DEVICE_CONFIGURATION_ERROR) on hot-add or STOP
0x7B INACCESSIBLE_BOOT_DEVICE on the boot disk.

Add a 16 KB floor to NVME_REG_BAR0_SIZE. For higher MAX_QPAIRS
the natural computed size is used unchanged.

Propolis (Oxide) fixed the identical bug with the same approach
in 2022: oxidecomputer/propolis#126

Tested on Windows Server 2025 with Cloud Hypervisor main and
upstream QEMU 10.2.

Fixes #2576
Change-Id: Ie916cb3dd3bf0157acd89b08ce54bda3d45dce9d
Signed-off-by: Max Makarov <maxpain@linux.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/28341
Reviewed-by: John Levon <levon@movementarian.org>
Tested-by: SPDK Automated Test System <spdkbot@gmail.com>
Reviewed-by: Tomasz Zawadzki <tomasz@tzawadzki.com>
Reviewed-by: Changpeng Liu <changpeliu@tencent.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants