summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill XIE <persmule@hardenedlinux.org>2022-08-04 21:52:05 +0800
committerMartin L Roth <gaumless@gmail.com>2022-08-07 19:49:35 +0000
commit385e43274e515b1d235540323a4907514df765fd (patch)
treeaefd04ea29eeb02cf854d189a77343cea80f470f
parent02f2b193840f68c41a91380be0dd4f435ab2f339 (diff)
downloadcoreboot-385e43274e515b1d235540323a4907514df765fd.tar.gz
coreboot-385e43274e515b1d235540323a4907514df765fd.tar.bz2
coreboot-385e43274e515b1d235540323a4907514df765fd.zip
pciexp_device: Handle unsupported requests in pciexp_get_ext_cap_offset()
Looking into pciexp_get_ext_cap_offset() it seems a little hackish and prone to endless loops. Either it should limit the loop or bail out when pci_read_config32() returns 0xffffffff, meaning "Unsupported Requests". This commit fixes an endless loop when the queried PCIe device is downstream of a legacy PCI bus which doesn't support extended config space, thus pci_read_config32() will return 0xffffffff, for example, the combination below with CONFIG_PCIEXP_SUPPORT_RESIZABLE_BARS enabled. TEST=Build and boot to OS in ASUS P8C WS with the following peripherals and CONFIG_PCIEXP_SUPPORT_RESIZABLE_BARS enabled: 00:1c.4 PCI bridge [0604]: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 5 [8086:1e18] (rev c4) 00:1c.4/00.0 SATA controller [0106]: Marvell Technology Group Ltd. 88SE9170 PCIe 2.0 x1 2-port SATA 6 Gb/s Controller [1b4b:9170] (rev 13) 00:1e.0 PCI bridge [0604]: Intel Corporation 82801 PCI Bridge [8086:244e] (rev a4) 00:1e.0/00.0 PCI bridge [0604]: PLX Technology, Inc. PEX 8111 PCI Express-to-PCI Bridge [10b5:8111] (rev 21) 00:1e.0/03.0 FireWire (IEEE 1394) [0c00]: VIA Technologies, Inc. VT6306/7/8 [Fire II(M)] IEEE 1394 OHCI Controller [1106:3044] (rev c0) 00:1e.0/00.0/00.0 Network controller [0280]: Qualcomm Atheros AR93xx Wireless Network Adapter [168c:0030] (rev 01) with 00:1c.4/00.0 being successfully tuned with pciexp_tune_dev(), and 00: 1e.0/00.0/00.0 not tuned as expected. Change-Id: Ibb92548c47288b40e851fcc0a8a37937e8bdbf3c Signed-off-by: Bill XIE <persmule@hardenedlinux.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/66439 Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com> Reviewed-by: Martin L Roth <gaumless@gmail.com>
-rw-r--r--src/device/pciexp_device.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/device/pciexp_device.c b/src/device/pciexp_device.c
index c03c224003d6..ac4e668f08a3 100644
--- a/src/device/pciexp_device.c
+++ b/src/device/pciexp_device.c
@@ -15,6 +15,9 @@ static unsigned int pciexp_get_ext_cap_offset(const struct device *dev, unsigned
unsigned int next_cap_offset, this_cap, cafe;
do {
this_cap = pci_read_config32(dev, this_cap_offset);
+ /* Bail out when this request is unsupported */
+ if (this_cap == 0xffffffff)
+ break;
cafe = pci_read_config32(dev, this_cap_offset + 4);
if ((this_cap & 0xffff) == cap) {
return this_cap_offset;