Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cbb0b92 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ OHCI and EHCI controllers.
Required properties:
- compatible: "renesas,pci-r8a7790" for the R8A7790 SoC;
	      "renesas,pci-r8a7791" for the R8A7791 SoC;
	      "renesas,pci-r8a7793" for the R8A7793 SoC;
	      "renesas,pci-r8a7794" for the R8A7794 SoC;
	      "renesas,pci-rcar-gen2" for a generic R-Car Gen2 compatible device

+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ Required properties:
compatible: "renesas,pcie-r8a7779" for the R8A7779 SoC;
	    "renesas,pcie-r8a7790" for the R8A7790 SoC;
	    "renesas,pcie-r8a7791" for the R8A7791 SoC;
	    "renesas,pcie-r8a7793" for the R8A7793 SoC;
	    "renesas,pcie-r8a7795" for the R8A7795 SoC;
	    "renesas,pcie-rcar-gen2" for a generic R-Car Gen2 compatible device.

+11 −18
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@
#define OARR_SIZE_CFG                BIT(OARR_SIZE_CFG_SHIFT)

#define MAX_NUM_OB_WINDOWS           2
#define MAX_NUM_PAXC_PF              4

#define IPROC_PCIE_REG_INVALID 0xffff

@@ -170,20 +169,6 @@ static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie,
	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
 * by 'pci_lock' in drivers/pci/access.c
@@ -199,11 +184,11 @@ static void __iomem *iproc_pcie_map_cfg_bus(struct pci_bus *bus,
	u32 val;
	u16 offset;

	if (!iproc_pcie_device_is_valid(pcie, slot, fn))
		return NULL;

	/* root complex access */
	if (busno == 0) {
		if (slot > 0 || fn > 0)
			return NULL;

		iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR,
				     where & CFG_IND_ADDR_MASK);
		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,
			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 */
	val = (busno << CFG_ADDR_BUS_NUM_SHIFT) |
		(slot << CFG_ADDR_DEV_NUM_SHIFT) |
+1 −3
Original line number Diff line number Diff line
@@ -262,7 +262,6 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
	rpc->rpd = dev;
	INIT_WORK(&rpc->dpc_handler, aer_isr);
	mutex_init(&rpc->rpc_mutex);
	init_waitqueue_head(&rpc->wait_release);

	/* Use PCIe bus function to store rpc into PCIe device */
	set_service_data(dev, rpc);
@@ -285,8 +284,7 @@ static void aer_remove(struct pcie_device *dev)
		if (rpc->isr)
			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);
		kfree(rpc);
		set_service_data(dev, NULL);
+0 −1
Original line number Diff line number Diff line
@@ -72,7 +72,6 @@ struct aer_rpc {
					 * recovery on the same
					 * root port hierarchy
					 */
	wait_queue_head_t wait_release;
};

struct aer_broadcast_data {
Loading