diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-23 22:16:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-23 22:16:01 -0400 |
commit | 299d14d4c31aff3b37a03894e012edf8421676ee (patch) | |
tree | cb1ca4a273ff202818461f339bf947acb11924a3 /drivers/pci/iov.c | |
parent | e94f8ccde4710f9a3e51dd3bc6134c96e33f29b3 (diff) | |
parent | c5048a73b4770304699cb15e3ffcb97acab685f7 (diff) |
Merge tag 'pci-v5.4-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"Enumeration:
- Consolidate _HPP/_HPX stuff in pci-acpi.c and simplify it
(Krzysztof Wilczynski)
- Fix incorrect PCIe device types and remove dev->has_secondary_link
to simplify code that deals with upstream/downstream ports (Mika
Westerberg)
- After suspend, restore Resizable BAR size bits correctly for 1MB
BARs (Sumit Saxena)
- Enable PCI_MSI_IRQ_DOMAIN support for RISC-V (Wesley Terpstra)
Virtualization:
- Add ACS quirks for iProc PAXB (Abhinav Ratna), Amazon Annapurna
Labs (Ali Saidi)
- Move sysfs SR-IOV functions to iov.c (Kelsey Skunberg)
- Remove group write permissions from sysfs sriov_numvfs,
sriov_drivers_autoprobe (Kelsey Skunberg)
Hotplug:
- Simplify pciehp indicator control (Denis Efremov)
Peer-to-peer DMA:
- Allow P2P DMA between root ports for whitelisted bridges (Logan
Gunthorpe)
- Whitelist some Intel host bridges for P2P DMA (Logan Gunthorpe)
- DMA map P2P DMA requests that traverse host bridge (Logan
Gunthorpe)
Amazon Annapurna Labs host bridge driver:
- Add DT binding and controller driver (Jonathan Chocron)
Hyper-V host bridge driver:
- Fix hv_pci_dev->pci_slot use-after-free (Dexuan Cui)
- Fix PCI domain number collisions (Haiyang Zhang)
- Use instance ID bytes 4 & 5 as PCI domain numbers (Haiyang Zhang)
- Fix build errors on non-SYSFS config (Randy Dunlap)
i.MX6 host bridge driver:
- Limit DBI register length (Stefan Agner)
Intel VMD host bridge driver:
- Fix config addressing issues (Jon Derrick)
Layerscape host bridge driver:
- Add bar_fixed_64bit property to endpoint driver (Xiaowei Bao)
- Add CONFIG_PCI_LAYERSCAPE_EP to build EP/RC drivers separately
(Xiaowei Bao)
Mediatek host bridge driver:
- Add MT7629 controller support (Jianjun Wang)
Mobiveil host bridge driver:
- Fix CPU base address setup (Hou Zhiqiang)
- Make "num-lanes" property optional (Hou Zhiqiang)
Tegra host bridge driver:
- Fix OF node reference leak (Nishka Dasgupta)
- Disable MSI for root ports to work around design problem (Vidya
Sagar)
- Add Tegra194 DT binding and controller support (Vidya Sagar)
- Add support for sideband pins and slot regulators (Vidya Sagar)
- Add PIPE2UPHY support (Vidya Sagar)
Misc:
- Remove unused pci_block_cfg_access() et al (Kelsey Skunberg)
- Unexport pci_bus_get(), etc (Kelsey Skunberg)
- Hide PM, VC, link speed, ATS, ECRC, PTM constants and interfaces in
the PCI core (Kelsey Skunberg)
- Clean up sysfs DEVICE_ATTR() usage (Kelsey Skunberg)
- Mark expected switch fall-through (Gustavo A. R. Silva)
- Propagate errors for optional regulators and PHYs (Thierry Reding)
- Fix kernel command line resource_alignment parameter issues (Logan
Gunthorpe)"
* tag 'pci-v5.4-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (112 commits)
PCI: Add pci_irq_vector() and other stubs when !CONFIG_PCI
arm64: tegra: Add PCIe slot supply information in p2972-0000 platform
arm64: tegra: Add configuration for PCIe C5 sideband signals
PCI: tegra: Add support to enable slot regulators
PCI: tegra: Add support to configure sideband pins
PCI: vmd: Fix shadow offsets to reflect spec changes
PCI: vmd: Fix config addressing when using bus offsets
PCI: dwc: Add validation that PCIe core is set to correct mode
PCI: dwc: al: Add Amazon Annapurna Labs PCIe controller driver
dt-bindings: PCI: Add Amazon's Annapurna Labs PCIe host bridge binding
PCI: Add quirk to disable MSI-X support for Amazon's Annapurna Labs Root Port
PCI/VPD: Prevent VPD access for Amazon's Annapurna Labs Root Port
PCI: Add ACS quirk for Amazon Annapurna Labs root ports
PCI: Add Amazon's Annapurna Labs vendor ID
MAINTAINERS: Add PCI native host/endpoint controllers designated reviewer
PCI: hv: Use bytes 4 and 5 from instance ID as the PCI domain numbers
dt-bindings: PCI: tegra: Add PCIe slot supplies regulator entries
dt-bindings: PCI: tegra: Add sideband pins configuration entries
PCI: tegra: Add Tegra194 PCIe support
PCI: Get rid of dev->has_secondary_link flag
...
Diffstat (limited to 'drivers/pci/iov.c')
-rw-r--r-- | drivers/pci/iov.c | 171 |
1 files changed, 169 insertions, 2 deletions
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 525fd3f272b3..b3f972e8cfed 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -240,6 +240,173 @@ void pci_iov_remove_virtfn(struct pci_dev *dev, int id) | |||
240 | pci_dev_put(dev); | 240 | pci_dev_put(dev); |
241 | } | 241 | } |
242 | 242 | ||
243 | static ssize_t sriov_totalvfs_show(struct device *dev, | ||
244 | struct device_attribute *attr, | ||
245 | char *buf) | ||
246 | { | ||
247 | struct pci_dev *pdev = to_pci_dev(dev); | ||
248 | |||
249 | return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev)); | ||
250 | } | ||
251 | |||
252 | static ssize_t sriov_numvfs_show(struct device *dev, | ||
253 | struct device_attribute *attr, | ||
254 | char *buf) | ||
255 | { | ||
256 | struct pci_dev *pdev = to_pci_dev(dev); | ||
257 | |||
258 | return sprintf(buf, "%u\n", pdev->sriov->num_VFs); | ||
259 | } | ||
260 | |||
261 | /* | ||
262 | * num_vfs > 0; number of VFs to enable | ||
263 | * num_vfs = 0; disable all VFs | ||
264 | * | ||
265 | * Note: SRIOV spec does not allow partial VF | ||
266 | * disable, so it's all or none. | ||
267 | */ | ||
268 | static ssize_t sriov_numvfs_store(struct device *dev, | ||
269 | struct device_attribute *attr, | ||
270 | const char *buf, size_t count) | ||
271 | { | ||
272 | struct pci_dev *pdev = to_pci_dev(dev); | ||
273 | int ret; | ||
274 | u16 num_vfs; | ||
275 | |||
276 | ret = kstrtou16(buf, 0, &num_vfs); | ||
277 | if (ret < 0) | ||
278 | return ret; | ||
279 | |||
280 | if (num_vfs > pci_sriov_get_totalvfs(pdev)) | ||
281 | return -ERANGE; | ||
282 | |||
283 | device_lock(&pdev->dev); | ||
284 | |||
285 | if (num_vfs == pdev->sriov->num_VFs) | ||
286 | goto exit; | ||
287 | |||
288 | /* is PF driver loaded w/callback */ | ||
289 | if (!pdev->driver || !pdev->driver->sriov_configure) { | ||
290 | pci_info(pdev, "Driver does not support SRIOV configuration via sysfs\n"); | ||
291 | ret = -ENOENT; | ||
292 | goto exit; | ||
293 | } | ||
294 | |||
295 | if (num_vfs == 0) { | ||
296 | /* disable VFs */ | ||
297 | ret = pdev->driver->sriov_configure(pdev, 0); | ||
298 | goto exit; | ||
299 | } | ||
300 | |||
301 | /* enable VFs */ | ||
302 | if (pdev->sriov->num_VFs) { | ||
303 | pci_warn(pdev, "%d VFs already enabled. Disable before enabling %d VFs\n", | ||
304 | pdev->sriov->num_VFs, num_vfs); | ||
305 | ret = -EBUSY; | ||
306 | goto exit; | ||
307 | } | ||
308 | |||
309 | ret = pdev->driver->sriov_configure(pdev, num_vfs); | ||
310 | if (ret < 0) | ||
311 | goto exit; | ||
312 | |||
313 | if (ret != num_vfs) | ||
314 | pci_warn(pdev, "%d VFs requested; only %d enabled\n", | ||
315 | num_vfs, ret); | ||
316 | |||
317 | exit: | ||
318 | device_unlock(&pdev->dev); | ||
319 | |||
320 | if (ret < 0) | ||
321 | return ret; | ||
322 | |||
323 | return count; | ||
324 | } | ||
325 | |||
326 | static ssize_t sriov_offset_show(struct device *dev, | ||
327 | struct device_attribute *attr, | ||
328 | char *buf) | ||
329 | { | ||
330 | struct pci_dev *pdev = to_pci_dev(dev); | ||
331 | |||
332 | return sprintf(buf, "%u\n", pdev->sriov->offset); | ||
333 | } | ||
334 | |||
335 | static ssize_t sriov_stride_show(struct device *dev, | ||
336 | struct device_attribute *attr, | ||
337 | char *buf) | ||
338 | { | ||
339 | struct pci_dev *pdev = to_pci_dev(dev); | ||
340 | |||
341 | return sprintf(buf, "%u\n", pdev->sriov->stride); | ||
342 | } | ||
343 | |||
344 | static ssize_t sriov_vf_device_show(struct device *dev, | ||
345 | struct device_attribute *attr, | ||
346 | char *buf) | ||
347 | { | ||
348 | struct pci_dev *pdev = to_pci_dev(dev); | ||
349 | |||
350 | return sprintf(buf, "%x\n", pdev->sriov->vf_device); | ||
351 | } | ||
352 | |||
353 | static ssize_t sriov_drivers_autoprobe_show(struct device *dev, | ||
354 | struct device_attribute *attr, | ||
355 | char *buf) | ||
356 | { | ||
357 | struct pci_dev *pdev = to_pci_dev(dev); | ||
358 | |||
359 | return sprintf(buf, "%u\n", pdev->sriov->drivers_autoprobe); | ||
360 | } | ||
361 | |||
362 | static ssize_t sriov_drivers_autoprobe_store(struct device *dev, | ||
363 | struct device_attribute *attr, | ||
364 | const char *buf, size_t count) | ||
365 | { | ||
366 | struct pci_dev *pdev = to_pci_dev(dev); | ||
367 | bool drivers_autoprobe; | ||
368 | |||
369 | if (kstrtobool(buf, &drivers_autoprobe) < 0) | ||
370 | return -EINVAL; | ||
371 | |||
372 | pdev->sriov->drivers_autoprobe = drivers_autoprobe; | ||
373 | |||
374 | return count; | ||
375 | } | ||
376 | |||
377 | static DEVICE_ATTR_RO(sriov_totalvfs); | ||
378 | static DEVICE_ATTR_RW(sriov_numvfs); | ||
379 | static DEVICE_ATTR_RO(sriov_offset); | ||
380 | static DEVICE_ATTR_RO(sriov_stride); | ||
381 | static DEVICE_ATTR_RO(sriov_vf_device); | ||
382 | static DEVICE_ATTR_RW(sriov_drivers_autoprobe); | ||
383 | |||
384 | static struct attribute *sriov_dev_attrs[] = { | ||
385 | &dev_attr_sriov_totalvfs.attr, | ||
386 | &dev_attr_sriov_numvfs.attr, | ||
387 | &dev_attr_sriov_offset.attr, | ||
388 | &dev_attr_sriov_stride.attr, | ||
389 | &dev_attr_sriov_vf_device.attr, | ||
390 | &dev_attr_sriov_drivers_autoprobe.attr, | ||
391 | NULL, | ||
392 | }; | ||
393 | |||
394 | static umode_t sriov_attrs_are_visible(struct kobject *kobj, | ||
395 | struct attribute *a, int n) | ||
396 | { | ||
397 | struct device *dev = kobj_to_dev(kobj); | ||
398 | |||
399 | if (!dev_is_pf(dev)) | ||
400 | return 0; | ||
401 | |||
402 | return a->mode; | ||
403 | } | ||
404 | |||
405 | const struct attribute_group sriov_dev_attr_group = { | ||
406 | .attrs = sriov_dev_attrs, | ||
407 | .is_visible = sriov_attrs_are_visible, | ||
408 | }; | ||
409 | |||
243 | int __weak pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) | 410 | int __weak pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs) |
244 | { | 411 | { |
245 | return 0; | 412 | return 0; |
@@ -557,8 +724,8 @@ static void sriov_restore_state(struct pci_dev *dev) | |||
557 | ctrl |= iov->ctrl & PCI_SRIOV_CTRL_ARI; | 724 | ctrl |= iov->ctrl & PCI_SRIOV_CTRL_ARI; |
558 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, ctrl); | 725 | pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, ctrl); |
559 | 726 | ||
560 | for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) | 727 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) |
561 | pci_update_resource(dev, i); | 728 | pci_update_resource(dev, i + PCI_IOV_RESOURCES); |
562 | 729 | ||
563 | pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); | 730 | pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); |
564 | pci_iov_set_numvfs(dev, iov->num_VFs); | 731 | pci_iov_set_numvfs(dev, iov->num_VFs); |