Skip to content

Commit 7dc58aa

Browse files
ij-intelbjorn-helgaas
authored andcommitted
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
1 parent 85796d2 commit 7dc58aa

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

drivers/pci/pci-sysfs.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,13 +1562,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
15621562
const char *buf, size_t count)
15631563
{
15641564
struct pci_dev *pdev = to_pci_dev(dev);
1565-
unsigned long size, flags;
1565+
struct pci_bus *bus = pdev->bus;
1566+
struct resource *b_win, *res;
1567+
unsigned long size;
15661568
int ret, i;
15671569
u16 cmd;
15681570

15691571
if (kstrtoul(buf, 0, &size) < 0)
15701572
return -EINVAL;
15711573

1574+
b_win = pbus_select_window(bus, pci_resource_n(pdev, n));
1575+
if (!b_win)
1576+
return -EINVAL;
1577+
15721578
device_lock(dev);
15731579
if (dev->driver || pci_num_vf(pdev)) {
15741580
ret = -EBUSY;
@@ -1588,19 +1594,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
15881594
pci_write_config_word(pdev, PCI_COMMAND,
15891595
cmd & ~PCI_COMMAND_MEMORY);
15901596

1591-
flags = pci_resource_flags(pdev, n);
1592-
15931597
pci_remove_resource_files(pdev);
15941598

1595-
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
1596-
if (pci_resource_len(pdev, i) &&
1597-
pci_resource_flags(pdev, i) == flags)
1599+
pci_dev_for_each_resource(pdev, res, i) {
1600+
if (i >= PCI_BRIDGE_RESOURCES)
1601+
break;
1602+
1603+
if (b_win == pbus_select_window(bus, res))
15981604
pci_release_resource(pdev, i);
15991605
}
16001606

16011607
ret = pci_resize_resource(pdev, n, size);
16021608

1603-
pci_assign_unassigned_bus_resources(pdev->bus);
1609+
pci_assign_unassigned_bus_resources(bus);
16041610

16051611
if (pci_create_resource_files(pdev))
16061612
pci_warn(pdev, "Failed to recreate resource files after BAR resizing\n");

0 commit comments

Comments
 (0)