diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2016-10-26 12:15:35 +1100 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-11-23 17:21:42 -0600 |
commit | f40ec3c748c6912f6266c56a7f7992de61b255ed (patch) | |
tree | e1dc6271fa4d4f61af0b413a995ddc1e8e8c8c2f /drivers/pci/iov.c | |
parent | 1600f62534b7b3da7978b43b52231a54c24df287 (diff) | |
download | linux-f40ec3c748c6912f6266c56a7f7992de61b255ed.tar.gz linux-f40ec3c748c6912f6266c56a7f7992de61b255ed.tar.bz2 linux-f40ec3c748c6912f6266c56a7f7992de61b255ed.zip |
PCI: Do any VF BAR updates before enabling the BARs
Previously we enabled VFs and enable their memory space before calling
pcibios_sriov_enable(). But pcibios_sriov_enable() may update the VF BARs:
for example, on PPC PowerNV we may change them to manage the association of
VFs to PEs.
Because 64-bit BARs cannot be updated atomically, it's unsafe to update
them while they're enabled. The half-updated state may conflict with other
devices in the system.
Call pcibios_sriov_enable() before enabling the VFs so any BAR updates
happen while the VF BARs are disabled.
[bhelgaas: changelog]
Tested-by: Carol Soto <clsoto@us.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/iov.c')
-rw-r--r-- | drivers/pci/iov.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e30f05c8517f..d41ec29be60b 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -306,13 +306,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) return rc; } - pci_iov_set_numvfs(dev, nr_virtfn); - iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; - pci_cfg_access_lock(dev); - pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); - msleep(100); - pci_cfg_access_unlock(dev); - iov->initial_VFs = initial; if (nr_virtfn < initial) initial = nr_virtfn; @@ -323,6 +316,13 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) goto err_pcibios; } + pci_iov_set_numvfs(dev, nr_virtfn); + iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; + pci_cfg_access_lock(dev); + pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); + msleep(100); + pci_cfg_access_unlock(dev); + for (i = 0; i < initial; i++) { rc = pci_iov_add_virtfn(dev, i, 0); if (rc) |