Commit 6e460c3d authored by Ilpo Järvinen's avatar Ilpo Järvinen Committed by Bjorn Helgaas
Browse files

PCI: Ensure relaxed tail alignment does not increase min_align



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: 67f90855 ("PCI: Allow relaxed bridge window tail sizing for optional resources")
Reported-by: default avatarRio Liu <rio@r26.me>
Closes: https://lore.kernel.org/all/o2bL8MtD_40-lf8GlslTw-AZpUPzm8nmfCnJKvS8RQ3NOzOW1uq1dVCEfRpUjJ2i7G2WjfQhk2IWZ7oGp-7G-jXN4qOdtnyOcjRR0PZWK5I=@r26.me/


Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Tested-by: default avatarRio Liu <rio@r26.me>
Cc: stable@vger.kernel.org	# v6.15+
Link: https://patch.msgid.link/20250822123359.16305-2-ilpo.jarvinen@linux.intel.com
parent 8f5ae30d
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -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,