Skip to content

Commit 6ba2c03

Browse files
committed
pci_find_cap_method(): limit number of iterations for finding a capability
Powered down device might return 0xff of extended config registers reads, causing loop. PR: 283815 Reviewed by: imp Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D48348
1 parent e6d40f9 commit 6ba2c03

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

sys/dev/pci/pci.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,6 +1519,7 @@ pci_find_cap_method(device_t dev, device_t child, int capability,
15191519
pcicfgregs *cfg = &dinfo->cfg;
15201520
uint32_t status;
15211521
uint8_t ptr;
1522+
int cnt;
15221523

15231524
/*
15241525
* Check the CAP_LIST bit of the PCI status register first.
@@ -1545,9 +1546,11 @@ pci_find_cap_method(device_t dev, device_t child, int capability,
15451546
ptr = pci_read_config(child, ptr, 1);
15461547

15471548
/*
1548-
* Traverse the capabilities list.
1549+
* Traverse the capabilities list. Limit by total theoretical
1550+
* maximum number of caps: capability needs at least id and
1551+
* next registers, and any type X header cannot contain caps.
15491552
*/
1550-
while (ptr != 0) {
1553+
for (cnt = 0; ptr != 0 && cnt < (PCIE_REGMAX - 0x40) / 2; cnt++) {
15511554
if (pci_read_config(child, ptr + PCICAP_ID, 1) == capability) {
15521555
if (capreg != NULL)
15531556
*capreg = ptr;

0 commit comments

Comments
 (0)