git: 6ba2c036a011 - main - pci_find_cap_method(): limit number of iterations for finding a capability
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 07 Jan 2025 15:35:25 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=6ba2c036a0117ac02f9979b7dc49f15e9c1ea9c9
commit 6ba2c036a0117ac02f9979b7dc49f15e9c1ea9c9
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-01-06 23:29:18 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-01-07 15:34:59 +0000
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
---
sys/dev/pci/pci.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index cf01115581e1..0b02d873c5a1 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1519,6 +1519,7 @@ pci_find_cap_method(device_t dev, device_t child, int capability,
pcicfgregs *cfg = &dinfo->cfg;
uint32_t status;
uint8_t ptr;
+ int cnt;
/*
* 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,
ptr = pci_read_config(child, ptr, 1);
/*
- * Traverse the capabilities list.
+ * Traverse the capabilities list. Limit by total theoretical
+ * maximum number of caps: capability needs at least id and
+ * next registers, and any type X header cannot contain caps.
*/
- while (ptr != 0) {
+ for (cnt = 0; ptr != 0 && cnt < (PCIE_REGMAX - 0x40) / 2; cnt++) {
if (pci_read_config(child, ptr + PCICAP_ID, 1) == capability) {
if (capreg != NULL)
*capreg = ptr;