diff options
author | Liang He <windhl@126.com> | 2022-07-02 05:29:36 +0300 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2022-09-05 10:30:29 +0300 |
commit | ce63c44b63cdae892107717ba10fdb6fb4fc6cdb (patch) | |
tree | 77cc4d6282679ff0b17363ea491a8e13c5a1c7a2 /arch | |
parent | 605c27f3802038e4623b6fd1bbfa021e1f65b5c4 (diff) | |
download | linux-ce63c44b63cdae892107717ba10fdb6fb4fc6cdb.tar.xz |
powerpc/pci-common: Fix refcount bug for 'phb->dn'
In pcibios_alloc_controller(), 'phb' is allocated and escaped into
global 'hose_list'. So we should call of_node_get() when a new reference
created into 'phb->dn'. And when phb is freed, we should call
of_node_put() on it.
NOTE: This function is called in the iteration of for_each_xx in
chrp_find_bridges() and pSeries_discover_phbs(). If there is no
of_node_get(), the object may be prematurely freed.
Signed-off-by: Liang He <windhl@126.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220702022936.266146-1-windhl@126.com
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/pci-common.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 31de91c8359c..d67cf79bf5d0 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -135,7 +135,7 @@ struct pci_controller *pcibios_alloc_controller(struct device_node *dev) list_add_tail(&phb->list_node, &hose_list); spin_unlock(&hose_spinlock); - phb->dn = dev; + phb->dn = of_node_get(dev); phb->is_dynamic = slab_is_available(); #ifdef CONFIG_PPC64 if (dev) { @@ -158,7 +158,7 @@ void pcibios_free_controller(struct pci_controller *phb) /* Clear bit of phb_bitmap to allow reuse of this PHB number. */ if (phb->global_number < MAX_PHBS) clear_bit(phb->global_number, phb_bitmap); - + of_node_put(phb->dn); list_del(&phb->list_node); spin_unlock(&hose_spinlock); |