From 8c996e32712820d6d1e62ba6436424d0ba837d96 Mon Sep 17 00:00:00 2001 From: Klaus Jensen Date: Tue, 8 Apr 2025 12:20:46 +0200 Subject: [PATCH] hw/nvme: fix attachment of private namespaces MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Suggested-by: Alan Adamson Signed-off-by: Klaus Jensen Tested-by: Alan Adamson Reviewed-by: Alan Adamson Reviewed-by: Keith Busch Message-ID: <20250408-fix-private-ns-v1-1-28e169b6b60b@samsung.com> Signed-off-by: Philippe Mathieu-Daudé --- hw/nvme/ctrl.c | 7 ++++++- hw/nvme/ns.c | 4 ++++ hw/nvme/nvme.h | 3 +++ hw/nvme/subsys.c | 9 +-------- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index 518d02dc667..d6b77d4fbc9 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 98c1e75a5d2..4ab8ba74f51 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 6f782ba1882..b5c9378ea4e 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 2ae56f12a59..b617ac3892a 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; } -- 2.39.5