From e5f72cb9cea599dc9f5a9b80a33560a1d06f01cc Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 10 Feb 2026 22:20:57 +0800 Subject: [PATCH 1/5] PCI: Validate window resource type in pbus_select_window_for_type() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After ebe091ad81e1 ("PCI: Use pbus_select_window_for_type() during IO window sizing") and ae88d0b9c57f ("PCI: Use pbus_select_window_for_type() during mem window sizing"), many bridge windows can't get resources assigned: pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: can't assign; no space pci 0006:05:00.0: bridge window [??? 0x00001000-0x00001fff flags 0x20080000]: failed to assign Those commits replace find_bus_resource_of_type() with pbus_select_window_for_type(), and the latter lacks resource type validation. Add the resource type validation back to pbus_select_window_for_type() to match the original behavior. Fixes: 74afce3dfcba ("PCI: Add bridge window selection functions") Link: https://bugzilla.kernel.org/show_bug.cgi?id=221072 Signed-off-by: Kai-Heng Feng Signed-off-by: Bjorn Helgaas Reviewed-by: Ilpo Järvinen Link: https://patch.msgid.link/20260210142058.82701-1-kaihengf@nvidia.com --- drivers/pci/setup-bus.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 32aa72456a44..f30d1f7f023a 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -224,14 +224,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus, switch (iores_type) { case IORESOURCE_IO: - return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); + win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); + if (win && (win->flags & IORESOURCE_IO)) + return win; + return NULL; case IORESOURCE_MEM: mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); - if (!(type & IORESOURCE_PREFETCH) || - !(mmio_pref->flags & IORESOURCE_MEM)) + if (mmio && !(mmio->flags & IORESOURCE_MEM)) + mmio = NULL; + if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM)) + mmio_pref = NULL; + + if (!(type & IORESOURCE_PREFETCH) || !mmio_pref) return mmio; if ((type & IORESOURCE_MEM_64) || From a3b93b42238b3bb9eefc25729f567e66eea66a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Thu, 19 Feb 2026 00:34:18 +0200 Subject: [PATCH 2/5] PCI: Account fully optional bridge windows correctly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pbus_size_mem_optional() adds dev_res->add_size of a bridge window into children_add_size when the window has a non-optional part. However, if the bridge window is fully optional, only r_size is added (which is zero for such a window). Also, a second dev_res entry will be added by pci_dev_res_add_to_list() into realloc_head for the bridge window (resulting in triggering the realloc_head-must-be-fully-consumed sanity check after a single pass of the resource assignment algorithm): WARNING: drivers/pci/setup-bus.c:2153 at pci_assign_unassigned_root_bus_resources+0xa5/0x260 Correct these problems by always adding dev_res->add_size for bridge windows and not calling pci_dev_res_add_to_list() if the dev_res entry exists. Fixes: 6a5e64c75e82 ("PCI: Add pbus_mem_size_optional() to handle optional sizes") Reported-by: RavitejaX Veesam Signed-off-by: Ilpo Järvinen Signed-off-by: Bjorn Helgaas Tested-by: RavitejaX Veesam Link: https://patch.msgid.link/20260218223419.22366-1-ilpo.jarvinen@linux.intel.com --- drivers/pci/setup-bus.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index f30d1f7f023a..bd66ac47b3b9 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1224,31 +1224,34 @@ static bool pbus_size_mem_optional(struct pci_dev *dev, int resno, struct resource *res = pci_resource_n(dev, resno); bool optional = pci_resource_is_optional(dev, resno); resource_size_t r_size = resource_size(res); - struct pci_dev_resource *dev_res; + struct pci_dev_resource *dev_res = NULL; if (!realloc_head) return false; - if (!optional) { - /* - * Only bridges have optional sizes in realloc_head at this - * point. As res_to_dev_res() walks the entire realloc_head - * list, skip calling it when known unnecessary. - */ - if (!pci_resource_is_bridge_win(resno)) - return false; - + /* + * Only bridges have optional sizes in realloc_head at this + * point. As res_to_dev_res() walks the entire realloc_head + * list, skip calling it when known unnecessary. + */ + if (pci_resource_is_bridge_win(resno)) { dev_res = res_to_dev_res(realloc_head, res); if (dev_res) { *children_add_size += dev_res->add_size; *add_align = max(*add_align, dev_res->min_align); } - - return false; } - /* Put SRIOV requested res to the optional list */ - pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); + if (!optional) + return false; + + /* + * Put requested res to the optional list if not there yet (SR-IOV, + * disabled ROM). Bridge windows with an optional part are already + * on the list. + */ + if (!dev_res) + pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); *children_add_size += r_size; *add_align = max(align, *add_align); From 5ddb66967924e38c680e6a304585c0f553681a3a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 11 Feb 2026 08:07:40 +0100 Subject: [PATCH 3/5] PCI: endpoint: pci-epf-test: Select configfs Like some of the other endpoint modules, pci-epf-test now also uses configfs, but is missing an indication in Kconfig: arm-linux-gnueabi-ld: drivers/pci/endpoint/functions/pci-epf-test.o: in function `pci_epf_test_add_cfs': pci-epf-test.c:(.text.pci_epf_test_add_cfs+0x2c): undefined reference to `config_group_init_type_name' Select the symbol as needed. Fixes: ffcc4850a161 ("PCI: endpoint: pci-epf-test: Allow overriding default BAR sizes") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202602180706.VtXkmtqL-lkp@intel.com/ Signed-off-by: Arnd Bergmann Signed-off-by: Bjorn Helgaas Reviewed-by: Niklas Cassel Reviewed-by: Damien Le Moal Link: https://patch.msgid.link/20260211070812.4087119-1-arnd@kernel.org --- drivers/pci/endpoint/functions/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig index 0c9cea0698d7..bb5a23994288 100644 --- a/drivers/pci/endpoint/functions/Kconfig +++ b/drivers/pci/endpoint/functions/Kconfig @@ -6,6 +6,7 @@ config PCI_EPF_TEST tristate "PCI Endpoint Test driver" depends on PCI_ENDPOINT + select CONFIGFS_FS select CRC32 help Enable this configuration option to enable the test driver From 88a71941b90ddda44f4105e354e82a89b0389bc6 Mon Sep 17 00:00:00 2001 From: Koichiro Den Date: Mon, 2 Feb 2026 23:54:06 +0900 Subject: [PATCH 4/5] PCI: dwc: ep: Return after clearing BAR-match inbound mapping dw_pcie_ep_clear_ib_maps() first checks whether the inbound mapping for a BAR is in BAR Match Mode (tracked via ep_func->bar_to_atu[bar]). Once found, the iATU region is disabled and the bookkeeping is cleared. BAR Match Mode and Address Match Mode mappings are mutually exclusive for a given BAR, so there is nothing left for the Address Match Mode teardown path to do after the BAR Match Mode mapping has been removed. Return early after clearing the BAR Match Mode mapping to avoid running the Address Match Mode teardown path. This makes the helper's intention explicit and helps detect incorrect use of pci_epc_set_bar(). Suggested-by: Niklas Cassel Signed-off-by: Koichiro Den Signed-off-by: Bjorn Helgaas Reviewed-by: Niklas Cassel Link: https://patch.msgid.link/20260202145407.503348-2-den@valinux.co.jp --- drivers/pci/controller/dwc/pcie-designware-ep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 7e7844ff0f7e..0ca05943a1e5 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -165,6 +165,7 @@ static void dw_pcie_ep_clear_ib_maps(struct dw_pcie_ep *ep, u8 func_no, enum pci dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); clear_bit(atu_index, ep->ib_window_map); ep_func->bar_to_atu[bar] = 0; + return; } /* Tear down all Address Match Mode mappings, if any. */ From 8c746e22096579897d1f8f74dbb6b17a6862fb6d Mon Sep 17 00:00:00 2001 From: Koichiro Den Date: Mon, 2 Feb 2026 23:54:07 +0900 Subject: [PATCH 5/5] PCI: dwc: ep: Always clear IB maps on BAR update dw_pcie_ep_set_bar() currently tears down existing inbound mappings only when either the previous or the new struct pci_epf_bar uses submaps (num_submap != 0). If both the old and new mappings are BAR Match Mode, reprogramming the same ATU index is sufficient, so no explicit teardown was needed. However, some callers may reuse the same struct pci_epf_bar instance and update it in place before calling set_bar() again. In that case ep_func->epf_bar[bar] and the passed-in epf_bar can point to the same object, so we cannot reliably distinguish BAR Match Mode -> BAR Match Mode from Address Match Mode -> BAR Match Mode. As a result, the conditional teardown based on num_submap becomes unreliable and existing inbound maps may be left active. Call dw_pcie_ep_clear_ib_maps() unconditionally before reprogramming the BAR so that in-place updates are handled correctly. This introduces a behavioral change in a corner case: if a BAR reprogramming attempt fails (especially for the long-standing BAR Match Mode -> BAR Match Mode update case), the previously programmed inbound mapping will already have been torn down. This should be acceptable, since the caller observes the error and should not use the BAR for any real transactions in that case. While at it, document that the existing update parameter check is best-effort for in-place updates. Fixes: cc839bef7727 ("PCI: dwc: ep: Support BAR subrange inbound mapping via Address Match Mode iATU") Signed-off-by: Koichiro Den Signed-off-by: Bjorn Helgaas Reviewed-by: Niklas Cassel Link: https://patch.msgid.link/20260202145407.503348-3-den@valinux.co.jp --- drivers/pci/controller/dwc/pcie-designware-ep.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 0ca05943a1e5..295076cf70de 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -519,6 +519,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, /* * We can only dynamically change a BAR if the new BAR size and * BAR flags do not differ from the existing configuration. + * + * Note: this safety check only works when the caller uses + * a new struct pci_epf_bar in the second set_bar() call. + * If the same instance is updated in place and passed in, + * we cannot reliably detect invalid barno/size/flags + * changes here. */ if (ep_func->epf_bar[bar]->barno != bar || ep_func->epf_bar[bar]->size != size || @@ -527,10 +533,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, /* * When dynamically changing a BAR, tear down any existing - * mappings before re-programming. + * mappings before re-programming. This is redundant when + * both the old and new mappings are BAR Match Mode, but + * required to handle in-place updates and match-mode + * changes reliably. */ - if (ep_func->epf_bar[bar]->num_submap || epf_bar->num_submap) - dw_pcie_ep_clear_ib_maps(ep, func_no, bar); + dw_pcie_ep_clear_ib_maps(ep, func_no, bar); /* * When dynamically changing a BAR, skip writing the BAR reg, as