Skip to content

Commit b7e9392

Browse files
Robert Richterdjbw
authored andcommitted
PCI/AER: Unmask RCEC internal errors to enable RCH downstream port error handling
AER corrected and uncorrectable internal errors (CIE/UIE) are masked in their corresponding mask registers per default once in power-up state. [1][2] Enable internal errors for RCECs to receive CXL downstream port errors of Restricted CXL Hosts (RCHs). [1] CXL 3.0 Spec, 12.2.1.1 - RCH Downstream Port Detected Errors [2] PCIe Base Spec r6.0, 7.8.4.3 Uncorrectable Error Mask Register, 7.8.4.6 Correctable Error Mask Register Co-developed-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Terry Bowman <terry.bowman@amd.com> Signed-off-by: Robert Richter <rrichter@amd.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/20231018171713.1883517-19-rrichter@amd.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 0a86756 commit b7e9392

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

drivers/pci/pcie/aer.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,30 @@ static bool find_source_device(struct pci_dev *parent,
936936

937937
#ifdef CONFIG_PCIEAER_CXL
938938

939+
/**
940+
* pci_aer_unmask_internal_errors - unmask internal errors
941+
* @dev: pointer to the pcie_dev data structure
942+
*
943+
* Unmasks internal errors in the Uncorrectable and Correctable Error
944+
* Mask registers.
945+
*
946+
* Note: AER must be enabled and supported by the device which must be
947+
* checked in advance, e.g. with pcie_aer_is_native().
948+
*/
949+
static void pci_aer_unmask_internal_errors(struct pci_dev *dev)
950+
{
951+
int aer = dev->aer_cap;
952+
u32 mask;
953+
954+
pci_read_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, &mask);
955+
mask &= ~PCI_ERR_UNC_INTN;
956+
pci_write_config_dword(dev, aer + PCI_ERR_UNCOR_MASK, mask);
957+
958+
pci_read_config_dword(dev, aer + PCI_ERR_COR_MASK, &mask);
959+
mask &= ~PCI_ERR_COR_INTERNAL;
960+
pci_write_config_dword(dev, aer + PCI_ERR_COR_MASK, mask);
961+
}
962+
939963
static bool is_cxl_mem_dev(struct pci_dev *dev)
940964
{
941965
/*
@@ -1012,7 +1036,39 @@ static void cxl_rch_handle_error(struct pci_dev *dev, struct aer_err_info *info)
10121036
pcie_walk_rcec(dev, cxl_rch_handle_error_iter, info);
10131037
}
10141038

1039+
static int handles_cxl_error_iter(struct pci_dev *dev, void *data)
1040+
{
1041+
bool *handles_cxl = data;
1042+
1043+
if (!*handles_cxl)
1044+
*handles_cxl = is_cxl_mem_dev(dev) && cxl_error_is_native(dev);
1045+
1046+
/* Non-zero terminates iteration */
1047+
return *handles_cxl;
1048+
}
1049+
1050+
static bool handles_cxl_errors(struct pci_dev *rcec)
1051+
{
1052+
bool handles_cxl = false;
1053+
1054+
if (pci_pcie_type(rcec) == PCI_EXP_TYPE_RC_EC &&
1055+
pcie_aer_is_native(rcec))
1056+
pcie_walk_rcec(rcec, handles_cxl_error_iter, &handles_cxl);
1057+
1058+
return handles_cxl;
1059+
}
1060+
1061+
static void cxl_rch_enable_rcec(struct pci_dev *rcec)
1062+
{
1063+
if (!handles_cxl_errors(rcec))
1064+
return;
1065+
1066+
pci_aer_unmask_internal_errors(rcec);
1067+
pci_info(rcec, "CXL: Internal errors unmasked");
1068+
}
1069+
10151070
#else
1071+
static inline void cxl_rch_enable_rcec(struct pci_dev *dev) { }
10161072
static inline void cxl_rch_handle_error(struct pci_dev *dev,
10171073
struct aer_err_info *info) { }
10181074
#endif
@@ -1412,6 +1468,7 @@ static int aer_probe(struct pcie_device *dev)
14121468
return status;
14131469
}
14141470

1471+
cxl_rch_enable_rcec(port);
14151472
aer_enable_rootport(rpc);
14161473
pci_info(port, "enabled with IRQ %d\n", dev->irq);
14171474
return 0;

0 commit comments

Comments
 (0)