Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: defer enablement of SRIOV BARS

All the PCI BARs of a device are enabled when the device is enabled
using pci_enable_device(). This unnecessarily enables SRIOV BARs of the
device.

On some platforms, which do not support SRIOV as yet, the
pci_enable_device() fails to enable the device if its SRIOV BARs are not
allocated resources correctly.

The following patch fixes the above problem. The SRIOV BARs are now
enabled when IOV capability of the device is enabled in sriov_enable().

NOTE: Note, there is subtle change in the pci_enable_device() API. Any
driver that depends on SRIOV BARS to be enabled in pci_enable_device()
can fail.

The patch has been touch tested on power and x86 platform.

Tested-by: Michael Wang <wangyun@linux.vnet.ibm.com>
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

authored by

Ram Pai and committed by
Jesse Barnes
bbef98ab 8e8da023

+8 -1
+7
drivers/pci/iov.c
··· 283 283 struct resource *res; 284 284 struct pci_dev *pdev; 285 285 struct pci_sriov *iov = dev->sriov; 286 + int bars = 0; 286 287 287 288 if (!nr_virtfn) 288 289 return 0; ··· 308 307 309 308 nres = 0; 310 309 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { 310 + bars |= (1 << (i + PCI_IOV_RESOURCES)); 311 311 res = dev->resource + PCI_IOV_RESOURCES + i; 312 312 if (res->parent) 313 313 nres++; ··· 323 321 324 322 if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) { 325 323 dev_err(&dev->dev, "SR-IOV: bus number out of range\n"); 324 + return -ENOMEM; 325 + } 326 + 327 + if (pci_enable_resources(dev, bars)) { 328 + dev_err(&dev->dev, "SR-IOV: IOV BARS not allocated\n"); 326 329 return -ENOMEM; 327 330 } 328 331
+1 -1
drivers/pci/pci.c
··· 1126 1126 if (atomic_add_return(1, &dev->enable_cnt) > 1) 1127 1127 return 0; /* already enabled */ 1128 1128 1129 - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) 1129 + for (i = 0; i < PCI_ROM_RESOURCE; i++) 1130 1130 if (dev->resource[i].flags & flags) 1131 1131 bars |= (1 << i); 1132 1132