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>
This commit is contained in:
Klaus Jensen 2025-04-08 12:20:46 +02:00 committed by Philippe Mathieu-Daudé
parent f978f410aa
commit 8c996e3271
4 changed files with 14 additions and 9 deletions

View File

@ -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;

View File

@ -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[] = {

View File

@ -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;

View File

@ -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;
}