aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Jensen <k.jensen@samsung.com>2025-04-08 12:20:46 +0200
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2025-04-08 20:46:10 +0200
commit8c996e32712820d6d1e62ba6436424d0ba837d96 (patch)
treee2133cc3dcd1f6617e26c08b06ffc895851a0c5c
parentf978f410aa4f4b5ce9a4c18c815507bcbfb75b9d (diff)
downloadqemu-8c996e32712820d6d1e62ba6436424d0ba837d96.zip
qemu-8c996e32712820d6d1e62ba6436424d0ba837d96.tar.gz
qemu-8c996e32712820d6d1e62ba6436424d0ba837d96.tar.bz2
hw/nvme: fix attachment of private namespaces
Fix regression when attaching private namespaces that gets attached to the wrong controller. Keep track of the original controller "owner" of private namespaces, and only attach if this matches on controller enablement. Fixes: 6ccca4b6bb9f ("hw/nvme: rework csi handling") Reported-by: Alan Adamson <alan.adamson@oracle.com> Suggested-by: Alan Adamson <alan.adamson@oracle.com> Signed-off-by: Klaus Jensen <k.jensen@samsung.com> Tested-by: Alan Adamson <alan.adamson@oracle.com> Reviewed-by: Alan Adamson <alan.adamson@oracle.com> Reviewed-by: Keith Busch <kbusch@kernel.org> Message-ID: <20250408-fix-private-ns-v1-1-28e169b6b60b@samsung.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
-rw-r--r--hw/nvme/ctrl.c7
-rw-r--r--hw/nvme/ns.c4
-rw-r--r--hw/nvme/nvme.h3
-rw-r--r--hw/nvme/subsys.c9
4 files changed, 14 insertions, 9 deletions
diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 518d02d..d6b77d4 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -7755,7 +7755,11 @@ static int nvme_start_ctrl(NvmeCtrl *n)
for (int i = 1; i <= NVME_MAX_NAMESPACES; i++) {
NvmeNamespace *ns = nvme_subsys_ns(n->subsys, i);
- if (ns && nvme_csi_supported(n, ns->csi) && !ns->params.detached) {
+ if (!ns || (!ns->params.shared && ns->ctrl != n)) {
+ continue;
+ }
+
+ if (nvme_csi_supported(n, ns->csi) && !ns->params.detached) {
if (!ns->attached || ns->params.shared) {
nvme_attach_ns(n, ns);
}
@@ -8988,6 +8992,7 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
if (n->namespace.blkconf.blk) {
ns = &n->namespace;
ns->params.nsid = 1;
+ ns->ctrl = n;
if (nvme_ns_setup(ns, errp)) {
return;
diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c
index 98c1e75..4ab8ba7 100644
--- a/hw/nvme/ns.c
+++ b/hw/nvme/ns.c
@@ -763,6 +763,10 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
ns->id_ns.endgid = cpu_to_le16(0x1);
ns->id_ns_ind.endgrpid = cpu_to_le16(0x1);
+
+ if (!ns->params.shared) {
+ ns->ctrl = n;
+ }
}
static const Property nvme_ns_props[] = {
diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
index 6f782ba..b5c9378 100644
--- a/hw/nvme/nvme.h
+++ b/hw/nvme/nvme.h
@@ -268,6 +268,9 @@ typedef struct NvmeNamespace {
NvmeSubsystem *subsys;
NvmeEnduranceGroup *endgrp;
+ /* NULL for shared namespaces; set to specific controller if private */
+ NvmeCtrl *ctrl;
+
struct {
uint32_t err_rec;
} features;
diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c
index 2ae56f1..b617ac3 100644
--- a/hw/nvme/subsys.c
+++ b/hw/nvme/subsys.c
@@ -56,7 +56,7 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp)
{
NvmeSubsystem *subsys = n->subsys;
NvmeSecCtrlEntry *sctrl = nvme_sctrl(n);
- int cntlid, nsid, num_rsvd, num_vfs = n->params.sriov_max_vfs;
+ int cntlid, num_rsvd, num_vfs = n->params.sriov_max_vfs;
if (pci_is_vf(&n->parent_obj)) {
cntlid = le16_to_cpu(sctrl->scid);
@@ -92,13 +92,6 @@ int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp)
subsys->ctrls[cntlid] = n;
- for (nsid = 1; nsid < ARRAY_SIZE(subsys->namespaces); nsid++) {
- NvmeNamespace *ns = subsys->namespaces[nsid];
- if (ns && ns->params.shared && !ns->params.detached) {
- nvme_attach_ns(n, ns);
- }
- }
-
return cntlid;
}