diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-08 13:55:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-07-08 13:55:21 -0400 |
commit | 8979319f2d361b5729b215e1d47cb5bbcaca9d76 (patch) | |
tree | 04d0d557d8c1f242b724094a277cbd4adc94c6b2 | |
parent | b2d44d145d2a72386b1b17da59a5e04989594897 (diff) | |
parent | 83235822b8b4fe47ecbd6b6bcbcc902860ac00fc (diff) |
Merge tag 'pci-v4.18-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI fixes from Bjorn Helgaas:
- Fix a use-after-free in the endpoint code (Dan Carpenter)
- Stop defaulting CONFIG_PCIE_DW_PLAT_HOST to yes (Geert Uytterhoeven)
- Fix an nfp regression caused by a change in how we limit the number
of VFs we can enable (Jakub Kicinski)
- Fix failure path cleanup issues in the new R-Car gen3 PHY support
(Marek Vasut)
- Fix leaks of OF nodes in faraday, xilinx-nwl, xilinx (Nicholas Mc
Guire)
* tag 'pci-v4.18-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
nfp: stop limiting VFs to 0
PCI/IOV: Reset total_VFs limit after detaching PF driver
PCI: faraday: Add missing of_node_put()
PCI: xilinx-nwl: Add missing of_node_put()
PCI: xilinx: Add missing of_node_put()
PCI: endpoint: Use after free in pci_epf_unregister_driver()
PCI: controller: dwc: Do not let PCIE_DW_PLAT_HOST default to yes
PCI: rcar: Clean up PHY init on failure
PCI: rcar: Shut the PHY down in failpath
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/nfp_main.c | 6 | ||||
-rw-r--r-- | drivers/pci/controller/dwc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/pci/controller/pci-ftpci100.c | 2 | ||||
-rw-r--r-- | drivers/pci/controller/pcie-rcar.c | 16 | ||||
-rw-r--r-- | drivers/pci/controller/pcie-xilinx-nwl.c | 2 | ||||
-rw-r--r-- | drivers/pci/controller/pcie-xilinx.c | 1 | ||||
-rw-r--r-- | drivers/pci/endpoint/pci-epf-core.c | 4 | ||||
-rw-r--r-- | drivers/pci/iov.c | 16 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 1 | ||||
-rw-r--r-- | drivers/pci/pci.h | 4 |
10 files changed, 41 insertions, 12 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_main.c b/drivers/net/ethernet/netronome/nfp/nfp_main.c index 46b76d5a726c..152283d7e59c 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_main.c | |||
@@ -240,7 +240,6 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf) | |||
240 | return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs); | 240 | return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs); |
241 | 241 | ||
242 | pf->limit_vfs = ~0; | 242 | pf->limit_vfs = ~0; |
243 | pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */ | ||
244 | /* Allow any setting for backwards compatibility if symbol not found */ | 243 | /* Allow any setting for backwards compatibility if symbol not found */ |
245 | if (err == -ENOENT) | 244 | if (err == -ENOENT) |
246 | return 0; | 245 | return 0; |
@@ -668,7 +667,7 @@ static int nfp_pci_probe(struct pci_dev *pdev, | |||
668 | 667 | ||
669 | err = nfp_net_pci_probe(pf); | 668 | err = nfp_net_pci_probe(pf); |
670 | if (err) | 669 | if (err) |
671 | goto err_sriov_unlimit; | 670 | goto err_fw_unload; |
672 | 671 | ||
673 | err = nfp_hwmon_register(pf); | 672 | err = nfp_hwmon_register(pf); |
674 | if (err) { | 673 | if (err) { |
@@ -680,8 +679,6 @@ static int nfp_pci_probe(struct pci_dev *pdev, | |||
680 | 679 | ||
681 | err_net_remove: | 680 | err_net_remove: |
682 | nfp_net_pci_remove(pf); | 681 | nfp_net_pci_remove(pf); |
683 | err_sriov_unlimit: | ||
684 | pci_sriov_set_totalvfs(pf->pdev, 0); | ||
685 | err_fw_unload: | 682 | err_fw_unload: |
686 | kfree(pf->rtbl); | 683 | kfree(pf->rtbl); |
687 | nfp_mip_close(pf->mip); | 684 | nfp_mip_close(pf->mip); |
@@ -715,7 +712,6 @@ static void nfp_pci_remove(struct pci_dev *pdev) | |||
715 | nfp_hwmon_unregister(pf); | 712 | nfp_hwmon_unregister(pf); |
716 | 713 | ||
717 | nfp_pcie_sriov_disable(pdev); | 714 | nfp_pcie_sriov_disable(pdev); |
718 | pci_sriov_set_totalvfs(pf->pdev, 0); | ||
719 | 715 | ||
720 | nfp_net_pci_remove(pf); | 716 | nfp_net_pci_remove(pf); |
721 | 717 | ||
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index 16f52c626b4b..91b0194240a5 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig | |||
@@ -58,7 +58,6 @@ config PCIE_DW_PLAT_HOST | |||
58 | depends on PCI && PCI_MSI_IRQ_DOMAIN | 58 | depends on PCI && PCI_MSI_IRQ_DOMAIN |
59 | select PCIE_DW_HOST | 59 | select PCIE_DW_HOST |
60 | select PCIE_DW_PLAT | 60 | select PCIE_DW_PLAT |
61 | default y | ||
62 | help | 61 | help |
63 | Enables support for the PCIe controller in the Designware IP to | 62 | Enables support for the PCIe controller in the Designware IP to |
64 | work in host mode. There are two instances of PCIe controller in | 63 | work in host mode. There are two instances of PCIe controller in |
diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index a1ebe9ed441f..20bb2564a6b3 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c | |||
@@ -355,11 +355,13 @@ static int faraday_pci_setup_cascaded_irq(struct faraday_pci *p) | |||
355 | irq = of_irq_get(intc, 0); | 355 | irq = of_irq_get(intc, 0); |
356 | if (irq <= 0) { | 356 | if (irq <= 0) { |
357 | dev_err(p->dev, "failed to get parent IRQ\n"); | 357 | dev_err(p->dev, "failed to get parent IRQ\n"); |
358 | of_node_put(intc); | ||
358 | return irq ?: -EINVAL; | 359 | return irq ?: -EINVAL; |
359 | } | 360 | } |
360 | 361 | ||
361 | p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX, | 362 | p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX, |
362 | &faraday_pci_irqdomain_ops, p); | 363 | &faraday_pci_irqdomain_ops, p); |
364 | of_node_put(intc); | ||
363 | if (!p->irqdomain) { | 365 | if (!p->irqdomain) { |
364 | dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n"); | 366 | dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n"); |
365 | return -EINVAL; | 367 | return -EINVAL; |
diff --git a/drivers/pci/controller/pcie-rcar.c b/drivers/pci/controller/pcie-rcar.c index 874d75c9ee4a..c8febb009454 100644 --- a/drivers/pci/controller/pcie-rcar.c +++ b/drivers/pci/controller/pcie-rcar.c | |||
@@ -680,7 +680,11 @@ static int rcar_pcie_phy_init_gen3(struct rcar_pcie *pcie) | |||
680 | if (err) | 680 | if (err) |
681 | return err; | 681 | return err; |
682 | 682 | ||
683 | return phy_power_on(pcie->phy); | 683 | err = phy_power_on(pcie->phy); |
684 | if (err) | ||
685 | phy_exit(pcie->phy); | ||
686 | |||
687 | return err; | ||
684 | } | 688 | } |
685 | 689 | ||
686 | static int rcar_msi_alloc(struct rcar_msi *chip) | 690 | static int rcar_msi_alloc(struct rcar_msi *chip) |
@@ -1165,7 +1169,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
1165 | if (rcar_pcie_hw_init(pcie)) { | 1169 | if (rcar_pcie_hw_init(pcie)) { |
1166 | dev_info(dev, "PCIe link down\n"); | 1170 | dev_info(dev, "PCIe link down\n"); |
1167 | err = -ENODEV; | 1171 | err = -ENODEV; |
1168 | goto err_clk_disable; | 1172 | goto err_phy_shutdown; |
1169 | } | 1173 | } |
1170 | 1174 | ||
1171 | data = rcar_pci_read_reg(pcie, MACSR); | 1175 | data = rcar_pci_read_reg(pcie, MACSR); |
@@ -1177,7 +1181,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
1177 | dev_err(dev, | 1181 | dev_err(dev, |
1178 | "failed to enable MSI support: %d\n", | 1182 | "failed to enable MSI support: %d\n", |
1179 | err); | 1183 | err); |
1180 | goto err_clk_disable; | 1184 | goto err_phy_shutdown; |
1181 | } | 1185 | } |
1182 | } | 1186 | } |
1183 | 1187 | ||
@@ -1191,6 +1195,12 @@ err_msi_teardown: | |||
1191 | if (IS_ENABLED(CONFIG_PCI_MSI)) | 1195 | if (IS_ENABLED(CONFIG_PCI_MSI)) |
1192 | rcar_pcie_teardown_msi(pcie); | 1196 | rcar_pcie_teardown_msi(pcie); |
1193 | 1197 | ||
1198 | err_phy_shutdown: | ||
1199 | if (pcie->phy) { | ||
1200 | phy_power_off(pcie->phy); | ||
1201 | phy_exit(pcie->phy); | ||
1202 | } | ||
1203 | |||
1194 | err_clk_disable: | 1204 | err_clk_disable: |
1195 | clk_disable_unprepare(pcie->bus_clk); | 1205 | clk_disable_unprepare(pcie->bus_clk); |
1196 | 1206 | ||
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c index 6a4bbb5b3de0..fb32840ce8e6 100644 --- a/drivers/pci/controller/pcie-xilinx-nwl.c +++ b/drivers/pci/controller/pcie-xilinx-nwl.c | |||
@@ -559,7 +559,7 @@ static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie) | |||
559 | PCI_NUM_INTX, | 559 | PCI_NUM_INTX, |
560 | &legacy_domain_ops, | 560 | &legacy_domain_ops, |
561 | pcie); | 561 | pcie); |
562 | 562 | of_node_put(legacy_intc_node); | |
563 | if (!pcie->legacy_irq_domain) { | 563 | if (!pcie->legacy_irq_domain) { |
564 | dev_err(dev, "failed to create IRQ domain\n"); | 564 | dev_err(dev, "failed to create IRQ domain\n"); |
565 | return -ENOMEM; | 565 | return -ENOMEM; |
diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c index b110a3a814e3..7b1389d8e2a5 100644 --- a/drivers/pci/controller/pcie-xilinx.c +++ b/drivers/pci/controller/pcie-xilinx.c | |||
@@ -509,6 +509,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) | |||
509 | port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, | 509 | port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, |
510 | &intx_domain_ops, | 510 | &intx_domain_ops, |
511 | port); | 511 | port); |
512 | of_node_put(pcie_intc_node); | ||
512 | if (!port->leg_domain) { | 513 | if (!port->leg_domain) { |
513 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); | 514 | dev_err(dev, "Failed to get a INTx IRQ domain\n"); |
514 | return -ENODEV; | 515 | return -ENODEV; |
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 523a8cab3bfb..bf53fad636a5 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c | |||
@@ -145,10 +145,10 @@ EXPORT_SYMBOL_GPL(pci_epf_alloc_space); | |||
145 | */ | 145 | */ |
146 | void pci_epf_unregister_driver(struct pci_epf_driver *driver) | 146 | void pci_epf_unregister_driver(struct pci_epf_driver *driver) |
147 | { | 147 | { |
148 | struct config_group *group; | 148 | struct config_group *group, *tmp; |
149 | 149 | ||
150 | mutex_lock(&pci_epf_mutex); | 150 | mutex_lock(&pci_epf_mutex); |
151 | list_for_each_entry(group, &driver->epf_group, group_entry) | 151 | list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry) |
152 | pci_ep_cfs_remove_epf_group(group); | 152 | pci_ep_cfs_remove_epf_group(group); |
153 | list_del(&driver->epf_group); | 153 | list_del(&driver->epf_group); |
154 | mutex_unlock(&pci_epf_mutex); | 154 | mutex_unlock(&pci_epf_mutex); |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index d0d73dbbd5ca..0f04ae648cf1 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -575,6 +575,22 @@ void pci_iov_release(struct pci_dev *dev) | |||
575 | } | 575 | } |
576 | 576 | ||
577 | /** | 577 | /** |
578 | * pci_iov_remove - clean up SR-IOV state after PF driver is detached | ||
579 | * @dev: the PCI device | ||
580 | */ | ||
581 | void pci_iov_remove(struct pci_dev *dev) | ||
582 | { | ||
583 | struct pci_sriov *iov = dev->sriov; | ||
584 | |||
585 | if (!dev->is_physfn) | ||
586 | return; | ||
587 | |||
588 | iov->driver_max_VFs = iov->total_VFs; | ||
589 | if (iov->num_VFs) | ||
590 | pci_warn(dev, "driver left SR-IOV enabled after remove\n"); | ||
591 | } | ||
592 | |||
593 | /** | ||
578 | * pci_iov_update_resource - update a VF BAR | 594 | * pci_iov_update_resource - update a VF BAR |
579 | * @dev: the PCI device | 595 | * @dev: the PCI device |
580 | * @resno: the resource number | 596 | * @resno: the resource number |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index c125d53033c6..6792292b5fc7 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -445,6 +445,7 @@ static int pci_device_remove(struct device *dev) | |||
445 | } | 445 | } |
446 | pcibios_free_irq(pci_dev); | 446 | pcibios_free_irq(pci_dev); |
447 | pci_dev->driver = NULL; | 447 | pci_dev->driver = NULL; |
448 | pci_iov_remove(pci_dev); | ||
448 | } | 449 | } |
449 | 450 | ||
450 | /* Undo the runtime PM settings in local_pci_probe() */ | 451 | /* Undo the runtime PM settings in local_pci_probe() */ |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index c358e7a07f3f..882f1f9596df 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -311,6 +311,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) | |||
311 | #ifdef CONFIG_PCI_IOV | 311 | #ifdef CONFIG_PCI_IOV |
312 | int pci_iov_init(struct pci_dev *dev); | 312 | int pci_iov_init(struct pci_dev *dev); |
313 | void pci_iov_release(struct pci_dev *dev); | 313 | void pci_iov_release(struct pci_dev *dev); |
314 | void pci_iov_remove(struct pci_dev *dev); | ||
314 | void pci_iov_update_resource(struct pci_dev *dev, int resno); | 315 | void pci_iov_update_resource(struct pci_dev *dev, int resno); |
315 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); | 316 | resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); |
316 | void pci_restore_iov_state(struct pci_dev *dev); | 317 | void pci_restore_iov_state(struct pci_dev *dev); |
@@ -325,6 +326,9 @@ static inline void pci_iov_release(struct pci_dev *dev) | |||
325 | 326 | ||
326 | { | 327 | { |
327 | } | 328 | } |
329 | static inline void pci_iov_remove(struct pci_dev *dev) | ||
330 | { | ||
331 | } | ||
328 | static inline void pci_restore_iov_state(struct pci_dev *dev) | 332 | static inline void pci_restore_iov_state(struct pci_dev *dev) |
329 | { | 333 | { |
330 | } | 334 | } |