diff options
author | weiping zhang <zhangweiping@didichuxing.com> | 2017-12-21 20:40:24 +0800 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2018-02-01 16:26:45 +0200 |
commit | 33635bd976fb4c3ccf0cfbb81a8d29bb87760607 (patch) | |
tree | ba99b9f18644729f7010e9c23b47eec9006f65be /drivers/virtio | |
parent | f2b44cde7e1687ef7886831a3a30df653bda2481 (diff) | |
download | linux-stable-33635bd976fb4c3ccf0cfbb81a8d29bb87760607.tar.gz linux-stable-33635bd976fb4c3ccf0cfbb81a8d29bb87760607.tar.bz2 linux-stable-33635bd976fb4c3ccf0cfbb81a8d29bb87760607.zip |
virtio_pci: 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 vp_dev until vp_dev->vdev.dev.release be called.
Signed-off-by: weiping zhang <zhangweiping@didichuxing.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/virtio')
-rw-r--r-- | drivers/virtio/virtio_pci_common.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index 1c4797e53f68..48d4d1cf1cb6 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -513,7 +513,7 @@ static void virtio_pci_release_dev(struct device *_d) static int virtio_pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { - struct virtio_pci_device *vp_dev; + struct virtio_pci_device *vp_dev, *reg_dev = NULL; int rc; /* allocate our structure and fill it out */ @@ -551,6 +551,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev, pci_set_master(pci_dev); rc = register_virtio_device(&vp_dev->vdev); + reg_dev = vp_dev; if (rc) goto err_register; @@ -564,7 +565,10 @@ err_register: err_probe: pci_disable_device(pci_dev); err_enable_device: - kfree(vp_dev); + if (reg_dev) + put_device(&vp_dev->vdev.dev); + else + kfree(vp_dev); return rc; } |