Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+13 −7
Original line number Original line Diff line number Diff line
@@ -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,
			   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,
	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,6 +515,9 @@ 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:
	if (reg_dev)
		put_device(&vdev->vdev.dev);
	else
		kfree(vdev);
		kfree(vdev);
	return ret;
	return ret;
}
}
@@ -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));