[PATCH v5 05/14] PCI: Prevent zero align from reaching __ffs64()

From: Ilpo Järvinen

Date: Fri Nov 06 2026 - 08:48:00 EST


The bridge window sizing algorithm calculates order from alignment
using __ffs64(). __ffs*() is undefined for zero input.

pci_resource_alignment() & resource_alignment() have a number potential
ways ways to return 0, in fact, resource_alignment() intentionally does
that if neither SIZEALIGN nor STARTALIGN is set.

Thus, ensure zero align is always properly dealt with in
pbus_size_mem(). pdev_sort_resources() already has a similar check for
values returned from pci_resource_alignment() (though it is not using
__ffs*()).

Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
---
drivers/pci/setup-bus.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index f4358322f766..9d167e7773a1 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1309,6 +1309,8 @@ static void pbus_size_mem(struct pci_bus *bus, struct resource *b_res,
continue;

align = pci_resource_alignment(dev, r);
+ if (!align)
+ goto bad_alignment;
/*
* aligns[0] is for 1MB (since bridge memory
* windows are always at least 1MB aligned), so
@@ -1317,6 +1319,7 @@ static void pbus_size_mem(struct pci_bus *bus, struct resource *b_res,
*/
order = max_t(int, __ffs64(align) - __ffs(SZ_1M), 0);
if (order >= ARRAY_SIZE(aligns)) {
+bad_alignment:
pci_warn(dev, "%s %pR: disabling; bad alignment %#llx\n",
r_name, r, (unsigned long long) align);
r->flags = 0;
--
2.47.3