Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI: Introduce pcie_is_cxl()

CXL is a protocol that runs on top of PCIe electricals. Its error model
also runs on top of the PCIe AER error model by standardizing "internal"
errors as "CXL" errors. Linux has historically ignored internal errors.

CXL protocol error handling is then a task of enhancing the PCIe AER
core to understand that PCIe ports (upstream and downstream) and
endpoints may throw internal errors that represent standard CXL protocol
errors.

The proposed method to make that determination is to teach 'struct
pci_dev' to cache when its link has trained the CXL.mem and/or CXL.cache
protocols and then treat all internal errors as CXL errors. A design
goal is to not burden the PCIe AER core with CXL knowledge beyond just
enough to forward error notifications to the CXL RAS core. The forwarded
notification looks up a 'struct cxl_port' or 'struct cxl_dport'
companion device to the PCI device.

Introduce set_pcie_cxl() with logic checking for CXL.mem or CXL.cache
status in the CXL Flex Bus DVSEC status register. The CXL Flex Bus DVSEC
presence is used because it is required for all the CXL PCIe devices.[1]

[1] CXL 3.1 Spec, 8.1.1 PCIe Designated Vendor-Specific Extended
Capability (DVSEC) ID Assignment, Table 8-2

Signed-off-by: Terry Bowman <terry.bowman@amd.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Alejandro Lucero <alucerop@amd.com>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260114182055.46029-4-terry.bowman@amd.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Dave Jiang <dave.jiang@intel.com>

authored by

Terry Bowman and committed by
Dave Jiang
7c29ba02 6612bd9f

+43
+31
drivers/pci/probe.c
··· 1735 1735 dev->is_thunderbolt = 1; 1736 1736 } 1737 1737 1738 + static void set_pcie_cxl(struct pci_dev *dev) 1739 + { 1740 + struct pci_dev *bridge; 1741 + u16 dvsec, cap; 1742 + 1743 + if (!pci_is_pcie(dev)) 1744 + return; 1745 + 1746 + /* 1747 + * Update parent's CXL state because alternate protocol training 1748 + * may have changed 1749 + */ 1750 + bridge = pci_upstream_bridge(dev); 1751 + if (bridge) 1752 + set_pcie_cxl(bridge); 1753 + 1754 + dvsec = pci_find_dvsec_capability(dev, PCI_VENDOR_ID_CXL, 1755 + PCI_DVSEC_CXL_FLEXBUS_PORT); 1756 + if (!dvsec) 1757 + return; 1758 + 1759 + pci_read_config_word(dev, dvsec + PCI_DVSEC_CXL_FLEXBUS_PORT_STATUS, 1760 + &cap); 1761 + 1762 + dev->is_cxl = FIELD_GET(PCI_DVSEC_CXL_FLEXBUS_PORT_STATUS_CACHE, cap) || 1763 + FIELD_GET(PCI_DVSEC_CXL_FLEXBUS_PORT_STATUS_MEM, cap); 1764 + 1765 + } 1766 + 1738 1767 static void set_pcie_untrusted(struct pci_dev *dev) 1739 1768 { 1740 1769 struct pci_dev *parent = pci_upstream_bridge(dev); ··· 2093 2064 2094 2065 /* Need to have dev->cfg_size ready */ 2095 2066 set_pcie_thunderbolt(dev); 2067 + 2068 + set_pcie_cxl(dev); 2096 2069 2097 2070 set_pcie_untrusted(dev); 2098 2071
+6
include/linux/pci.h
··· 463 463 unsigned int is_pciehp:1; 464 464 unsigned int shpc_managed:1; /* SHPC owned by shpchp */ 465 465 unsigned int is_thunderbolt:1; /* Thunderbolt controller */ 466 + unsigned int is_cxl:1; /* Compute Express Link (CXL) */ 466 467 /* 467 468 * Devices marked being untrusted are the ones that can potentially 468 469 * execute DMA attacks and similar. They are typically connected ··· 790 789 static inline bool pci_is_display(struct pci_dev *pdev) 791 790 { 792 791 return (pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY; 792 + } 793 + 794 + static inline bool pcie_is_cxl(struct pci_dev *pci_dev) 795 + { 796 + return pci_dev->is_cxl; 793 797 } 794 798 795 799 #define for_each_pci_bridge(dev, bus) \
+6
include/uapi/linux/pci_regs.h
··· 1379 1379 /* CXL r4.0, 8.1.7: GPF DVSEC for CXL Device */ 1380 1380 #define PCI_DVSEC_CXL_DEVICE_GPF 5 1381 1381 1382 + /* CXL r4.0, 8.1.8: Flex Bus DVSEC */ 1383 + #define PCI_DVSEC_CXL_FLEXBUS_PORT 7 1384 + #define PCI_DVSEC_CXL_FLEXBUS_PORT_STATUS 0xE 1385 + #define PCI_DVSEC_CXL_FLEXBUS_PORT_STATUS_CACHE _BITUL(0) 1386 + #define PCI_DVSEC_CXL_FLEXBUS_PORT_STATUS_MEM _BITUL(2) 1387 + 1382 1388 /* CXL r4.0, 8.1.9: Register Locator DVSEC */ 1383 1389 #define PCI_DVSEC_CXL_REG_LOCATOR 8 1384 1390 #define PCI_DVSEC_CXL_REG_LOCATOR_BLOCK1 0xC