Commit 0cbb0b92 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v4.5-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:
 "These are some Renesas binding updates for PCI host controllers, a
  Broadcom fix for a regression we added in v4.5-rc1, and a fix for an
  AER use-after-free problem that can cause memory corruption.

  Summary:

  AER:
    Flush workqueue on device remove to avoid use-after-free (Sebastian Andrzej Siewior)

  Broadcom iProc host bridge driver:
    Allow multiple devices except on PAXC (Ray Jui)

  Renesas R-Car host bridge driver:
    Add gen2 device tree support for r8a7793 (Simon Horman)
    Add device tree support for r8a7793 (Simon Horman)"

* tag 'pci-v4.5-fixes-1' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  PCI: rcar: Add device tree support for r8a7793
  PCI: rcar: Add gen2 device tree support for r8a7793
  PCI: iproc: Allow multiple devices except on PAXC
  PCI/AER: Flush workqueue on device remove to avoid use-after-free
parents 29f1bf34 0cf1337e
...@@ -8,6 +8,7 @@ OHCI and EHCI controllers. ...@@ -8,6 +8,7 @@ OHCI and EHCI controllers.
Required properties: Required properties:
- compatible: "renesas,pci-r8a7790" for the R8A7790 SoC; - compatible: "renesas,pci-r8a7790" for the R8A7790 SoC;
"renesas,pci-r8a7791" for the R8A7791 SoC; "renesas,pci-r8a7791" for the R8A7791 SoC;
"renesas,pci-r8a7793" for the R8A7793 SoC;
"renesas,pci-r8a7794" for the R8A7794 SoC; "renesas,pci-r8a7794" for the R8A7794 SoC;
"renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device "renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device
......
...@@ -4,6 +4,7 @@ Required properties: ...@@ -4,6 +4,7 @@ Required properties:
compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC; compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC;
"renesas,pcie-r8a7790" for the R8A7790 SoC; "renesas,pcie-r8a7790" for the R8A7790 SoC;
"renesas,pcie-r8a7791" for the R8A7791 SoC; "renesas,pcie-r8a7791" for the R8A7791 SoC;
"renesas,pcie-r8a7793" for the R8A7793 SoC;
"renesas,pcie-r8a7795" for the R8A7795 SoC; "renesas,pcie-r8a7795" for the R8A7795 SoC;
"renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device. "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device.
......
...@@ -64,7 +64,6 @@ ...@@ -64,7 +64,6 @@
#define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT) #define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT)
#define MAX_NUM_OB_WINDOWS 2 #define MAX_NUM_OB_WINDOWS 2
#define MAX_NUM_PAXC_PF 4
#define IPROC_PCIE_REG_INVALID 0xffff #define IPROC_PCIE_REG_INVALID 0xffff
...@@ -170,20 +169,6 @@ static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie, ...@@ -170,20 +169,6 @@ static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
writel(val, pcie->base + offset + (window * 8)); writel(val, pcie->base + offset + (window * 8));
} }
static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie,
unsigned int slot,
unsigned int fn)
{
if (slot > 0)
return false;
/* PAXC can only support limited number of functions */
if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF)
return false;
return true;
}
/** /**
* Note access to the configuration registers are protected at the higher layer * Note access to the configuration registers are protected at the higher layer
* by 'pci_lock' in drivers/pci/access.c * by 'pci_lock' in drivers/pci/access.c
...@@ -199,11 +184,11 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, ...@@ -199,11 +184,11 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
u32 val; u32 val;
u16 offset; u16 offset;
if (!iproc_pcie_device_is_valid(pcie, slot, fn))
return NULL;
/* root complex access */ /* root complex access */
if (busno == 0) { if (busno == 0) {
if (slot > 0 || fn > 0)
return NULL;
iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR, iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
where & CFG_IND_ADDR_MASK); where & CFG_IND_ADDR_MASK);
offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA); offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA);
...@@ -213,6 +198,14 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus, ...@@ -213,6 +198,14 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
return (pcie->base + offset); return (pcie->base + offset);
} }
/*
* PAXC is connected to an internally emulated EP within the SoC. It
* allows only one device.
*/
if (pcie->type == IPROC_PCIE_PAXC)
if (slot > 0)
return NULL;
/* EP device access */ /* EP device access */
val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
(slot << CFG_ADDR_DEV_NUM_SHIFT) | (slot << CFG_ADDR_DEV_NUM_SHIFT) |
......
...@@ -262,7 +262,6 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev) ...@@ -262,7 +262,6 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
rpc->rpd = dev; rpc->rpd = dev;
INIT_WORK(&rpc->dpc_handler, aer_isr); INIT_WORK(&rpc->dpc_handler, aer_isr);
mutex_init(&rpc->rpc_mutex); mutex_init(&rpc->rpc_mutex);
init_waitqueue_head(&rpc->wait_release);
/* Use PCIe bus function to store rpc into PCIe device */ /* Use PCIe bus function to store rpc into PCIe device */
set_service_data(dev, rpc); set_service_data(dev, rpc);
...@@ -285,8 +284,7 @@ static void aer_remove(struct pcie_device *dev) ...@@ -285,8 +284,7 @@ static void aer_remove(struct pcie_device *dev)
if (rpc->isr) if (rpc->isr)
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx); flush_work(&rpc->dpc_handler);
aer_disable_rootport(rpc); aer_disable_rootport(rpc);
kfree(rpc); kfree(rpc);
set_service_data(dev, NULL); set_service_data(dev, NULL);
......
...@@ -72,7 +72,6 @@ struct aer_rpc { ...@@ -72,7 +72,6 @@ struct aer_rpc {
* recovery on the same * recovery on the same
* root port hierarchy * root port hierarchy
*/ */
wait_queue_head_t wait_release;
}; };
struct aer_broadcast_data { struct aer_broadcast_data {
......
...@@ -811,8 +811,6 @@ void aer_isr(struct work_struct *work) ...@@ -811,8 +811,6 @@ void aer_isr(struct work_struct *work)
while (get_e_source(rpc, &e_src)) while (get_e_source(rpc, &e_src))
aer_isr_one_error(p_device, &e_src); aer_isr_one_error(p_device, &e_src);
mutex_unlock(&rpc->rpc_mutex); mutex_unlock(&rpc->rpc_mutex);
wake_up(&rpc->wait_release);
} }
/** /**
......
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