aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiang Liu <liuj97@gmail.com>2013-06-06 13:10:08 -0400
committerBjorn Helgaas <bhelgaas@google.com>2013-06-07 16:42:03 -0400
commit343df771e671d821478dd3ef525a0610b808dbf8 (patch)
tree71fb953db03eaf6134345c6f277af58b8819b9d0
parenta649dbfea36bdcead7ffddc622c272844b95a13e (diff)
PCI: Fix refcount issue in pci_create_root_bus() error recovery path
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> Cc: stable@vger.kernel.org
-rw-r--r--drivers/pci/probe.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ed5ce185eed9..15c39cb09619 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1711,12 +1711,16 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1711 bridge->dev.release = pci_release_bus_bridge_dev; 1711 bridge->dev.release = pci_release_bus_bridge_dev;
1712 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); 1712 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
1713 error = pcibios_root_bridge_prepare(bridge); 1713 error = pcibios_root_bridge_prepare(bridge);
1714 if (error) 1714 if (error) {
1715 goto bridge_dev_reg_err; 1715 kfree(bridge);
1716 goto err_out;
1717 }
1716 1718
1717 error = device_register(&bridge->dev); 1719 error = device_register(&bridge->dev);
1718 if (error) 1720 if (error) {
1719 goto bridge_dev_reg_err; 1721 put_device(&bridge->dev);
1722 goto err_out;
1723 }
1720 b->bridge = get_device(&bridge->dev); 1724 b->bridge = get_device(&bridge->dev);
1721 device_enable_async_suspend(b->bridge); 1725 device_enable_async_suspend(b->bridge);
1722 pci_set_bus_of_node(b); 1726 pci_set_bus_of_node(b);
@@ -1772,8 +1776,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1772class_dev_reg_err: 1776class_dev_reg_err:
1773 put_device(&bridge->dev); 1777 put_device(&bridge->dev);
1774 device_unregister(&bridge->dev); 1778 device_unregister(&bridge->dev);
1775bridge_dev_reg_err:
1776 kfree(bridge);
1777err_out: 1779err_out:
1778 kfree(b); 1780 kfree(b);
1779 return NULL; 1781 return NULL;