[PATCH] NVMe: Add a character device for each nvme device
Matthew Wilcox
willy at linux.intel.com
Fri Jul 27 16:44:47 EDT 2012
On Fri, Jul 27, 2012 at 10:44:18AM -0600, Keith Busch wrote:
> @@ -1222,6 +1228,35 @@ static const struct block_device_operations nvme_fops = {
> .compat_ioctl = nvme_ioctl,
> };
>
> +static long nvme_char_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
> +{
> + struct nvme_dev *dev;
> + int instance = iminor(f->f_dentry->d_inode);
> +
> + spin_lock(&dev_list_lock);
> + list_for_each_entry(dev, &dev_list, node) {
> + if (dev->instance == instance)
> + break;
> + }
> + spin_unlock(&dev_list_lock);
So what happens if we get a PCI hotplug event here? nvme_remove gets
called, we unmap the BAR and kfree the dev. Now nvme_user_admin_cmd()
is going to dereference a pointer to freed memory, and even if that
happens to work, it's going to end up writing a doorbell that doesn't
exist any more.
I think we need refcounting on the dev to fix this ... urgh.
> + if (&dev->node == &dev_list)
> + return -ENOTTY;
> +
> + switch (cmd) {
> + case NVME_IOCTL_ADMIN_CMD:
> + return nvme_user_admin_cmd(dev, (void __user *)arg);
> + default:
> + return -ENOTTY;
> + }
> +}
More information about the Linux-nvme
mailing list