Skip to content

Commit a61c55f

Browse files
Mani-Sadhasivamgregkh
authored andcommitted
PCI: Pass domain number to pci_bus_release_domain_nr() explicitly
commit 0cca961 upstream. The pci_bus_release_domain_nr() API is supposed to free the domain number allocated by pci_bus_find_domain_nr(). Most of the callers of pci_bus_find_domain_nr(), store the domain number in pci_bus::domain_nr. As such, the pci_bus_release_domain_nr() implicitly frees the domain number by dereferencing 'struct pci_bus'. However, one of the callers of this API, the PCI endpoint subsystem, doesn't have 'struct pci_bus', so it only passes NULL. Due to this, the API will end up dereferencing the NULL pointer. To fix this issue, pass the domain number to this API explicitly. Since 'struct pci_bus' is not used for anything else other than extracting the domain number, it makes sense to pass the domain number directly. Fixes: 0328947 ("PCI: endpoint: Assign PCI domain number for endpoint controllers") Closes: https://lore.kernel.org/linux-pci/c0c40ddb-bf64-4b22-9dd1-8dbb18aa2813@stanley.mountain Link: https://lore.kernel.org/linux-pci/20240912053025.25314-1-manivannan.sadhasivam@linaro.org Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 757786a commit a61c55f

5 files changed

Lines changed: 11 additions & 11 deletions

File tree

drivers/pci/endpoint/pci-epc-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ void pci_epc_destroy(struct pci_epc *epc)
840840
device_unregister(&epc->dev);
841841

842842
#ifdef CONFIG_PCI_DOMAINS_GENERIC
843-
pci_bus_release_domain_nr(NULL, &epc->dev);
843+
pci_bus_release_domain_nr(&epc->dev, epc->domain_nr);
844844
#endif
845845
}
846846
EXPORT_SYMBOL_GPL(pci_epc_destroy);

drivers/pci/pci.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6814,16 +6814,16 @@ static int of_pci_bus_find_domain_nr(struct device *parent)
68146814
return ida_alloc(&pci_domain_nr_dynamic_ida, GFP_KERNEL);
68156815
}
68166816

6817-
static void of_pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
6817+
static void of_pci_bus_release_domain_nr(struct device *parent, int domain_nr)
68186818
{
6819-
if (bus->domain_nr < 0)
6819+
if (domain_nr < 0)
68206820
return;
68216821

68226822
/* Release domain from IDA where it was allocated. */
6823-
if (of_get_pci_domain_nr(parent->of_node) == bus->domain_nr)
6824-
ida_free(&pci_domain_nr_static_ida, bus->domain_nr);
6823+
if (of_get_pci_domain_nr(parent->of_node) == domain_nr)
6824+
ida_free(&pci_domain_nr_static_ida, domain_nr);
68256825
else
6826-
ida_free(&pci_domain_nr_dynamic_ida, bus->domain_nr);
6826+
ida_free(&pci_domain_nr_dynamic_ida, domain_nr);
68276827
}
68286828

68296829
int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
@@ -6832,11 +6832,11 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent)
68326832
acpi_pci_bus_find_domain_nr(bus);
68336833
}
68346834

6835-
void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
6835+
void pci_bus_release_domain_nr(struct device *parent, int domain_nr)
68366836
{
68376837
if (!acpi_disabled)
68386838
return;
6839-
of_pci_bus_release_domain_nr(bus, parent);
6839+
of_pci_bus_release_domain_nr(parent, domain_nr);
68406840
}
68416841
#endif
68426842

drivers/pci/probe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
10611061

10621062
free:
10631063
#ifdef CONFIG_PCI_DOMAINS_GENERIC
1064-
pci_bus_release_domain_nr(bus, parent);
1064+
pci_bus_release_domain_nr(parent, bus->domain_nr);
10651065
#endif
10661066
kfree(bus);
10671067
return err;

drivers/pci/remove.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ void pci_remove_root_bus(struct pci_bus *bus)
179179
#ifdef CONFIG_PCI_DOMAINS_GENERIC
180180
/* Release domain_nr if it was dynamically allocated */
181181
if (host_bridge->domain_nr == PCI_DOMAIN_NR_NOT_SET)
182-
pci_bus_release_domain_nr(bus, host_bridge->dev.parent);
182+
pci_bus_release_domain_nr(host_bridge->dev.parent, bus->domain_nr);
183183
#endif
184184

185185
pci_remove_bus(bus);

include/linux/pci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1884,7 +1884,7 @@ static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
18841884
{ return 0; }
18851885
#endif
18861886
int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent);
1887-
void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent);
1887+
void pci_bus_release_domain_nr(struct device *parent, int domain_nr);
18881888
#endif
18891889

18901890
/* Some architectures require additional setup to direct VGA traffic */

0 commit comments

Comments
 (0)