PCI: Use pbus_select_window() during BAR resize

Prior to a BAR resize, __resource_resize_store() loops through the normal
resources of the PCI device and releases those that match to the flags of
the BAR to be resized. This is necessary to allow resizing also the
upstream bridge window as only childless bridge windows can be resized.

While the flags check (mostly) works (if corner cases are ignored), the
more straightforward way is to check if the resources share the bridge
window. Change __resource_resize_store() to do the check using
pbus_select_window().

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20250829131113.36754-16-ilpo.jarvinen@linux.intel.com
This commit is contained in:
Ilpo Järvinen 2025-08-29 16:11:04 +03:00 committed by Bjorn Helgaas
parent 85796d20a6
commit 7dc58aa7f1

View File

@ -1562,13 +1562,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
const char *buf, size_t count)
{
struct pci_dev *pdev = to_pci_dev(dev);
unsigned long size, flags;
struct pci_bus *bus = pdev->bus;
struct resource *b_win, *res;
unsigned long size;
int ret, i;
u16 cmd;
if (kstrtoul(buf, 0, &size) < 0)
return -EINVAL;
b_win = pbus_select_window(bus, pci_resource_n(pdev, n));
if (!b_win)
return -EINVAL;
device_lock(dev);
if (dev->driver || pci_num_vf(pdev)) {
ret = -EBUSY;
@ -1588,19 +1594,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
pci_write_config_word(pdev, PCI_COMMAND,
cmd & ~PCI_COMMAND_MEMORY);
flags = pci_resource_flags(pdev, n);
pci_remove_resource_files(pdev);
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
if (pci_resource_len(pdev, i) &&
pci_resource_flags(pdev, i) == flags)
pci_dev_for_each_resource(pdev, res, i) {
if (i >= PCI_BRIDGE_RESOURCES)
break;
if (b_win == pbus_select_window(bus, res))
pci_release_resource(pdev, i);
}
ret = pci_resize_resource(pdev, n, size);
pci_assign_unassigned_bus_resources(pdev->bus);
pci_assign_unassigned_bus_resources(bus);
if (pci_create_resource_files(pdev))
pci_warn(pdev, "Failed to recreate resource files after BAR resizing\n");