提交 a96d4f5c 编写于 作者: K Keith Busch 提交者: Jens Axboe

NVMe: Reference count pci device

If an nvme device is removed but user space has an open reference,
the nvme driver would have been holding an invalid reference to its pci
device. You may get a general protection fault on x86 h/w when the driver
uses that reference in dma_map_sg(), as is done in nvme_map_user_pages()
from the IOCTL interface.

This patch fixes the fault by taking a reference on the pci device and
holding it even after device removal until all opens on the nvme device
are closed.
Signed-off-by: NKeith Busch <keith.busch@intel.com>
Reported-by: NNilesh Choudhury <nilesh.choudhury@oracle.com>
Signed-off-by: NMatthew Wilcox <matthew.r.wilcox@intel.com>
Signed-off-by: NJens Axboe <axboe@fb.com>
上级 062261be
......@@ -2678,6 +2678,7 @@ static void nvme_free_dev(struct kref *kref)
{
struct nvme_dev *dev = container_of(kref, struct nvme_dev, kref);
pci_dev_put(dev->pci_dev);
nvme_free_namespaces(dev);
free_percpu(dev->io_queue);
kfree(dev->queues);
......@@ -2853,11 +2854,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev->reset_workfn = nvme_reset_failed_dev;
INIT_WORK(&dev->reset_work, nvme_reset_workfn);
INIT_WORK(&dev->cpu_work, nvme_cpu_workfn);
dev->pci_dev = pdev;
dev->pci_dev = pci_dev_get(pdev);
pci_set_drvdata(pdev, dev);
result = nvme_set_instance(dev);
if (result)
goto free;
goto put_pci;
result = nvme_setup_prp_pools(dev);
if (result)
......@@ -2895,6 +2896,8 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
nvme_release_prp_pools(dev);
release:
nvme_release_instance(dev);
put_pci:
pci_dev_put(dev->pci_dev);
free:
free_percpu(dev->io_queue);
kfree(dev->queues);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册