Commit 0063e8bb authored by weiping zhang's avatar weiping zhang Committed by Michael S. Tsirkin

virtio_vop: don't kfree device on register failure

As mentioned at drivers/base/core.c:
/*
 * NOTE: _Never_ directly free @dev after calling this function, even
 * if it returned an error! Always use put_device() to give up the
 * reference initialized in this function instead.
 */
so we don't free vdev until vdev->vdev.dev.release be called.
Signed-off-by: default avatarweiping zhang <zhangweiping@didichuxing.com>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent 33635bd9
...@@ -452,10 +452,12 @@ static irqreturn_t vop_virtio_intr_handler(int irq, void *data) ...@@ -452,10 +452,12 @@ static irqreturn_t vop_virtio_intr_handler(int irq, void *data)
static void vop_virtio_release_dev(struct device *_d) static void vop_virtio_release_dev(struct device *_d)
{ {
/* struct virtio_device *vdev =
* No need for a release method similar to virtio PCI. container_of(_d, struct virtio_device, dev);
* Provide an empty one to avoid getting a warning from core. struct _vop_vdev *vop_vdev =
*/ container_of(vdev, struct _vop_vdev, vdev);
kfree(vop_vdev);
} }
/* /*
...@@ -466,7 +468,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d, ...@@ -466,7 +468,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
unsigned int offset, struct vop_device *vpdev, unsigned int offset, struct vop_device *vpdev,
int dnode) int dnode)
{ {
struct _vop_vdev *vdev; struct _vop_vdev *vdev, *reg_dev = NULL;
int ret; int ret;
u8 type = ioread8(&d->type); u8 type = ioread8(&d->type);
...@@ -497,6 +499,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d, ...@@ -497,6 +499,7 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db); vdev->c2h_vdev_db = ioread8(&vdev->dc->c2h_vdev_db);
ret = register_virtio_device(&vdev->vdev); ret = register_virtio_device(&vdev->vdev);
reg_dev = vdev;
if (ret) { if (ret) {
dev_err(_vop_dev(vdev), dev_err(_vop_dev(vdev),
"Failed to register vop device %u type %u\n", "Failed to register vop device %u type %u\n",
...@@ -512,7 +515,10 @@ static int _vop_add_device(struct mic_device_desc __iomem *d, ...@@ -512,7 +515,10 @@ static int _vop_add_device(struct mic_device_desc __iomem *d,
free_irq: free_irq:
vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev); vpdev->hw_ops->free_irq(vpdev, vdev->virtio_cookie, vdev);
kfree: kfree:
kfree(vdev); if (reg_dev)
put_device(&vdev->vdev.dev);
else
kfree(vdev);
return ret; return ret;
} }
...@@ -568,7 +574,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d, ...@@ -568,7 +574,7 @@ static int _vop_remove_device(struct mic_device_desc __iomem *d,
iowrite8(-1, &dc->h2c_vdev_db); iowrite8(-1, &dc->h2c_vdev_db);
if (status & VIRTIO_CONFIG_S_DRIVER_OK) if (status & VIRTIO_CONFIG_S_DRIVER_OK)
wait_for_completion(&vdev->reset_done); wait_for_completion(&vdev->reset_done);
kfree(vdev); put_device(&vdev->vdev.dev);
iowrite8(1, &dc->guest_ack); iowrite8(1, &dc->guest_ack);
dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n", dev_dbg(&vpdev->dev, "%s %d guest_ack %d\n",
__func__, __LINE__, ioread8(&dc->guest_ack)); __func__, __LINE__, ioread8(&dc->guest_ack));
......
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