| From 343df771e671d821478dd3ef525a0610b808dbf8 Mon Sep 17 00:00:00 2001 |
| From: Jiang Liu <liuj97@gmail.com> |
| Date: Fri, 7 Jun 2013 01:10:08 +0800 |
| Subject: PCI: Fix refcount issue in pci_create_root_bus() error recovery path |
| |
| From: Jiang Liu <liuj97@gmail.com> |
| |
| commit 343df771e671d821478dd3ef525a0610b808dbf8 upstream. |
| |
| After calling device_register(&bridge->dev), the bridge is reference- |
| counted, and it is illegal to call kfree() on it except in the release |
| function. |
| |
| [bhelgaas: changelog, use put_device() after device_register() failure] |
| Signed-off-by: Jiang Liu <jiang.liu@huawei.com> |
| Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/pci/probe.c | 14 ++++++++------ |
| 1 file changed, 8 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/pci/probe.c |
| +++ b/drivers/pci/probe.c |
| @@ -1694,12 +1694,16 @@ struct pci_bus *pci_create_root_bus(stru |
| bridge->dev.release = pci_release_bus_bridge_dev; |
| dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
| error = pcibios_root_bridge_prepare(bridge); |
| - if (error) |
| - goto bridge_dev_reg_err; |
| + if (error) { |
| + kfree(bridge); |
| + goto err_out; |
| + } |
| |
| error = device_register(&bridge->dev); |
| - if (error) |
| - goto bridge_dev_reg_err; |
| + if (error) { |
| + put_device(&bridge->dev); |
| + goto err_out; |
| + } |
| b->bridge = get_device(&bridge->dev); |
| device_enable_async_suspend(b->bridge); |
| pci_set_bus_of_node(b); |
| @@ -1753,8 +1757,6 @@ struct pci_bus *pci_create_root_bus(stru |
| class_dev_reg_err: |
| put_device(&bridge->dev); |
| device_unregister(&bridge->dev); |
| -bridge_dev_reg_err: |
| - kfree(bridge); |
| err_out: |
| kfree(b); |
| return NULL; |