[PATCH v2 1/2] PCI: Skip Resizable BAR restore on read error

From: Marco Nenciarini

Date: Fri Apr 17 2026 - 09:26:04 EST


pci_restore_rebar_state() uses the Resizable BAR Control register to
decide how many BARs to restore (nbars) and which BAR each iteration
addresses (bar_idx).

When the device does not respond, config reads return the all-ones
pattern. Both fields are 3 bits wide, so nbars and bar_idx both
evaluate to 7, past the spec's valid ranges for both fields.
pci_resource_n() then returns an unrelated resource slot, whose
size is used to derive a nonsensical value written back to the
Resizable BAR Control register.

Bail out if any Resizable BAR Control read returns the error
pattern. No further BARs are touched, which is safe because a
config read that returns the error pattern indicates the device is
unreachable and restoration is pointless.

Fixes: d3252ace0bc6 ("PCI: Restore resized BAR state on resume")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Marco Nenciarini <mnencia@xxxxxxxx>
---
Cc: Michał Winiarski <michal.winiarski@xxxxxxxxx>
Cc: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx>
Cc: Rafael J. Wysocki <rafael@xxxxxxxxxx>
Cc: Eric Chanudet <echanude@xxxxxxxxxx>
Cc: Alex Williamson <alex@xxxxxxxxxxx>
Cc: Lukas Wunner <lukas@xxxxxxxxx>

drivers/pci/rebar.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/drivers/pci/rebar.c b/drivers/pci/rebar.c
index 39f8cf3b70d57..11965947c4cb5 100644
--- a/drivers/pci/rebar.c
+++ b/drivers/pci/rebar.c
@@ -231,6 +231,9 @@ void pci_restore_rebar_state(struct pci_dev *pdev)
return;

pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+ if (PCI_POSSIBLE_ERROR(ctrl))
+ return;
+
nbars = FIELD_GET(PCI_REBAR_CTRL_NBAR_MASK, ctrl);

for (i = 0; i < nbars; i++, pos += 8) {
@@ -238,6 +241,9 @@ void pci_restore_rebar_state(struct pci_dev *pdev)
int bar_idx, size;

pci_read_config_dword(pdev, pos + PCI_REBAR_CTRL, &ctrl);
+ if (PCI_POSSIBLE_ERROR(ctrl))
+ return;
+
bar_idx = ctrl & PCI_REBAR_CTRL_BAR_IDX;
res = pci_resource_n(pdev, bar_idx);
size = pci_rebar_bytes_to_size(resource_size(res));
--
2.47.3