aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>2023-12-29 15:16:03 +0100
committerMartin Mares <mj@ucw.cz>2023-12-29 15:16:03 +0100
commit944bb1df9fc9f4280f2c9c8e87b5954e8e700c2c (patch)
treed4cc42821158fd6793d745ac7455787790c8dcca
parent93c1c6bcc9e2b52652b859986354ddd54ef34058 (diff)
downloadpciutils-944bb1df9fc9f4280f2c9c8e87b5954e8e700c2c.tar.gz
Constants for CXL capability should not change
When CXL capability decoding was upgraded to revision 2 by commit c0ccce1b4cd5b42b17f2e8f7bae4031c311677ff, the value of PCI_CXL_DEV_LEN in lib/header.h has changed. This is probably not a good idea - programs using libpci can depend on the exact value of this constant. Let us revert PCI_CXL_DEV_LEN to the original value for revision 1 and add PCI_CXL_DEV_LEN_REV2 for the next revision. Also, fixed a bug in the decoder which caused it to read past the end of the buffer for a capability which is declared as revision 2, but too short.
-rw-r--r--lib/header.h3
-rw-r--r--ls-ecaps.c9
2 files changed, 5 insertions, 7 deletions
diff --git a/lib/header.h b/lib/header.h
index 2bace93..58fe7df 100644
--- a/lib/header.h
+++ b/lib/header.h
@@ -1076,7 +1076,8 @@
#define PCI_DVSEC_ID_CXL 0 /* Designated Vendor-Specific ID for Intel CXL */
/* PCIe CXL Designated Vendor-Specific Capabilities for Devices: Control, Status */
-#define PCI_CXL_DEV_LEN 0x3c /* CXL Device DVSEC Length */
+#define PCI_CXL_DEV_LEN 0x38 /* CXL Device DVSEC Length for Rev1 */
+#define PCI_CXL_DEV_LEN_REV2 0x3c /* ... for Rev2 */
#define PCI_CXL_DEV_CAP 0x0a /* CXL Capability Register */
#define PCI_CXL_DEV_CAP_CACHE 0x0001 /* CXL.cache Protocol Support */
#define PCI_CXL_DEV_CAP_IO 0x0002 /* CXL.io Protocol Support */
diff --git a/ls-ecaps.c b/ls-ecaps.c
index 6d2e7b0..2d7d827 100644
--- a/ls-ecaps.c
+++ b/ls-ecaps.c
@@ -718,14 +718,11 @@ dvsec_cxl_device(struct device *d, int rev, int where, int len)
u64 range_base, range_size;
u16 w;
- if (len < 0x38)
- return;
-
/* Legacy 1.1 revs aren't handled */
if (rev == 0)
return;
- if (rev >= 1)
+ if (rev >= 1 && len >= PCI_CXL_DEV_LEN)
{
w = get_conf_word(d, where + PCI_CXL_DEV_CAP);
printf("\t\tCXLCap:\tCache%c IO%c Mem%c MemHWInit%c HDMCount %d Viral%c\n",
@@ -788,7 +785,7 @@ dvsec_cxl_device(struct device *d, int rev, int where, int len)
cxl_range(range_base, range_size, 2);
}
- if (rev >= 2)
+ if (rev >= 2 && len >= PCI_CXL_DEV_LEN_REV2)
{
w = get_conf_word(d, where + PCI_CXL_DEV_CAP3);
printf("\t\tCXLCap3:\tDefaultVolatile HDM State After:\tColdReset%c WarmReset%c HotReset%c HotResetConfigurability%c\n",
@@ -799,7 +796,7 @@ dvsec_cxl_device(struct device *d, int rev, int where, int len)
}
// Unparsed data
- if (len > PCI_CXL_DEV_LEN)
+ if (len > PCI_CXL_DEV_LEN_REV2)
printf("\t\t<?>\n");
}