From 944bb1df9fc9f4280f2c9c8e87b5954e8e700c2c Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 29 Dec 2023 15:16:03 +0100 Subject: [PATCH] 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. --- lib/header.h | 3 ++- ls-ecaps.c | 9 +++------ 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"); } -- 2.39.2