Commit 8979319f authored by Linus Torvalds's avatar Linus Torvalds

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
parents b2d44d14 83235822
...@@ -240,7 +240,6 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf) ...@@ -240,7 +240,6 @@ static int nfp_pcie_sriov_read_nfd_limit(struct nfp_pf *pf)
return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs); return pci_sriov_set_totalvfs(pf->pdev, pf->limit_vfs);
pf->limit_vfs = ~0; pf->limit_vfs = ~0;
pci_sriov_set_totalvfs(pf->pdev, 0); /* 0 is unset */
/* Allow any setting for backwards compatibility if symbol not found */ /* Allow any setting for backwards compatibility if symbol not found */
if (err == -ENOENT) if (err == -ENOENT)
return 0; return 0;
...@@ -668,7 +667,7 @@ static int nfp_pci_probe(struct pci_dev *pdev, ...@@ -668,7 +667,7 @@ static int nfp_pci_probe(struct pci_dev *pdev,
err = nfp_net_pci_probe(pf); err = nfp_net_pci_probe(pf);
if (err) if (err)
goto err_sriov_unlimit; goto err_fw_unload;
err = nfp_hwmon_register(pf); err = nfp_hwmon_register(pf);
if (err) { if (err) {
...@@ -680,8 +679,6 @@ static int nfp_pci_probe(struct pci_dev *pdev, ...@@ -680,8 +679,6 @@ static int nfp_pci_probe(struct pci_dev *pdev,
err_net_remove: err_net_remove:
nfp_net_pci_remove(pf); nfp_net_pci_remove(pf);
err_sriov_unlimit:
pci_sriov_set_totalvfs(pf->pdev, 0);
err_fw_unload: err_fw_unload:
kfree(pf->rtbl); kfree(pf->rtbl);
nfp_mip_close(pf->mip); nfp_mip_close(pf->mip);
...@@ -715,7 +712,6 @@ static void nfp_pci_remove(struct pci_dev *pdev) ...@@ -715,7 +712,6 @@ static void nfp_pci_remove(struct pci_dev *pdev)
nfp_hwmon_unregister(pf); nfp_hwmon_unregister(pf);
nfp_pcie_sriov_disable(pdev); nfp_pcie_sriov_disable(pdev);
pci_sriov_set_totalvfs(pf->pdev, 0);
nfp_net_pci_remove(pf); nfp_net_pci_remove(pf);
......
...@@ -58,7 +58,6 @@ config PCIE_DW_PLAT_HOST ...@@ -58,7 +58,6 @@ config PCIE_DW_PLAT_HOST
depends on PCI && PCI_MSI_IRQ_DOMAIN depends on PCI && PCI_MSI_IRQ_DOMAIN
select PCIE_DW_HOST select PCIE_DW_HOST
select PCIE_DW_PLAT select PCIE_DW_PLAT
default y
help help
Enables support for the PCIe controller in the Designware IP to Enables support for the PCIe controller in the Designware IP to
work in host mode. There are two instances of PCIe controller in work in host mode. There are two instances of PCIe controller in
......
...@@ -355,11 +355,13 @@ static int faraday_pci_setup_cascaded_irq(struct faraday_pci *p) ...@@ -355,11 +355,13 @@ static int faraday_pci_setup_cascaded_irq(struct faraday_pci *p)
irq = of_irq_get(intc, 0); irq = of_irq_get(intc, 0);
if (irq <= 0) { if (irq <= 0) {
dev_err(p->dev, "failed to get parent IRQ\n"); dev_err(p->dev, "failed to get parent IRQ\n");
of_node_put(intc);
return irq ?: -EINVAL; return irq ?: -EINVAL;
} }
p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX, p->irqdomain = irq_domain_add_linear(intc, PCI_NUM_INTX,
&faraday_pci_irqdomain_ops, p); &faraday_pci_irqdomain_ops, p);
of_node_put(intc);
if (!p->irqdomain) { if (!p->irqdomain) {
dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n"); dev_err(p->dev, "failed to create Gemini PCI IRQ domain\n");
return -EINVAL; return -EINVAL;
......
...@@ -680,7 +680,11 @@ static int rcar_pcie_phy_init_gen3(struct rcar_pcie *pcie) ...@@ -680,7 +680,11 @@ static int rcar_pcie_phy_init_gen3(struct rcar_pcie *pcie)
if (err) if (err)
return err; return err;
return phy_power_on(pcie->phy); err = phy_power_on(pcie->phy);
if (err)
phy_exit(pcie->phy);
return err;
} }
static int rcar_msi_alloc(struct rcar_msi *chip) static int rcar_msi_alloc(struct rcar_msi *chip)
...@@ -1165,7 +1169,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) ...@@ -1165,7 +1169,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
if (rcar_pcie_hw_init(pcie)) { if (rcar_pcie_hw_init(pcie)) {
dev_info(dev, "PCIe link down\n"); dev_info(dev, "PCIe link down\n");
err = -ENODEV; err = -ENODEV;
goto err_clk_disable; goto err_phy_shutdown;
} }
data = rcar_pci_read_reg(pcie, MACSR); data = rcar_pci_read_reg(pcie, MACSR);
...@@ -1177,7 +1181,7 @@ static int rcar_pcie_probe(struct platform_device *pdev) ...@@ -1177,7 +1181,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
dev_err(dev, dev_err(dev,
"failed to enable MSI support: %d\n", "failed to enable MSI support: %d\n",
err); err);
goto err_clk_disable; goto err_phy_shutdown;
} }
} }
...@@ -1191,6 +1195,12 @@ static int rcar_pcie_probe(struct platform_device *pdev) ...@@ -1191,6 +1195,12 @@ static int rcar_pcie_probe(struct platform_device *pdev)
if (IS_ENABLED(CONFIG_PCI_MSI)) if (IS_ENABLED(CONFIG_PCI_MSI))
rcar_pcie_teardown_msi(pcie); rcar_pcie_teardown_msi(pcie);
err_phy_shutdown:
if (pcie->phy) {
phy_power_off(pcie->phy);
phy_exit(pcie->phy);
}
err_clk_disable: err_clk_disable:
clk_disable_unprepare(pcie->bus_clk); clk_disable_unprepare(pcie->bus_clk);
......
...@@ -559,7 +559,7 @@ static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie) ...@@ -559,7 +559,7 @@ static int nwl_pcie_init_irq_domain(struct nwl_pcie *pcie)
PCI_NUM_INTX, PCI_NUM_INTX,
&legacy_domain_ops, &legacy_domain_ops,
pcie); pcie);
of_node_put(legacy_intc_node);
if (!pcie->legacy_irq_domain) { if (!pcie->legacy_irq_domain) {
dev_err(dev, "failed to create IRQ domain\n"); dev_err(dev, "failed to create IRQ domain\n");
return -ENOMEM; return -ENOMEM;
......
...@@ -509,6 +509,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) ...@@ -509,6 +509,7 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX, port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
&intx_domain_ops, &intx_domain_ops,
port); port);
of_node_put(pcie_intc_node);
if (!port->leg_domain) { if (!port->leg_domain) {
dev_err(dev, "Failed to get a INTx IRQ domain\n"); dev_err(dev, "Failed to get a INTx IRQ domain\n");
return -ENODEV; return -ENODEV;
......
...@@ -145,10 +145,10 @@ EXPORT_SYMBOL_GPL(pci_epf_alloc_space); ...@@ -145,10 +145,10 @@ EXPORT_SYMBOL_GPL(pci_epf_alloc_space);
*/ */
void pci_epf_unregister_driver(struct pci_epf_driver *driver) void pci_epf_unregister_driver(struct pci_epf_driver *driver)
{ {
struct config_group *group; struct config_group *group, *tmp;
mutex_lock(&pci_epf_mutex); mutex_lock(&pci_epf_mutex);
list_for_each_entry(group, &driver->epf_group, group_entry) list_for_each_entry_safe(group, tmp, &driver->epf_group, group_entry)
pci_ep_cfs_remove_epf_group(group); pci_ep_cfs_remove_epf_group(group);
list_del(&driver->epf_group); list_del(&driver->epf_group);
mutex_unlock(&pci_epf_mutex); mutex_unlock(&pci_epf_mutex);
......
...@@ -574,6 +574,22 @@ void pci_iov_release(struct pci_dev *dev) ...@@ -574,6 +574,22 @@ void pci_iov_release(struct pci_dev *dev)
sriov_release(dev); sriov_release(dev);
} }
/**
* pci_iov_remove - clean up SR-IOV state after PF driver is detached
* @dev: the PCI device
*/
void pci_iov_remove(struct pci_dev *dev)
{
struct pci_sriov *iov = dev->sriov;
if (!dev->is_physfn)
return;
iov->driver_max_VFs = iov->total_VFs;
if (iov->num_VFs)
pci_warn(dev, "driver left SR-IOV enabled after remove\n");
}
/** /**
* pci_iov_update_resource - update a VF BAR * pci_iov_update_resource - update a VF BAR
* @dev: the PCI device * @dev: the PCI device
......
...@@ -445,6 +445,7 @@ static int pci_device_remove(struct device *dev) ...@@ -445,6 +445,7 @@ static int pci_device_remove(struct device *dev)
} }
pcibios_free_irq(pci_dev); pcibios_free_irq(pci_dev);
pci_dev->driver = NULL; pci_dev->driver = NULL;
pci_iov_remove(pci_dev);
} }
/* Undo the runtime PM settings in local_pci_probe() */ /* Undo the runtime PM settings in local_pci_probe() */
......
...@@ -311,6 +311,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev) ...@@ -311,6 +311,7 @@ static inline void pci_restore_ats_state(struct pci_dev *dev)
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
int pci_iov_init(struct pci_dev *dev); int pci_iov_init(struct pci_dev *dev);
void pci_iov_release(struct pci_dev *dev); void pci_iov_release(struct pci_dev *dev);
void pci_iov_remove(struct pci_dev *dev);
void pci_iov_update_resource(struct pci_dev *dev, int resno); void pci_iov_update_resource(struct pci_dev *dev, int resno);
resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno); resource_size_t pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
void pci_restore_iov_state(struct pci_dev *dev); void pci_restore_iov_state(struct pci_dev *dev);
...@@ -323,6 +324,9 @@ static inline int pci_iov_init(struct pci_dev *dev) ...@@ -323,6 +324,9 @@ static inline int pci_iov_init(struct pci_dev *dev)
} }
static inline void pci_iov_release(struct pci_dev *dev) static inline void pci_iov_release(struct pci_dev *dev)
{
}
static inline void pci_iov_remove(struct pci_dev *dev)
{ {
} }
static inline void pci_restore_iov_state(struct pci_dev *dev) static inline void pci_restore_iov_state(struct pci_dev *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment