[PATCH 1/3] hw/nvme: fix assertion failure on sr-iov capable nvme controller removal
Daniel Paziyski <[email protected]> Wed, 5 Aug 2026 14:45:16 +0200
| Newsgroups | gmane.comp.emulators.qemu,gmane.comp.emulators.qemu.stable,gmane.comp.emulators.qemu.block |
|---|---|
| Message-ID | <[email protected]> |
In a nvme subsystem, the ctrls array maps controller IDs to nvme controllers.
The value of the array elements can either be NULL (no controller present for
this ID), SUBSYS_SLOT_RSVD, or any other value, representing a pointer to the
nvme controller structure.
The SUBSYS_SLOT_RSVD value is special: when a nvme controller physical function
is being created and is reserving the controller IDs for its virtual functions,
it indicates that the slot is soon going to be filled by its corresponding
virtual function when it is realized, and on virtual function removal, it means
that its controller has been removed.
When the physical function is being removed, it goes through its list of
secondary controllers (virtual functions), ensures that their slots have the
SUBSYS_SLOT_RSVD values, and then frees up the controller IDs by setting the
NULL value. This traversal occurs before the virtual functions are destroyed,
causing an assertion failure because the slots contain as values the pointers to
the secondary controllers.
Destroy the virtual functions (and therefore, the secondary controllers) after
they are offlined in the nvme_ctrl_reset call of the physical function, but
before releasing the controller IDs of the secondary controllers in
nvme_subsys_unregister_ctrl.
QEMU command line (boot with a hotunplug-aware OS, such as Linux):
qemu-system-x86_64 -M q35 -device pcie-root-port,id=rp -monitor stdio \
-device nvme-subsys,id=subsys0 \
-device nvme,subsys=subsys0,serial=ctrl0,sriov_max_vfs=1,\
sriov_vq_flexible=2,sriov_vi_flexible=1,max_ioqpairs=4,msix_qsize=2,bus=rp,id=ctrl0
In the QEMU monitor:
device_del ctrl0
Message in stderr:
qemu-system-x86_64: ../hw/nvme/subsys.c:49: nvme_subsys_unreserve_cntlids: Assertion `subsys->ctrls[cntlid] == SUBSYS_SLOT_RSVD' failed.
Cc: [email protected]
Fixes: 44c2c09488db ("hw/nvme: Add support for SR-IOV")
Signed-off-by: Daniel Paziyski <[email protected]>
---
hw/nvme/ctrl.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index bd6ad64b20..b726c13a56 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -9676,6 +9676,10 @@ static void nvme_exit(PCIDevice *pci_dev)
}
}
+ if (!pci_is_vf(pci_dev) && n->params.sriov_max_vfs) {
+ pcie_sriov_pf_exit(pci_dev);
+ }
+
nvme_subsys_unregister_ctrl(n->subsys, n);
g_free(n->cq);
@@ -9700,10 +9704,6 @@ static void nvme_exit(PCIDevice *pci_dev)
host_memory_backend_set_mapped(n->pmr.dev, false);
}
- if (!pci_is_vf(pci_dev) && n->params.sriov_max_vfs) {
- pcie_sriov_pf_exit(pci_dev);
- }
-
if (n->params.msix_exclusive_bar && !pci_is_vf(pci_dev)) {
msix_uninit_exclusive_bar(pci_dev);
} else {
--
2.55.0