Skip to content

Commit 1b1031c

Browse files
author
Christoph Hellwig
committed
nvme: validate cntlid during controller initialisation
The CNTLID value is required to be unique, and we do rely on this for correct operation. So reject any controller for which a non-unique CNTLID has been detected. Based on a patch from Hannes Reinecke. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Chaitanya Kulkarni <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]>
1 parent 32fd90c commit 1b1031c

File tree

1 file changed

+24
-17
lines changed

1 file changed

+24
-17
lines changed

drivers/nvme/host/core.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2341,20 +2341,35 @@ static const struct attribute_group *nvme_subsys_attrs_groups[] = {
23412341
NULL,
23422342
};
23432343

2344-
static int nvme_active_ctrls(struct nvme_subsystem *subsys)
2344+
static bool nvme_validate_cntlid(struct nvme_subsystem *subsys,
2345+
struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
23452346
{
2346-
int count = 0;
2347-
struct nvme_ctrl *ctrl;
2347+
struct nvme_ctrl *tmp;
23482348

23492349
lockdep_assert_held(&nvme_subsystems_lock);
23502350

2351-
list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) {
2352-
if (ctrl->state != NVME_CTRL_DELETING &&
2353-
ctrl->state != NVME_CTRL_DEAD)
2354-
count++;
2351+
list_for_each_entry(tmp, &subsys->ctrls, subsys_entry) {
2352+
if (ctrl->state == NVME_CTRL_DELETING ||
2353+
ctrl->state == NVME_CTRL_DEAD)
2354+
continue;
2355+
2356+
if (tmp->cntlid == ctrl->cntlid) {
2357+
dev_err(ctrl->device,
2358+
"Duplicate cntlid %u with %s, rejecting\n",
2359+
ctrl->cntlid, dev_name(tmp->device));
2360+
return false;
2361+
}
2362+
2363+
if ((id->cmic & (1 << 1)) ||
2364+
(ctrl->opts && ctrl->opts->discovery_nqn))
2365+
continue;
2366+
2367+
dev_err(ctrl->device,
2368+
"Subsystem does not support multiple controllers\n");
2369+
return false;
23552370
}
23562371

2357-
return count;
2372+
return true;
23582373
}
23592374

23602375
static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
@@ -2397,15 +2412,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
23972412
__nvme_release_subsystem(subsys);
23982413
subsys = found;
23992414

2400-
/*
2401-
* Verify that the subsystem actually supports multiple
2402-
* controllers, else bail out.
2403-
*/
2404-
if (!(ctrl->opts && ctrl->opts->discovery_nqn) &&
2405-
nvme_active_ctrls(found) && !(id->cmic & (1 << 1))) {
2406-
dev_err(ctrl->device,
2407-
"ignoring ctrl due to duplicate subnqn (%s).\n",
2408-
subsys->subnqn);
2415+
if (!nvme_validate_cntlid(subsys, ctrl, id)) {
24092416
ret = -EINVAL;
24102417
goto out_put_subsystem;
24112418
}

0 commit comments

Comments
 (0)