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.
#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 */
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",
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",
}
// Unparsed data
- if (len > PCI_CXL_DEV_LEN)
+ if (len > PCI_CXL_DEV_LEN_REV2)
printf("\t\t<?>\n");
}