]> www.infradead.org Git - users/hch/misc.git/commitdiff
PCI: Ensure relaxed tail alignment does not increase min_align
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 30 Jun 2025 14:26:39 +0000 (17:26 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 16 Sep 2025 16:18:15 +0000 (11:18 -0500)
When using relaxed tail alignment for the bridge window, pbus_size_mem()
also tries to minimize min_align, which can under certain scenarios end up
increasing min_align from that found by calculate_mem_align().

Ensure min_align is not increased by the relaxed tail alignment.

Eventually, it would be better to add calculate_relaxed_head_align()
similar to calculate_mem_align() which finds out what alignment can be used
for the head without introducing any gaps into the bridge window to give
flexibility on head address too. But that looks relatively complex so it
requires much more testing than fixing the immediate problem causing a
regression.

Fixes: 67f9085596ee ("PCI: Allow relaxed bridge window tail sizing for optional resources")
Reported-by: Rio Liu <rio@r26.me>
Closes: https://lore.kernel.org/all/o2bL8MtD_40-lf8GlslTw-AZpUPzm8nmfCnJKvS8RQ3NOzOW1uq1dVCEfRpUjJ2i7G2WjfQhk2IWZ7oGp-7G-jXN4qOdtnyOcjRR0PZWK5I=@r26.me/
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Rio Liu <rio@r26.me>
Cc: stable@vger.kernel.org # v6.15+
Link: https://patch.msgid.link/20250822123359.16305-2-ilpo.jarvinen@linux.intel.com
drivers/pci/setup-bus.c

index 7853ac6999e2cac4745247cb3e80bae7d5569000..527f0479e983cfb411f2062bfa9aef17e02d4239 100644 (file)
@@ -1169,6 +1169,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
        resource_size_t children_add_size = 0;
        resource_size_t children_add_align = 0;
        resource_size_t add_align = 0;
+       resource_size_t relaxed_align;
 
        if (!b_res)
                return -ENOSPC;
@@ -1246,8 +1247,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
        if (bus->self && size0 &&
            !pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type,
                                           size0, min_align)) {
-               min_align = 1ULL << (max_order + __ffs(SZ_1M));
-               min_align = max(min_align, win_align);
+               relaxed_align = 1ULL << (max_order + __ffs(SZ_1M));
+               relaxed_align = max(relaxed_align, win_align);
+               min_align = min(min_align, relaxed_align);
                size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), win_align);
                pci_info(bus->self, "bridge window %pR to %pR requires relaxed alignment rules\n",
                         b_res, &bus->busn_res);
@@ -1261,8 +1263,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
                if (bus->self && size1 &&
                    !pbus_upstream_space_available(bus, mask | IORESOURCE_PREFETCH, type,
                                                   size1, add_align)) {
-                       min_align = 1ULL << (max_order + __ffs(SZ_1M));
-                       min_align = max(min_align, win_align);
+                       relaxed_align = 1ULL << (max_order + __ffs(SZ_1M));
+                       relaxed_align = max(relaxed_align, win_align);
+                       min_align = min(min_align, relaxed_align);
                        size1 = calculate_memsize(size, min_size, add_size, children_add_size,
                                                  resource_size(b_res), win_align);
                        pci_info(bus->self,