Commit d4875622 authored by Keith Busch's avatar Keith Busch Committed by Jens Axboe

nvme/pci: Don't free queues on error

The nvme_remove function tears down all allocated resources in the correct
order, so no need to free queues on error during initialization. This
fixes possible use-after-free errors when queues are still associated
with a blk-mq hctx.
Reported-by: default avatarScott Bauer <scott.bauer@intel.com>
Tested-by: default avatarScott Bauer <scott.bauer@intel.com>
Signed-off-by: default avatarKeith Busch <keith.busch@intel.com>
Reviewed-by: default avatarSagi Grimberg <sagi@grimbeg.me>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 959401aa
...@@ -1242,20 +1242,16 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) ...@@ -1242,20 +1242,16 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
result = nvme_enable_ctrl(&dev->ctrl, cap); result = nvme_enable_ctrl(&dev->ctrl, cap);
if (result) if (result)
goto free_nvmeq; return result;
nvmeq->cq_vector = 0; nvmeq->cq_vector = 0;
result = queue_request_irq(nvmeq); result = queue_request_irq(nvmeq);
if (result) { if (result) {
nvmeq->cq_vector = -1; nvmeq->cq_vector = -1;
goto free_nvmeq; return result;
} }
return result; return result;
free_nvmeq:
nvme_free_queues(dev, 0);
return result;
} }
static bool nvme_should_reset(struct nvme_dev *dev, u32 csts) static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
...@@ -1317,10 +1313,8 @@ static int nvme_create_io_queues(struct nvme_dev *dev) ...@@ -1317,10 +1313,8 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
max = min(dev->max_qid, dev->queue_count - 1); max = min(dev->max_qid, dev->queue_count - 1);
for (i = dev->online_queues; i <= max; i++) { for (i = dev->online_queues; i <= max; i++) {
ret = nvme_create_queue(dev->queues[i], i); ret = nvme_create_queue(dev->queues[i], i);
if (ret) { if (ret)
nvme_free_queues(dev, i);
break; break;
}
} }
/* /*
...@@ -1460,13 +1454,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) ...@@ -1460,13 +1454,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
result = queue_request_irq(adminq); result = queue_request_irq(adminq);
if (result) { if (result) {
adminq->cq_vector = -1; adminq->cq_vector = -1;
goto free_queues; return result;
} }
return nvme_create_io_queues(dev); return nvme_create_io_queues(dev);
free_queues:
nvme_free_queues(dev, 1);
return result;
} }
static void nvme_del_queue_end(struct request *req, int error) static void nvme_del_queue_end(struct request *req, int error)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment