Commit 04db6314 authored by Mika Westerberg's avatar Mika Westerberg Committed by sanglipeng
Browse files

PCI: Align extra resources for hotplug bridges properly

stable inclusion
from stable-v5.10.173
commit fdca189e522850ee122a409ed7e693795e31fb58
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7X0QU

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=fdca189e522850ee122a409ed7e693795e31fb58

--------------------------------

[ Upstream commit 08f0a15e ]

After division the extra resource space per hotplug bridge may not be
aligned according to the window alignment, so align it before passing it
down for further distribution.

Link: https://lore.kernel.org/r/20230131092405.29121-2-mika.westerberg@linux.intel.com


Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarsanglipeng <sanglipeng1@jd.com>
parent 547e8af4
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -2004,6 +2004,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
	 * resource space between hotplug bridges.
	 */
	for_each_pci_bridge(dev, bus) {
		struct resource *res;
		struct pci_bus *b;

		b = dev->subordinate;
@@ -2015,16 +2016,28 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
		 * hotplug-capable downstream ports taking alignment into
		 * account.
		 */
		io.end = io.start + io_per_hp - 1;
		mmio.end = mmio.start + mmio_per_hp - 1;
		mmio_pref.end = mmio_pref.start + mmio_pref_per_hp - 1;
		res = &dev->resource[PCI_BRIDGE_IO_WINDOW];
		align = pci_resource_alignment(dev, res);
		io.end = align ? io.start + ALIGN_DOWN(io_per_hp, align) - 1
			       : io.start + io_per_hp - 1;

		res = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
		align = pci_resource_alignment(dev, res);
		mmio.end = align ? mmio.start + ALIGN_DOWN(mmio_per_hp, align) - 1
				 : mmio.start + mmio_per_hp - 1;

		res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
		align = pci_resource_alignment(dev, res);
		mmio_pref.end = align ? mmio_pref.start +
					ALIGN_DOWN(mmio_pref_per_hp, align) - 1
				      : mmio_pref.start + mmio_pref_per_hp - 1;

		pci_bus_distribute_available_resources(b, add_list, io, mmio,
						       mmio_pref);

		io.start += io_per_hp;
		mmio.start += mmio_per_hp;
		mmio_pref.start += mmio_pref_per_hp;
		io.start += io.end + 1;
		mmio.start += mmio.end + 1;
		mmio_pref.start += mmio_pref.end + 1;
	}
}