From: Greg Kroah-Hartman Date: Sun, 16 Oct 2022 11:24:32 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v5.4.219~144 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0d22f0000f9fef4fef9ad36e10303d18412dbd5f;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: pci-sanitise-firmware-bar-assignments-behind-a-pci-pci-bridge.patch --- diff --git a/queue-4.9/pci-sanitise-firmware-bar-assignments-behind-a-pci-pci-bridge.patch b/queue-4.9/pci-sanitise-firmware-bar-assignments-behind-a-pci-pci-bridge.patch new file mode 100644 index 00000000000..f028d6639c5 --- /dev/null +++ b/queue-4.9/pci-sanitise-firmware-bar-assignments-behind-a-pci-pci-bridge.patch @@ -0,0 +1,102 @@ +From 0e32818397426a688f598f35d3bc762eca6d7592 Mon Sep 17 00:00:00 2001 +From: "Maciej W. Rozycki" +Date: Wed, 21 Sep 2022 20:49:16 +0100 +Subject: PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge + +From: Maciej W. Rozycki + +commit 0e32818397426a688f598f35d3bc762eca6d7592 upstream. + +When pci_assign_resource() is unable to assign resources to a BAR, it uses +pci_revert_fw_address() to fall back to a firmware assignment (if any). +Previously pci_revert_fw_address() assumed all addresses could reach the +device, but this is not true if the device is below a bridge that only +forwards addresses within its windows. + +This problem was observed on a Tyan Tomcat IV S1564D system where the BIOS +did not assign valid addresses to several bridges and USB devices: + + pci 0000:00:11.0: PCI-to-PCIe bridge to [bus 01-ff] + pci 0000:00:11.0: bridge window [io 0xe000-0xefff] + pci 0000:01:00.0: PCIe Upstream Port to [bus 02-ff] + pci 0000:01:00.0: bridge window [io 0x0000-0x0fff] # unreachable + pci 0000:02:02.0: PCIe Downstream Port to [bus 05-ff] + pci 0000:02:02.0: bridge window [io 0x0000-0x0fff] # unreachable + pci 0000:05:00.0: PCIe-to-PCI bridge to [bus 06-ff] + pci 0000:05:00.0: bridge window [io 0x0000-0x0fff] # unreachable + pci 0000:06:08.0: USB UHCI 1.1 + pci 0000:06:08.0: BAR 4: [io 0xfce0-0xfcff] # unreachable + pci 0000:06:08.1: USB UHCI 1.1 + pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] # unreachable + pci 0000:06:08.0: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window + pci 0000:06:08.1: can't claim BAR 4 [io 0xfce0-0xfcff]: no compatible bridge window + +During the first pass of assigning unassigned resources, there was not +enough I/O space available, so we couldn't assign the 06:08.0 BAR and +reverted to the firmware assignment (still unreachable). Reverting the +06:08.1 assignment failed because it conflicted with 06:08.0: + + pci 0000:00:11.0: bridge window [io 0xe000-0xefff] + pci 0000:01:00.0: no space for bridge window [io size 0x2000] + pci 0000:02:02.0: no space for bridge window [io size 0x1000] + pci 0000:05:00.0: no space for bridge window [io size 0x1000] + pci 0000:06:08.0: BAR 4: no space for [io size 0x0020] + pci 0000:06:08.0: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] + pci 0000:06:08.1: BAR 4: no space for [io size 0x0020] + pci 0000:06:08.1: BAR 4: trying firmware assignment [io 0xfce0-0xfcff] + pci 0000:06:08.1: BAR 4: [io 0xfce0-0xfcff] conflicts with 0000:06:08.0 [io 0xfce0-0xfcff] + +A subsequent pass assigned valid bridge windows and a valid 06:08.1 BAR, +but left the 06:08.0 BAR alone, so the UHCI device was still unusable: + + pci 0000:00:11.0: bridge window [io 0xe000-0xefff] released + pci 0000:00:11.0: bridge window [io 0x1000-0x2fff] # reassigned + pci 0000:01:00.0: bridge window [io 0x1000-0x2fff] # reassigned + pci 0000:02:02.0: bridge window [io 0x2000-0x2fff] # reassigned + pci 0000:05:00.0: bridge window [io 0x2000-0x2fff] # reassigned + pci 0000:06:08.0: BAR 4: assigned [io 0xfce0-0xfcff] # left alone + pci 0000:06:08.1: BAR 4: assigned [io 0x2000-0x201f] + ... + uhci_hcd 0000:06:08.0: host system error, PCI problems? + uhci_hcd 0000:06:08.0: host controller process error, something bad happened! + uhci_hcd 0000:06:08.0: host controller halted, very bad! + uhci_hcd 0000:06:08.0: HCRESET not completed yet! + uhci_hcd 0000:06:08.0: HC died; cleaning up + +If the address assigned by firmware is not reachable because it's not +within upstream bridge windows, fail instead of assigning the unusable +address from firmware. + +[bhelgaas: commit log, use pci_upstream_bridge()] +Link: https://bugzilla.kernel.org/show_bug.cgi?id=16263 +Link: https://lore.kernel.org/r/alpine.DEB.2.21.2203012338460.46819@angie.orcam.me.uk +Link: https://lore.kernel.org/r/alpine.DEB.2.21.2209211921250.29493@angie.orcam.me.uk +Fixes: 58c84eda0756 ("PCI: fall back to original BIOS BAR addresses") +Signed-off-by: Maciej W. Rozycki +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org # v2.6.35+ +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/setup-res.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/pci/setup-res.c ++++ b/drivers/pci/setup-res.c +@@ -214,6 +214,17 @@ static int pci_revert_fw_address(struct + + root = pci_find_parent_resource(dev, res); + if (!root) { ++ /* ++ * If dev is behind a bridge, accesses will only reach it ++ * if res is inside the relevant bridge window. ++ */ ++ if (pci_upstream_bridge(dev)) ++ return -ENXIO; ++ ++ /* ++ * On the root bus, assume the host bridge will forward ++ * everything. ++ */ + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + else diff --git a/queue-4.9/series b/queue-4.9/series index 925f981b4da..0bf347a2f8e 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -49,3 +49,4 @@ quota-check-next-prev-free-block-number-after-reading-from-quota-file.patch regulator-qcom_rpm-fix-circular-deferral-regression.patch parisc-fbdev-stifb-align-graphics-memory-size-to-4mb.patch um-cpuinfo-fix-a-warning-for-config_cpumask_offstack.patch +pci-sanitise-firmware-bar-assignments-behind-a-pci-pci-bridge.patch