--- /dev/null
+From 0cca961a026177af69044f10d6ae76d8ce043764 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Thu, 12 Sep 2024 11:00:25 +0530
+Subject: PCI: Pass domain number to pci_bus_release_domain_nr() explicitly
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+commit 0cca961a026177af69044f10d6ae76d8ce043764 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: 0328947c5032 ("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>
+---
+ drivers/pci/endpoint/pci-epc-core.c | 2 +-
+ drivers/pci/pci.c | 14 +++++++-------
+ drivers/pci/probe.c | 2 +-
+ drivers/pci/remove.c | 2 +-
+ include/linux/pci.h | 2 +-
+ 5 files changed, 11 insertions(+), 11 deletions(-)
+
+--- a/drivers/pci/endpoint/pci-epc-core.c
++++ b/drivers/pci/endpoint/pci-epc-core.c
+@@ -840,7 +840,7 @@ void pci_epc_destroy(struct pci_epc *epc
+ device_unregister(&epc->dev);
+
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
+- pci_bus_release_domain_nr(NULL, &epc->dev);
++ pci_bus_release_domain_nr(&epc->dev, epc->domain_nr);
+ #endif
+ }
+ EXPORT_SYMBOL_GPL(pci_epc_destroy);
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -6814,16 +6814,16 @@ static int of_pci_bus_find_domain_nr(str
+ return ida_alloc(&pci_domain_nr_dynamic_ida, GFP_KERNEL);
+ }
+
+-static void of_pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
++static void of_pci_bus_release_domain_nr(struct device *parent, int domain_nr)
+ {
+- if (bus->domain_nr < 0)
++ if (domain_nr < 0)
+ return;
+
+ /* Release domain from IDA where it was allocated. */
+- if (of_get_pci_domain_nr(parent->of_node) == bus->domain_nr)
+- ida_free(&pci_domain_nr_static_ida, bus->domain_nr);
++ if (of_get_pci_domain_nr(parent->of_node) == domain_nr)
++ ida_free(&pci_domain_nr_static_ida, domain_nr);
+ else
+- ida_free(&pci_domain_nr_dynamic_ida, bus->domain_nr);
++ ida_free(&pci_domain_nr_dynamic_ida, domain_nr);
+ }
+
+ 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_bu
+ acpi_pci_bus_find_domain_nr(bus);
+ }
+
+-void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent)
++void pci_bus_release_domain_nr(struct device *parent, int domain_nr)
+ {
+ if (!acpi_disabled)
+ return;
+- of_pci_bus_release_domain_nr(bus, parent);
++ of_pci_bus_release_domain_nr(parent, domain_nr);
+ }
+ #endif
+
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -1061,7 +1061,7 @@ unregister:
+
+ free:
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
+- pci_bus_release_domain_nr(bus, parent);
++ pci_bus_release_domain_nr(parent, bus->domain_nr);
+ #endif
+ kfree(bus);
+ return err;
+--- a/drivers/pci/remove.c
++++ b/drivers/pci/remove.c
+@@ -179,7 +179,7 @@ void pci_remove_root_bus(struct pci_bus
+ #ifdef CONFIG_PCI_DOMAINS_GENERIC
+ /* Release domain_nr if it was dynamically allocated */
+ if (host_bridge->domain_nr == PCI_DOMAIN_NR_NOT_SET)
+- pci_bus_release_domain_nr(bus, host_bridge->dev.parent);
++ pci_bus_release_domain_nr(host_bridge->dev.parent, bus->domain_nr);
+ #endif
+
+ pci_remove_bus(bus);
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1884,7 +1884,7 @@ static inline int acpi_pci_bus_find_doma
+ { return 0; }
+ #endif
+ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent);
+-void pci_bus_release_domain_nr(struct pci_bus *bus, struct device *parent);
++void pci_bus_release_domain_nr(struct device *parent, int domain_nr);
+ #endif
+
+ /* Some architectures require additional setup to direct VGA traffic */