@@ -936,6 +936,30 @@ static bool find_source_device(struct pci_dev *parent,
936
936
937
937
#ifdef CONFIG_PCIEAER_CXL
938
938
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
+
939
963
static bool is_cxl_mem_dev (struct pci_dev * dev )
940
964
{
941
965
/*
@@ -1012,7 +1036,39 @@ static void cxl_rch_handle_error(struct pci_dev *dev, struct aer_err_info *info)
1012
1036
pcie_walk_rcec (dev , cxl_rch_handle_error_iter , info );
1013
1037
}
1014
1038
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
+
1015
1070
#else
1071
+ static inline void cxl_rch_enable_rcec (struct pci_dev * dev ) { }
1016
1072
static inline void cxl_rch_handle_error (struct pci_dev * dev ,
1017
1073
struct aer_err_info * info ) { }
1018
1074
#endif
@@ -1412,6 +1468,7 @@ static int aer_probe(struct pcie_device *dev)
1412
1468
return status ;
1413
1469
}
1414
1470
1471
+ cxl_rch_enable_rcec (port );
1415
1472
aer_enable_rootport (rpc );
1416
1473
pci_info (port , "enabled with IRQ %d\n" , dev -> irq );
1417
1474
return 0 ;
0 commit comments