Loading drivers/cxl/cxl.h +1 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ static inline int ways_to_eiw(unsigned int ways, u8 *eiw) #define CXL_RAS_UNCORRECTABLE_STATUS_MASK (GENMASK(16, 14) | GENMASK(11, 0)) #define CXL_RAS_UNCORRECTABLE_MASK_OFFSET 0x4 #define CXL_RAS_UNCORRECTABLE_MASK_MASK (GENMASK(16, 14) | GENMASK(11, 0)) #define CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK BIT(8) #define CXL_RAS_UNCORRECTABLE_SEVERITY_OFFSET 0x8 #define CXL_RAS_UNCORRECTABLE_SEVERITY_MASK (GENMASK(16, 14) | GENMASK(11, 0)) #define CXL_RAS_CORRECTABLE_STATUS_OFFSET 0xC Loading drivers/cxl/pci.c +62 −8 Original line number Diff line number Diff line Loading @@ -412,9 +412,65 @@ static bool is_cxl_restricted(struct pci_dev *pdev) return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END; } static void disable_aer(void *pdev) /* * CXL v3.0 6.2.3 Table 6-4 * The table indicates that if PCIe Flit Mode is set, then CXL is in 256B flits * mode, otherwise it's 68B flits mode. */ static bool cxl_pci_flit_256(struct pci_dev *pdev) { pci_disable_pcie_error_reporting(pdev); u16 lnksta2; pcie_capability_read_word(pdev, PCI_EXP_LNKSTA2, &lnksta2); return lnksta2 & PCI_EXP_LNKSTA2_FLIT; } static int cxl_pci_ras_unmask(struct pci_dev *pdev) { struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus); struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); void __iomem *addr; u32 orig_val, val, mask; u16 cap; int rc; if (!cxlds->regs.ras) { dev_dbg(&pdev->dev, "No RAS registers.\n"); return 0; } /* BIOS has CXL error control */ if (!host_bridge->native_cxl_error) return -ENXIO; rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); if (rc) return rc; if (cap & PCI_EXP_DEVCTL_URRE) { addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_MASK_OFFSET; orig_val = readl(addr); mask = CXL_RAS_UNCORRECTABLE_MASK_MASK; if (!cxl_pci_flit_256(pdev)) mask &= ~CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK; val = orig_val & ~mask; writel(val, addr); dev_dbg(&pdev->dev, "Uncorrectable RAS Errors Mask: %#x -> %#x\n", orig_val, val); } if (cap & PCI_EXP_DEVCTL_CERE) { addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_MASK_OFFSET; orig_val = readl(addr); val = orig_val & ~CXL_RAS_CORRECTABLE_MASK_MASK; writel(val, addr); dev_dbg(&pdev->dev, "Correctable RAS Errors Mask: %#x -> %#x\n", orig_val, val); } return 0; } static void free_event_buf(void *buf) Loading Loading @@ -733,12 +789,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; if (cxlds->regs.ras) { pci_enable_pcie_error_reporting(pdev); rc = devm_add_action_or_reset(&pdev->dev, disable_aer, pdev); rc = cxl_pci_ras_unmask(pdev); if (rc) return rc; } dev_dbg(&pdev->dev, "No RAS reporting unmasked\n"); pci_save_state(pdev); return rc; Loading include/uapi/linux/pci_regs.h +1 −0 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ #define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380 /* Transmit Margin */ #define PCI_EXP_LNKCTL2_HASD 0x0020 /* HW Autonomous Speed Disable */ #define PCI_EXP_LNKSTA2 0x32 /* Link Status 2 */ #define PCI_EXP_LNKSTA2_FLIT 0x0400 /* Flit Mode Status */ #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32 /* end of v2 EPs w/ link */ #define PCI_EXP_SLTCAP2 0x34 /* Slot Capabilities 2 */ #define PCI_EXP_SLTCAP2_IBPD 0x00000001 /* In-band PD Disable Supported */ Loading Loading
drivers/cxl/cxl.h +1 −0 Original line number Diff line number Diff line Loading @@ -130,6 +130,7 @@ static inline int ways_to_eiw(unsigned int ways, u8 *eiw) #define CXL_RAS_UNCORRECTABLE_STATUS_MASK (GENMASK(16, 14) | GENMASK(11, 0)) #define CXL_RAS_UNCORRECTABLE_MASK_OFFSET 0x4 #define CXL_RAS_UNCORRECTABLE_MASK_MASK (GENMASK(16, 14) | GENMASK(11, 0)) #define CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK BIT(8) #define CXL_RAS_UNCORRECTABLE_SEVERITY_OFFSET 0x8 #define CXL_RAS_UNCORRECTABLE_SEVERITY_MASK (GENMASK(16, 14) | GENMASK(11, 0)) #define CXL_RAS_CORRECTABLE_STATUS_OFFSET 0xC Loading
drivers/cxl/pci.c +62 −8 Original line number Diff line number Diff line Loading @@ -412,9 +412,65 @@ static bool is_cxl_restricted(struct pci_dev *pdev) return pci_pcie_type(pdev) == PCI_EXP_TYPE_RC_END; } static void disable_aer(void *pdev) /* * CXL v3.0 6.2.3 Table 6-4 * The table indicates that if PCIe Flit Mode is set, then CXL is in 256B flits * mode, otherwise it's 68B flits mode. */ static bool cxl_pci_flit_256(struct pci_dev *pdev) { pci_disable_pcie_error_reporting(pdev); u16 lnksta2; pcie_capability_read_word(pdev, PCI_EXP_LNKSTA2, &lnksta2); return lnksta2 & PCI_EXP_LNKSTA2_FLIT; } static int cxl_pci_ras_unmask(struct pci_dev *pdev) { struct pci_host_bridge *host_bridge = pci_find_host_bridge(pdev->bus); struct cxl_dev_state *cxlds = pci_get_drvdata(pdev); void __iomem *addr; u32 orig_val, val, mask; u16 cap; int rc; if (!cxlds->regs.ras) { dev_dbg(&pdev->dev, "No RAS registers.\n"); return 0; } /* BIOS has CXL error control */ if (!host_bridge->native_cxl_error) return -ENXIO; rc = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &cap); if (rc) return rc; if (cap & PCI_EXP_DEVCTL_URRE) { addr = cxlds->regs.ras + CXL_RAS_UNCORRECTABLE_MASK_OFFSET; orig_val = readl(addr); mask = CXL_RAS_UNCORRECTABLE_MASK_MASK; if (!cxl_pci_flit_256(pdev)) mask &= ~CXL_RAS_UNCORRECTABLE_MASK_F256B_MASK; val = orig_val & ~mask; writel(val, addr); dev_dbg(&pdev->dev, "Uncorrectable RAS Errors Mask: %#x -> %#x\n", orig_val, val); } if (cap & PCI_EXP_DEVCTL_CERE) { addr = cxlds->regs.ras + CXL_RAS_CORRECTABLE_MASK_OFFSET; orig_val = readl(addr); val = orig_val & ~CXL_RAS_CORRECTABLE_MASK_MASK; writel(val, addr); dev_dbg(&pdev->dev, "Correctable RAS Errors Mask: %#x -> %#x\n", orig_val, val); } return 0; } static void free_event_buf(void *buf) Loading Loading @@ -733,12 +789,10 @@ static int cxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; if (cxlds->regs.ras) { pci_enable_pcie_error_reporting(pdev); rc = devm_add_action_or_reset(&pdev->dev, disable_aer, pdev); rc = cxl_pci_ras_unmask(pdev); if (rc) return rc; } dev_dbg(&pdev->dev, "No RAS reporting unmasked\n"); pci_save_state(pdev); return rc; Loading
include/uapi/linux/pci_regs.h +1 −0 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ #define PCI_EXP_LNKCTL2_TX_MARGIN 0x0380 /* Transmit Margin */ #define PCI_EXP_LNKCTL2_HASD 0x0020 /* HW Autonomous Speed Disable */ #define PCI_EXP_LNKSTA2 0x32 /* Link Status 2 */ #define PCI_EXP_LNKSTA2_FLIT 0x0400 /* Flit Mode Status */ #define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32 /* end of v2 EPs w/ link */ #define PCI_EXP_SLTCAP2 0x34 /* Slot Capabilities 2 */ #define PCI_EXP_SLTCAP2_IBPD 0x00000001 /* In-band PD Disable Supported */ Loading