--- /dev/null
+From ee8bdfb6568d86bb93f55f8d99c4c643e77304ee Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Mon, 2 Oct 2017 15:08:40 +0100
+Subject: PCI/ASPM: Deal with missing root ports in link state handling
+
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit ee8bdfb6568d86bb93f55f8d99c4c643e77304ee upstream.
+
+Even though it is unconventional, some PCIe host implementations omit the
+root ports entirely, and simply consist of a host bridge (which is not
+modeled as a device in the PCI hierarchy) and a link.
+
+When the downstream device is an endpoint, our current code does not seem
+to mind this unusual configuration. However, when PCIe switches are
+involved, the ASPM code assumes that any downstream switch port has a
+parent, and blindly dereferences the bus->parent->self field of the pci_dev
+struct to chain the downstream link state to the link state of the root
+port. Given that the root port is missing, the link is not modeled at all,
+and nor is the link state, and attempting to access it results in a NULL
+pointer dereference and a crash.
+
+Avoid this by allowing the link state chain to terminate at the downstream
+port if no root port exists.
+
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/pcie/aspm.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/pcie/aspm.c
++++ b/drivers/pci/pcie/aspm.c
+@@ -526,10 +526,14 @@ static struct pcie_link_state *alloc_pci
+
+ /*
+ * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe
+- * hierarchies.
++ * hierarchies. Note that some PCIe host implementations omit
++ * the root ports entirely, in which case a downstream port on
++ * a switch may become the root of the link state chain for all
++ * its subordinate endpoints.
+ */
+ if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
+- pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE) {
++ pci_pcie_type(pdev) == PCI_EXP_TYPE_PCIE_BRIDGE ||
++ !pdev->bus->parent->self) {
+ link->root = link;
+ } else {
+ struct pcie_link_state *parent;