diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2017-02-15 12:56:11 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-02-15 12:56:11 -0500 |
commit | 8b9c156262f9ebaa88736b93263c1af5ae5fa43e (patch) | |
tree | d86c3b6a072f4a0374c0da17999281a72128b468 | |
parent | 0dc49eb2a25a6b48e235803eeb2b52677f577ca5 (diff) | |
parent | 5b0948dfe138f0837699f46f5877f4f81c252dac (diff) |
Merge branch 'pci/virtualization' into next
* pci/virtualization:
PCI: Lock each enable/disable num_vfs operation in sysfs
PCI: Add ACS quirk for Intel Union Point
-rw-r--r-- | drivers/pci/iov.c | 7 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 23 | ||||
-rw-r--r-- | drivers/pci/pci.h | 2 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 28 |
4 files changed, 41 insertions, 19 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 47227820406d..2479ae876482 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -124,7 +124,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | |||
124 | struct pci_sriov *iov = dev->sriov; | 124 | struct pci_sriov *iov = dev->sriov; |
125 | struct pci_bus *bus; | 125 | struct pci_bus *bus; |
126 | 126 | ||
127 | mutex_lock(&iov->dev->sriov->lock); | ||
128 | bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); | 127 | bus = virtfn_add_bus(dev->bus, pci_iov_virtfn_bus(dev, id)); |
129 | if (!bus) | 128 | if (!bus) |
130 | goto failed; | 129 | goto failed; |
@@ -162,7 +161,6 @@ int pci_iov_add_virtfn(struct pci_dev *dev, int id, int reset) | |||
162 | __pci_reset_function(virtfn); | 161 | __pci_reset_function(virtfn); |
163 | 162 | ||
164 | pci_device_add(virtfn, virtfn->bus); | 163 | pci_device_add(virtfn, virtfn->bus); |
165 | mutex_unlock(&iov->dev->sriov->lock); | ||
166 | 164 | ||
167 | pci_bus_add_device(virtfn); | 165 | pci_bus_add_device(virtfn); |
168 | sprintf(buf, "virtfn%u", id); | 166 | sprintf(buf, "virtfn%u", id); |
@@ -181,12 +179,10 @@ failed2: | |||
181 | sysfs_remove_link(&dev->dev.kobj, buf); | 179 | sysfs_remove_link(&dev->dev.kobj, buf); |
182 | failed1: | 180 | failed1: |
183 | pci_dev_put(dev); | 181 | pci_dev_put(dev); |
184 | mutex_lock(&iov->dev->sriov->lock); | ||
185 | pci_stop_and_remove_bus_device(virtfn); | 182 | pci_stop_and_remove_bus_device(virtfn); |
186 | failed0: | 183 | failed0: |
187 | virtfn_remove_bus(dev->bus, bus); | 184 | virtfn_remove_bus(dev->bus, bus); |
188 | failed: | 185 | failed: |
189 | mutex_unlock(&iov->dev->sriov->lock); | ||
190 | 186 | ||
191 | return rc; | 187 | return rc; |
192 | } | 188 | } |
@@ -195,7 +191,6 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) | |||
195 | { | 191 | { |
196 | char buf[VIRTFN_ID_LEN]; | 192 | char buf[VIRTFN_ID_LEN]; |
197 | struct pci_dev *virtfn; | 193 | struct pci_dev *virtfn; |
198 | struct pci_sriov *iov = dev->sriov; | ||
199 | 194 | ||
200 | virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), | 195 | virtfn = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), |
201 | pci_iov_virtfn_bus(dev, id), | 196 | pci_iov_virtfn_bus(dev, id), |
@@ -218,10 +213,8 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id, int reset) | |||
218 | if (virtfn->dev.kobj.sd) | 213 | if (virtfn->dev.kobj.sd) |
219 | sysfs_remove_link(&virtfn->dev.kobj, "physfn"); | 214 | sysfs_remove_link(&virtfn->dev.kobj, "physfn"); |
220 | 215 | ||
221 | mutex_lock(&iov->dev->sriov->lock); | ||
222 | pci_stop_and_remove_bus_device(virtfn); | 216 | pci_stop_and_remove_bus_device(virtfn); |
223 | virtfn_remove_bus(dev->bus, virtfn->bus); | 217 | virtfn_remove_bus(dev->bus, virtfn->bus); |
224 | mutex_unlock(&iov->dev->sriov->lock); | ||
225 | 218 | ||
226 | /* balance pci_get_domain_bus_and_slot() */ | 219 | /* balance pci_get_domain_bus_and_slot() */ |
227 | pci_dev_put(virtfn); | 220 | pci_dev_put(virtfn); |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 066628776e1b..25d010d449a3 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -472,6 +472,7 @@ static ssize_t sriov_numvfs_store(struct device *dev, | |||
472 | const char *buf, size_t count) | 472 | const char *buf, size_t count) |
473 | { | 473 | { |
474 | struct pci_dev *pdev = to_pci_dev(dev); | 474 | struct pci_dev *pdev = to_pci_dev(dev); |
475 | struct pci_sriov *iov = pdev->sriov; | ||
475 | int ret; | 476 | int ret; |
476 | u16 num_vfs; | 477 | u16 num_vfs; |
477 | 478 | ||
@@ -482,38 +483,46 @@ static ssize_t sriov_numvfs_store(struct device *dev, | |||
482 | if (num_vfs > pci_sriov_get_totalvfs(pdev)) | 483 | if (num_vfs > pci_sriov_get_totalvfs(pdev)) |
483 | return -ERANGE; | 484 | return -ERANGE; |
484 | 485 | ||
486 | mutex_lock(&iov->dev->sriov->lock); | ||
487 | |||
485 | if (num_vfs == pdev->sriov->num_VFs) | 488 | if (num_vfs == pdev->sriov->num_VFs) |
486 | return count; /* no change */ | 489 | goto exit; |
487 | 490 | ||
488 | /* is PF driver loaded w/callback */ | 491 | /* is PF driver loaded w/callback */ |
489 | if (!pdev->driver || !pdev->driver->sriov_configure) { | 492 | if (!pdev->driver || !pdev->driver->sriov_configure) { |
490 | dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n"); | 493 | dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n"); |
491 | return -ENOSYS; | 494 | ret = -ENOENT; |
495 | goto exit; | ||
492 | } | 496 | } |
493 | 497 | ||
494 | if (num_vfs == 0) { | 498 | if (num_vfs == 0) { |
495 | /* disable VFs */ | 499 | /* disable VFs */ |
496 | ret = pdev->driver->sriov_configure(pdev, 0); | 500 | ret = pdev->driver->sriov_configure(pdev, 0); |
497 | if (ret < 0) | 501 | goto exit; |
498 | return ret; | ||
499 | return count; | ||
500 | } | 502 | } |
501 | 503 | ||
502 | /* enable VFs */ | 504 | /* enable VFs */ |
503 | if (pdev->sriov->num_VFs) { | 505 | if (pdev->sriov->num_VFs) { |
504 | dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n", | 506 | dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n", |
505 | pdev->sriov->num_VFs, num_vfs); | 507 | pdev->sriov->num_VFs, num_vfs); |
506 | return -EBUSY; | 508 | ret = -EBUSY; |
509 | goto exit; | ||
507 | } | 510 | } |
508 | 511 | ||
509 | ret = pdev->driver->sriov_configure(pdev, num_vfs); | 512 | ret = pdev->driver->sriov_configure(pdev, num_vfs); |
510 | if (ret < 0) | 513 | if (ret < 0) |
511 | return ret; | 514 | goto exit; |
512 | 515 | ||
513 | if (ret != num_vfs) | 516 | if (ret != num_vfs) |
514 | dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n", | 517 | dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n", |
515 | num_vfs, ret); | 518 | num_vfs, ret); |
516 | 519 | ||
520 | exit: | ||
521 | mutex_unlock(&iov->dev->sriov->lock); | ||
522 | |||
523 | if (ret < 0) | ||
524 | return ret; | ||
525 | |||
517 | return count; | 526 | return count; |
518 | } | 527 | } |
519 | 528 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index cb17db242f30..8dd38e69d6f2 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -270,7 +270,7 @@ struct pci_sriov { | |||
270 | u16 driver_max_VFs; /* max num VFs driver supports */ | 270 | u16 driver_max_VFs; /* max num VFs driver supports */ |
271 | struct pci_dev *dev; /* lowest numbered PF */ | 271 | struct pci_dev *dev; /* lowest numbered PF */ |
272 | struct pci_dev *self; /* this PF */ | 272 | struct pci_dev *self; /* this PF */ |
273 | struct mutex lock; /* lock for VF bus */ | 273 | struct mutex lock; /* lock for setting sriov_numvfs in sysfs */ |
274 | resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */ | 274 | resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */ |
275 | }; | 275 | }; |
276 | 276 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 1800befa8b8b..a0b3cd5726dc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -4150,15 +4150,35 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags) | |||
4150 | * | 4150 | * |
4151 | * N.B. This doesn't fix what lspci shows. | 4151 | * N.B. This doesn't fix what lspci shows. |
4152 | * | 4152 | * |
4153 | * The 100 series chipset specification update includes this as errata #23[3]. | ||
4154 | * | ||
4155 | * The 200 series chipset (Union Point) has the same bug according to the | ||
4156 | * specification update (Intel 200 Series Chipset Family Platform Controller | ||
4157 | * Hub, Specification Update, January 2017, Revision 001, Document# 335194-001, | ||
4158 | * Errata 22)[4]. Per the datasheet[5], root port PCI Device IDs for this | ||
4159 | * chipset include: | ||
4160 | * | ||
4161 | * 0xa290-0xa29f PCI Express Root port #{0-16} | ||
4162 | * 0xa2e7-0xa2ee PCI Express Root port #{17-24} | ||
4163 | * | ||
4153 | * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html | 4164 | * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html |
4154 | * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html | 4165 | * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html |
4166 | * [3] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-spec-update.html | ||
4167 | * [4] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-spec-update.html | ||
4168 | * [5] http://www.intel.com/content/www/us/en/chipsets/200-series-chipset-pch-datasheet-vol-1.html | ||
4155 | */ | 4169 | */ |
4156 | static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev) | 4170 | static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev) |
4157 | { | 4171 | { |
4158 | return pci_is_pcie(dev) && | 4172 | if (!pci_is_pcie(dev) || pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) |
4159 | pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT && | 4173 | return false; |
4160 | ((dev->device & ~0xf) == 0xa110 || | 4174 | |
4161 | (dev->device >= 0xa167 && dev->device <= 0xa16a)); | 4175 | switch (dev->device) { |
4176 | case 0xa110 ... 0xa11f: case 0xa167 ... 0xa16a: /* Sunrise Point */ | ||
4177 | case 0xa290 ... 0xa29f: case 0xa2e7 ... 0xa2ee: /* Union Point */ | ||
4178 | return true; | ||
4179 | } | ||
4180 | |||
4181 | return false; | ||
4162 | } | 4182 | } |
4163 | 4183 | ||
4164 | #define INTEL_SPT_ACS_CTRL (PCI_ACS_CAP + 4) | 4184 | #define INTEL_SPT_ACS_CTRL (PCI_ACS_CAP + 4) |