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.

Merge tag 'edac_updates_for_v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC updates from Borislav Petkov:

- Add support for Bluefield-2 SOCs to bluefield_edac

- Add support for Intel Panther Lake-H to igen6_edac

- Add polling support to igen6_edac as some Intel M100 chips have
trouble with error interrupts

- Add Kaby Lake-S support to ie31200_edac

- Fix memory source detection in the SKX common module which is used by
a couple of Intel EDAC drivers

- Add support for the NXP i.MX9 memory controller to fsl_edac

- The usual fixes and cleanups all over the place

* tag 'edac_updates_for_v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
EDAC/igen6: Add polling support
EDAC/igen6: Initialize edac_op_state according to the configuration data
EDAC/igen6: Avoid segmentation fault on module unload
EDAC/ie31200: Add Kaby Lake-S dual-core host bridge ID
MAINTAINERS: Change FSL DDR EDAC maintainership
EDAC/{skx_common,i10nm}: Fix incorrect far-memory error source indicator
EDAC/skx_common: Differentiate memory error sources
EDAC/fsl_ddr: Add support for i.MX9 DDR controller
dt-bindings: memory: fsl: Add compatible string nxp,imx9-memory-controller
EDAC/fsl_ddr: Fix bad bit shift operations
EDAC/fsl_ddr: Move global variables into struct fsl_mc_pdata
EDAC/fsl_ddr: Pass down fsl_mc_pdata in ddr_in32() and ddr_out32()
RAS/AMD/ATL: Add debug prints for DF register reads
EDAC/bluefield: Use Arm SMC for EMI access on BlueField-2
EDAC/bluefield: Fix potential integer overflow
EDAC/igen6: Add Intel Panther Lake-H SoCs support

+399 -97
+4
CREDITS
··· 3800 3800 S: Seattle, WA 98195-1800 3801 3801 S: USA 3802 3802 3803 + N: York Sun 3804 + E: york.sun@nxp.com 3805 + D: Freescale DDR EDAC 3806 + 3803 3807 N: Eugene Surovegin 3804 3808 E: ebs@ebshome.net 3805 3809 W: https://kernel.ebshome.net/
+30 -1
Documentation/devicetree/bindings/memory-controllers/fsl/fsl,ddr.yaml
··· 40 40 - fsl,p1021-memory-controller 41 41 - fsl,p2020-memory-controller 42 42 - fsl,qoriq-memory-controller 43 + - nxp,imx9-memory-controller 43 44 44 45 interrupts: 45 46 maxItems: 1 ··· 52 51 type: boolean 53 52 54 53 reg: 55 - maxItems: 1 54 + items: 55 + - description: Controller register space 56 + - description: Inject register space 57 + minItems: 1 58 + 59 + reg-names: 60 + items: 61 + - const: ctrl 62 + - const: inject 63 + minItems: 1 56 64 57 65 required: 58 66 - compatible 59 67 - interrupts 60 68 - reg 69 + 70 + allOf: 71 + - if: 72 + properties: 73 + compatible: 74 + contains: 75 + enum: 76 + - nxp,imx9-memory-controller 77 + then: 78 + properties: 79 + reg: 80 + minItems: 2 81 + reg-names: 82 + minItems: 2 83 + else: 84 + properties: 85 + reg: 86 + maxItems: 1 87 + reg-names: false 61 88 62 89 additionalProperties: false 63 90
+2 -1
MAINTAINERS
··· 8103 8103 F: drivers/edac/e7xxx_edac.c 8104 8104 8105 8105 EDAC-FSL_DDR 8106 - M: York Sun <york.sun@nxp.com> 8106 + R: Frank Li <Frank.Li@nxp.com> 8107 + L: imx@lists.linux.dev 8107 8108 L: linux-edac@vger.kernel.org 8108 8109 S: Maintained 8109 8110 F: drivers/edac/fsl_ddr_edac.*
+150 -20
drivers/edac/bluefield_edac.c
··· 47 47 #define MLXBF_EDAC_MAX_DIMM_PER_MC 2 48 48 #define MLXBF_EDAC_ERROR_GRAIN 8 49 49 50 + #define MLXBF_WRITE_REG_32 (0x82000009) 51 + #define MLXBF_READ_REG_32 (0x8200000A) 52 + #define MLXBF_SIP_SVC_VERSION (0x8200ff03) 53 + 54 + #define MLXBF_SMCCC_ACCESS_VIOLATION (-4) 55 + 56 + #define MLXBF_SVC_REQ_MAJOR 0 57 + #define MLXBF_SVC_REQ_MINOR 3 58 + 50 59 /* 51 - * Request MLNX_SIP_GET_DIMM_INFO 60 + * Request MLXBF_SIP_GET_DIMM_INFO 52 61 * 53 62 * Retrieve information about DIMM on a certain slot. 54 63 * 55 64 * Call register usage: 56 - * a0: MLNX_SIP_GET_DIMM_INFO 65 + * a0: MLXBF_SIP_GET_DIMM_INFO 57 66 * a1: (Memory controller index) << 16 | (Dimm index in memory controller) 58 67 * a2-7: not used. 59 68 * ··· 70 61 * a0: MLXBF_DIMM_INFO defined below describing the DIMM. 71 62 * a1-3: not used. 72 63 */ 73 - #define MLNX_SIP_GET_DIMM_INFO 0x82000008 64 + #define MLXBF_SIP_GET_DIMM_INFO 0x82000008 74 65 75 66 /* Format for the SMC response about the memory information */ 76 67 #define MLXBF_DIMM_INFO__SIZE_GB GENMASK_ULL(15, 0) ··· 81 72 #define MLXBF_DIMM_INFO__PACKAGE_X GENMASK_ULL(31, 24) 82 73 83 74 struct bluefield_edac_priv { 75 + /* pointer to device structure */ 76 + struct device *dev; 84 77 int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC]; 85 78 void __iomem *emi_base; 86 79 int dimm_per_mc; 80 + /* access to secure regs supported */ 81 + bool svc_sreg_support; 82 + /* SMC table# for secure regs access */ 83 + u32 sreg_tbl; 87 84 }; 88 85 89 86 static u64 smc_call1(u64 smc_op, u64 smc_arg) ··· 99 84 arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res); 100 85 101 86 return res.a0; 87 + } 88 + 89 + static int secure_readl(void __iomem *addr, u32 *result, u32 sreg_tbl) 90 + { 91 + struct arm_smccc_res res; 92 + int status; 93 + 94 + arm_smccc_smc(MLXBF_READ_REG_32, sreg_tbl, (uintptr_t)addr, 95 + 0, 0, 0, 0, 0, &res); 96 + 97 + status = res.a0; 98 + 99 + if (status == SMCCC_RET_NOT_SUPPORTED || 100 + status == MLXBF_SMCCC_ACCESS_VIOLATION) 101 + return -1; 102 + 103 + *result = (u32)res.a1; 104 + return 0; 105 + } 106 + 107 + static int secure_writel(void __iomem *addr, u32 data, u32 sreg_tbl) 108 + { 109 + struct arm_smccc_res res; 110 + int status; 111 + 112 + arm_smccc_smc(MLXBF_WRITE_REG_32, sreg_tbl, data, (uintptr_t)addr, 113 + 0, 0, 0, 0, &res); 114 + 115 + status = res.a0; 116 + 117 + if (status == SMCCC_RET_NOT_SUPPORTED || 118 + status == MLXBF_SMCCC_ACCESS_VIOLATION) 119 + return -1; 120 + else 121 + return 0; 122 + } 123 + 124 + static int bluefield_edac_readl(struct bluefield_edac_priv *priv, u32 offset, u32 *result) 125 + { 126 + void __iomem *addr; 127 + int err = 0; 128 + 129 + addr = priv->emi_base + offset; 130 + 131 + if (priv->svc_sreg_support) 132 + err = secure_readl(addr, result, priv->sreg_tbl); 133 + else 134 + *result = readl(addr); 135 + 136 + return err; 137 + } 138 + 139 + static int bluefield_edac_writel(struct bluefield_edac_priv *priv, u32 offset, u32 data) 140 + { 141 + void __iomem *addr; 142 + int err = 0; 143 + 144 + addr = priv->emi_base + offset; 145 + 146 + if (priv->svc_sreg_support) 147 + err = secure_writel(addr, data, priv->sreg_tbl); 148 + else 149 + writel(data, addr); 150 + 151 + return err; 102 152 } 103 153 104 154 /* ··· 179 99 u32 ecc_latch_select, dram_syndrom, serr, derr, syndrom; 180 100 enum hw_event_mc_err_type ecc_type; 181 101 u64 ecc_dimm_addr; 182 - int ecc_dimm; 102 + int ecc_dimm, err; 183 103 184 104 ecc_type = is_single_ecc ? HW_EVENT_ERR_CORRECTED : 185 105 HW_EVENT_ERR_UNCORRECTED; ··· 189 109 * registers with information about the last ECC error occurrence. 190 110 */ 191 111 ecc_latch_select = MLXBF_ECC_LATCH_SEL__START; 192 - writel(ecc_latch_select, priv->emi_base + MLXBF_ECC_LATCH_SEL); 112 + err = bluefield_edac_writel(priv, MLXBF_ECC_LATCH_SEL, ecc_latch_select); 113 + if (err) 114 + dev_err(priv->dev, "ECC latch select write failed.\n"); 193 115 194 116 /* 195 117 * Verify that the ECC reported info in the registers is of the 196 118 * same type as the one asked to report. If not, just report the 197 119 * error without the detailed information. 198 120 */ 199 - dram_syndrom = readl(priv->emi_base + MLXBF_SYNDROM); 121 + err = bluefield_edac_readl(priv, MLXBF_SYNDROM, &dram_syndrom); 122 + if (err) 123 + dev_err(priv->dev, "DRAM syndrom read failed.\n"); 124 + 200 125 serr = FIELD_GET(MLXBF_SYNDROM__SERR, dram_syndrom); 201 126 derr = FIELD_GET(MLXBF_SYNDROM__DERR, dram_syndrom); 202 127 syndrom = FIELD_GET(MLXBF_SYNDROM__SYN, dram_syndrom); ··· 212 127 return; 213 128 } 214 129 215 - dram_additional_info = readl(priv->emi_base + MLXBF_ADD_INFO); 130 + err = bluefield_edac_readl(priv, MLXBF_ADD_INFO, &dram_additional_info); 131 + if (err) 132 + dev_err(priv->dev, "DRAM additional info read failed.\n"); 133 + 216 134 err_prank = FIELD_GET(MLXBF_ADD_INFO__ERR_PRANK, dram_additional_info); 217 135 218 136 ecc_dimm = (err_prank >= 2 && priv->dimm_ranks[0] <= 2) ? 1 : 0; 219 137 220 - edea0 = readl(priv->emi_base + MLXBF_ERR_ADDR_0); 221 - edea1 = readl(priv->emi_base + MLXBF_ERR_ADDR_1); 138 + err = bluefield_edac_readl(priv, MLXBF_ERR_ADDR_0, &edea0); 139 + if (err) 140 + dev_err(priv->dev, "Error addr 0 read failed.\n"); 141 + 142 + err = bluefield_edac_readl(priv, MLXBF_ERR_ADDR_1, &edea1); 143 + if (err) 144 + dev_err(priv->dev, "Error addr 1 read failed.\n"); 222 145 223 146 ecc_dimm_addr = ((u64)edea1 << 32) | edea0; 224 147 ··· 240 147 { 241 148 struct bluefield_edac_priv *priv = mci->pvt_info; 242 149 u32 ecc_count, single_error_count, double_error_count, ecc_error = 0; 150 + int err; 243 151 244 152 /* 245 153 * The memory controller might not be initialized by the firmware ··· 249 155 if (mci->edac_cap == EDAC_FLAG_NONE) 250 156 return; 251 157 252 - ecc_count = readl(priv->emi_base + MLXBF_ECC_CNT); 158 + err = bluefield_edac_readl(priv, MLXBF_ECC_CNT, &ecc_count); 159 + if (err) 160 + dev_err(priv->dev, "ECC count read failed.\n"); 161 + 253 162 single_error_count = FIELD_GET(MLXBF_ECC_CNT__SERR_CNT, ecc_count); 254 163 double_error_count = FIELD_GET(MLXBF_ECC_CNT__DERR_CNT, ecc_count); 255 164 ··· 269 172 } 270 173 271 174 /* Write to clear reported errors. */ 272 - if (ecc_count) 273 - writel(ecc_error, priv->emi_base + MLXBF_ECC_ERR); 175 + if (ecc_count) { 176 + err = bluefield_edac_writel(priv, MLXBF_ECC_ERR, ecc_error); 177 + if (err) 178 + dev_err(priv->dev, "ECC Error write failed.\n"); 179 + } 274 180 } 275 181 276 182 /* Initialize the DIMMs information for the given memory controller. */ 277 183 static void bluefield_edac_init_dimms(struct mem_ctl_info *mci) 278 184 { 279 185 struct bluefield_edac_priv *priv = mci->pvt_info; 280 - int mem_ctrl_idx = mci->mc_idx; 186 + u64 mem_ctrl_idx = mci->mc_idx; 281 187 struct dimm_info *dimm; 282 188 u64 smc_info, smc_arg; 283 189 int is_empty = 1, i; ··· 289 189 dimm = mci->dimms[i]; 290 190 291 191 smc_arg = mem_ctrl_idx << 16 | i; 292 - smc_info = smc_call1(MLNX_SIP_GET_DIMM_INFO, smc_arg); 192 + smc_info = smc_call1(MLXBF_SIP_GET_DIMM_INFO, smc_arg); 293 193 294 194 if (!FIELD_GET(MLXBF_DIMM_INFO__SIZE_GB, smc_info)) { 295 195 dimm->mtype = MEM_EMPTY; ··· 344 244 struct bluefield_edac_priv *priv; 345 245 struct device *dev = &pdev->dev; 346 246 struct edac_mc_layer layers[1]; 247 + struct arm_smccc_res res; 347 248 struct mem_ctl_info *mci; 348 249 struct resource *emi_res; 349 250 unsigned int mc_idx, dimm_count; ··· 380 279 return -ENOMEM; 381 280 382 281 priv = mci->pvt_info; 282 + priv->dev = dev; 283 + 284 + /* 285 + * The "sec_reg_block" property in the ACPI table determines the method 286 + * the driver uses to access the EMI registers: 287 + * a) property is not present - directly access registers via readl/writel 288 + * b) property is present - indirectly access registers via SMC calls 289 + * (assuming required Silicon Provider service version found) 290 + */ 291 + if (device_property_read_u32(dev, "sec_reg_block", &priv->sreg_tbl)) { 292 + priv->svc_sreg_support = false; 293 + } else { 294 + /* 295 + * Check for minimum required Arm Silicon Provider (SiP) service 296 + * version, ensuring support of required SMC function IDs. 297 + */ 298 + arm_smccc_smc(MLXBF_SIP_SVC_VERSION, 0, 0, 0, 0, 0, 0, 0, &res); 299 + if (res.a0 == MLXBF_SVC_REQ_MAJOR && 300 + res.a1 >= MLXBF_SVC_REQ_MINOR) { 301 + priv->svc_sreg_support = true; 302 + } else { 303 + dev_err(dev, "Required SMCs are not supported.\n"); 304 + ret = -EINVAL; 305 + goto err; 306 + } 307 + } 383 308 384 309 priv->dimm_per_mc = dimm_count; 385 - priv->emi_base = devm_ioremap_resource(dev, emi_res); 386 - if (IS_ERR(priv->emi_base)) { 387 - dev_err(dev, "failed to map EMI IO resource\n"); 388 - ret = PTR_ERR(priv->emi_base); 389 - goto err; 310 + if (!priv->svc_sreg_support) { 311 + priv->emi_base = devm_ioremap_resource(dev, emi_res); 312 + if (IS_ERR(priv->emi_base)) { 313 + dev_err(dev, "failed to map EMI IO resource\n"); 314 + ret = PTR_ERR(priv->emi_base); 315 + goto err; 316 + } 317 + } else { 318 + priv->emi_base = (void __iomem *)emi_res->start; 390 319 } 391 320 392 321 mci->pdev = dev; ··· 451 320 edac_mc_free(mci); 452 321 453 322 return ret; 454 - 455 323 } 456 324 457 325 static void bluefield_edac_mc_remove(struct platform_device *pdev)
+92 -51
drivers/edac/fsl_ddr_edac.c
··· 31 31 32 32 static int edac_mc_idx; 33 33 34 - static u32 orig_ddr_err_disable; 35 - static u32 orig_ddr_err_sbe; 36 - static bool little_endian; 37 - 38 - static inline u32 ddr_in32(void __iomem *addr) 34 + static inline void __iomem *ddr_reg_addr(struct fsl_mc_pdata *pdata, unsigned int off) 39 35 { 40 - return little_endian ? ioread32(addr) : ioread32be(addr); 36 + if (pdata->flag == TYPE_IMX9 && off >= FSL_MC_DATA_ERR_INJECT_HI && off <= FSL_MC_ERR_SBE) 37 + return pdata->inject_vbase + off - FSL_MC_DATA_ERR_INJECT_HI 38 + + IMX9_MC_DATA_ERR_INJECT_OFF; 39 + 40 + if (pdata->flag == TYPE_IMX9 && off >= IMX9_MC_ERR_EN) 41 + return pdata->inject_vbase + off - IMX9_MC_ERR_EN; 42 + 43 + return pdata->mc_vbase + off; 41 44 } 42 45 43 - static inline void ddr_out32(void __iomem *addr, u32 value) 46 + static inline u32 ddr_in32(struct fsl_mc_pdata *pdata, unsigned int off) 44 47 { 45 - if (little_endian) 48 + void __iomem *addr = ddr_reg_addr(pdata, off); 49 + 50 + return pdata->little_endian ? ioread32(addr) : ioread32be(addr); 51 + } 52 + 53 + static inline void ddr_out32(struct fsl_mc_pdata *pdata, unsigned int off, u32 value) 54 + { 55 + void __iomem *addr = ddr_reg_addr(pdata, off); 56 + 57 + if (pdata->little_endian) 46 58 iowrite32(value, addr); 47 59 else 48 60 iowrite32be(value, addr); ··· 72 60 struct mem_ctl_info *mci = to_mci(dev); 73 61 struct fsl_mc_pdata *pdata = mci->pvt_info; 74 62 return sprintf(data, "0x%08x", 75 - ddr_in32(pdata->mc_vbase + FSL_MC_DATA_ERR_INJECT_HI)); 63 + ddr_in32(pdata, FSL_MC_DATA_ERR_INJECT_HI)); 76 64 } 77 65 78 66 static ssize_t fsl_mc_inject_data_lo_show(struct device *dev, ··· 82 70 struct mem_ctl_info *mci = to_mci(dev); 83 71 struct fsl_mc_pdata *pdata = mci->pvt_info; 84 72 return sprintf(data, "0x%08x", 85 - ddr_in32(pdata->mc_vbase + FSL_MC_DATA_ERR_INJECT_LO)); 73 + ddr_in32(pdata, FSL_MC_DATA_ERR_INJECT_LO)); 86 74 } 87 75 88 76 static ssize_t fsl_mc_inject_ctrl_show(struct device *dev, ··· 92 80 struct mem_ctl_info *mci = to_mci(dev); 93 81 struct fsl_mc_pdata *pdata = mci->pvt_info; 94 82 return sprintf(data, "0x%08x", 95 - ddr_in32(pdata->mc_vbase + FSL_MC_ECC_ERR_INJECT)); 83 + ddr_in32(pdata, FSL_MC_ECC_ERR_INJECT)); 96 84 } 97 85 98 86 static ssize_t fsl_mc_inject_data_hi_store(struct device *dev, ··· 109 97 if (rc) 110 98 return rc; 111 99 112 - ddr_out32(pdata->mc_vbase + FSL_MC_DATA_ERR_INJECT_HI, val); 100 + ddr_out32(pdata, FSL_MC_DATA_ERR_INJECT_HI, val); 113 101 return count; 114 102 } 115 103 return 0; ··· 129 117 if (rc) 130 118 return rc; 131 119 132 - ddr_out32(pdata->mc_vbase + FSL_MC_DATA_ERR_INJECT_LO, val); 120 + ddr_out32(pdata, FSL_MC_DATA_ERR_INJECT_LO, val); 133 121 return count; 134 122 } 135 123 return 0; ··· 149 137 if (rc) 150 138 return rc; 151 139 152 - ddr_out32(pdata->mc_vbase + FSL_MC_ECC_ERR_INJECT, val); 140 + ddr_out32(pdata, FSL_MC_ECC_ERR_INJECT, val); 153 141 return count; 154 142 } 155 143 return 0; ··· 298 286 int bad_data_bit; 299 287 int bad_ecc_bit; 300 288 301 - err_detect = ddr_in32(pdata->mc_vbase + FSL_MC_ERR_DETECT); 289 + err_detect = ddr_in32(pdata, FSL_MC_ERR_DETECT); 302 290 if (!err_detect) 303 291 return; 304 292 ··· 307 295 308 296 /* no more processing if not ECC bit errors */ 309 297 if (!(err_detect & (DDR_EDE_SBE | DDR_EDE_MBE))) { 310 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_DETECT, err_detect); 298 + ddr_out32(pdata, FSL_MC_ERR_DETECT, err_detect); 311 299 return; 312 300 } 313 301 314 - syndrome = ddr_in32(pdata->mc_vbase + FSL_MC_CAPTURE_ECC); 302 + syndrome = ddr_in32(pdata, FSL_MC_CAPTURE_ECC); 315 303 316 304 /* Mask off appropriate bits of syndrome based on bus width */ 317 - bus_width = (ddr_in32(pdata->mc_vbase + FSL_MC_DDR_SDRAM_CFG) & 305 + bus_width = (ddr_in32(pdata, FSL_MC_DDR_SDRAM_CFG) & 318 306 DSC_DBW_MASK) ? 32 : 64; 319 307 if (bus_width == 64) 320 308 syndrome &= 0xff; ··· 322 310 syndrome &= 0xffff; 323 311 324 312 err_addr = make64( 325 - ddr_in32(pdata->mc_vbase + FSL_MC_CAPTURE_EXT_ADDRESS), 326 - ddr_in32(pdata->mc_vbase + FSL_MC_CAPTURE_ADDRESS)); 313 + ddr_in32(pdata, FSL_MC_CAPTURE_EXT_ADDRESS), 314 + ddr_in32(pdata, FSL_MC_CAPTURE_ADDRESS)); 327 315 pfn = err_addr >> PAGE_SHIFT; 328 316 329 317 for (row_index = 0; row_index < mci->nr_csrows; row_index++) { ··· 332 320 break; 333 321 } 334 322 335 - cap_high = ddr_in32(pdata->mc_vbase + FSL_MC_CAPTURE_DATA_HI); 336 - cap_low = ddr_in32(pdata->mc_vbase + FSL_MC_CAPTURE_DATA_LO); 323 + cap_high = ddr_in32(pdata, FSL_MC_CAPTURE_DATA_HI); 324 + cap_low = ddr_in32(pdata, FSL_MC_CAPTURE_DATA_LO); 337 325 338 326 /* 339 327 * Analyze single-bit errors on 64-bit wide buses 340 328 * TODO: Add support for 32-bit wide buses 341 329 */ 342 330 if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) { 331 + u64 cap = (u64)cap_high << 32 | cap_low; 332 + u32 s = syndrome; 333 + 343 334 sbe_ecc_decode(cap_high, cap_low, syndrome, 344 335 &bad_data_bit, &bad_ecc_bit); 345 336 346 - if (bad_data_bit != -1) 347 - fsl_mc_printk(mci, KERN_ERR, 348 - "Faulty Data bit: %d\n", bad_data_bit); 349 - if (bad_ecc_bit != -1) 350 - fsl_mc_printk(mci, KERN_ERR, 351 - "Faulty ECC bit: %d\n", bad_ecc_bit); 337 + if (bad_data_bit >= 0) { 338 + fsl_mc_printk(mci, KERN_ERR, "Faulty Data bit: %d\n", bad_data_bit); 339 + cap ^= 1ULL << bad_data_bit; 340 + } 341 + 342 + if (bad_ecc_bit >= 0) { 343 + fsl_mc_printk(mci, KERN_ERR, "Faulty ECC bit: %d\n", bad_ecc_bit); 344 + s ^= 1 << bad_ecc_bit; 345 + } 352 346 353 347 fsl_mc_printk(mci, KERN_ERR, 354 348 "Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n", 355 - cap_high ^ (1 << (bad_data_bit - 32)), 356 - cap_low ^ (1 << bad_data_bit), 357 - syndrome ^ (1 << bad_ecc_bit)); 349 + upper_32_bits(cap), lower_32_bits(cap), s); 358 350 } 359 351 360 352 fsl_mc_printk(mci, KERN_ERR, ··· 383 367 row_index, 0, -1, 384 368 mci->ctl_name, ""); 385 369 386 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_DETECT, err_detect); 370 + ddr_out32(pdata, FSL_MC_ERR_DETECT, err_detect); 387 371 } 388 372 389 373 static irqreturn_t fsl_mc_isr(int irq, void *dev_id) ··· 392 376 struct fsl_mc_pdata *pdata = mci->pvt_info; 393 377 u32 err_detect; 394 378 395 - err_detect = ddr_in32(pdata->mc_vbase + FSL_MC_ERR_DETECT); 379 + err_detect = ddr_in32(pdata, FSL_MC_ERR_DETECT); 396 380 if (!err_detect) 397 381 return IRQ_NONE; 398 382 ··· 412 396 u32 cs_bnds; 413 397 int index; 414 398 415 - sdram_ctl = ddr_in32(pdata->mc_vbase + FSL_MC_DDR_SDRAM_CFG); 399 + sdram_ctl = ddr_in32(pdata, FSL_MC_DDR_SDRAM_CFG); 416 400 417 401 sdtype = sdram_ctl & DSC_SDTYPE_MASK; 418 402 if (sdram_ctl & DSC_RD_EN) { ··· 447 431 case 0x05000000: 448 432 mtype = MEM_DDR4; 449 433 break; 434 + case 0x04000000: 435 + mtype = MEM_LPDDR4; 436 + break; 450 437 default: 451 438 mtype = MEM_UNKNOWN; 452 439 break; ··· 463 444 csrow = mci->csrows[index]; 464 445 dimm = csrow->channels[0]->dimm; 465 446 466 - cs_bnds = ddr_in32(pdata->mc_vbase + FSL_MC_CS_BNDS_0 + 447 + cs_bnds = ddr_in32(pdata, FSL_MC_CS_BNDS_0 + 467 448 (index * FSL_MC_CS_BNDS_OFS)); 468 449 469 450 start = (cs_bnds & 0xffff0000) >> 16; ··· 483 464 dimm->grain = 8; 484 465 dimm->mtype = mtype; 485 466 dimm->dtype = DEV_UNKNOWN; 486 - if (sdram_ctl & DSC_X32_EN) 467 + if (pdata->flag == TYPE_IMX9) 468 + dimm->dtype = DEV_X16; 469 + else if (sdram_ctl & DSC_X32_EN) 487 470 dimm->dtype = DEV_X32; 488 471 dimm->edac_mode = EDAC_SECDED; 489 472 } ··· 497 476 struct edac_mc_layer layers[2]; 498 477 struct fsl_mc_pdata *pdata; 499 478 struct resource r; 479 + u32 ecc_en_mask; 500 480 u32 sdram_ctl; 501 481 int res; 502 482 ··· 525 503 mci->ctl_name = pdata->name; 526 504 mci->dev_name = pdata->name; 527 505 506 + pdata->flag = (unsigned long)device_get_match_data(&op->dev); 507 + 528 508 /* 529 509 * Get the endianness of DDR controller registers. 530 510 * Default is big endian. 531 511 */ 532 - little_endian = of_property_read_bool(op->dev.of_node, "little-endian"); 512 + pdata->little_endian = of_property_read_bool(op->dev.of_node, "little-endian"); 533 513 534 514 res = of_address_to_resource(op->dev.of_node, 0, &r); 535 515 if (res) { ··· 555 531 goto err; 556 532 } 557 533 558 - sdram_ctl = ddr_in32(pdata->mc_vbase + FSL_MC_DDR_SDRAM_CFG); 559 - if (!(sdram_ctl & DSC_ECC_EN)) { 534 + if (pdata->flag == TYPE_IMX9) { 535 + pdata->inject_vbase = devm_platform_ioremap_resource_byname(op, "inject"); 536 + if (IS_ERR(pdata->inject_vbase)) { 537 + res = -ENOMEM; 538 + goto err; 539 + } 540 + } 541 + 542 + if (pdata->flag == TYPE_IMX9) { 543 + sdram_ctl = ddr_in32(pdata, IMX9_MC_ERR_EN); 544 + ecc_en_mask = ERR_ECC_EN | ERR_INLINE_ECC; 545 + } else { 546 + sdram_ctl = ddr_in32(pdata, FSL_MC_DDR_SDRAM_CFG); 547 + ecc_en_mask = DSC_ECC_EN; 548 + } 549 + 550 + if ((sdram_ctl & ecc_en_mask) != ecc_en_mask) { 560 551 /* no ECC */ 561 552 pr_warn("%s: No ECC DIMMs discovered\n", __func__); 562 553 res = -ENODEV; ··· 582 543 mci->mtype_cap = MEM_FLAG_DDR | MEM_FLAG_RDDR | 583 544 MEM_FLAG_DDR2 | MEM_FLAG_RDDR2 | 584 545 MEM_FLAG_DDR3 | MEM_FLAG_RDDR3 | 585 - MEM_FLAG_DDR4 | MEM_FLAG_RDDR4; 546 + MEM_FLAG_DDR4 | MEM_FLAG_RDDR4 | 547 + MEM_FLAG_LPDDR4; 586 548 mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; 587 549 mci->edac_cap = EDAC_FLAG_SECDED; 588 550 mci->mod_name = EDAC_MOD_STR; ··· 598 558 fsl_ddr_init_csrows(mci); 599 559 600 560 /* store the original error disable bits */ 601 - orig_ddr_err_disable = ddr_in32(pdata->mc_vbase + FSL_MC_ERR_DISABLE); 602 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_DISABLE, 0); 561 + pdata->orig_ddr_err_disable = ddr_in32(pdata, FSL_MC_ERR_DISABLE); 562 + ddr_out32(pdata, FSL_MC_ERR_DISABLE, 0); 603 563 604 564 /* clear all error bits */ 605 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_DETECT, ~0); 565 + ddr_out32(pdata, FSL_MC_ERR_DETECT, ~0); 606 566 607 567 res = edac_mc_add_mc_with_groups(mci, fsl_ddr_dev_groups); 608 568 if (res) { ··· 611 571 } 612 572 613 573 if (edac_op_state == EDAC_OPSTATE_INT) { 614 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_INT_EN, 574 + ddr_out32(pdata, FSL_MC_ERR_INT_EN, 615 575 DDR_EIE_MBEE | DDR_EIE_SBEE); 616 576 617 577 /* store the original error management threshold */ 618 - orig_ddr_err_sbe = ddr_in32(pdata->mc_vbase + 619 - FSL_MC_ERR_SBE) & 0xff0000; 578 + pdata->orig_ddr_err_sbe = ddr_in32(pdata, 579 + FSL_MC_ERR_SBE) & 0xff0000; 620 580 621 581 /* set threshold to 1 error per interrupt */ 622 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_SBE, 0x10000); 582 + ddr_out32(pdata, FSL_MC_ERR_SBE, 0x10000); 623 583 624 584 /* register interrupts */ 625 585 pdata->irq = platform_get_irq(op, 0); ··· 660 620 edac_dbg(0, "\n"); 661 621 662 622 if (edac_op_state == EDAC_OPSTATE_INT) { 663 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_INT_EN, 0); 623 + ddr_out32(pdata, FSL_MC_ERR_INT_EN, 0); 664 624 } 665 625 666 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_DISABLE, 667 - orig_ddr_err_disable); 668 - ddr_out32(pdata->mc_vbase + FSL_MC_ERR_SBE, orig_ddr_err_sbe); 626 + ddr_out32(pdata, FSL_MC_ERR_DISABLE, 627 + pdata->orig_ddr_err_disable); 628 + ddr_out32(pdata, FSL_MC_ERR_SBE, pdata->orig_ddr_err_sbe); 629 + 669 630 670 631 edac_mc_del_mc(&op->dev); 671 632 edac_mc_free(mci);
+13
drivers/edac/fsl_ddr_edac.h
··· 39 39 #define FSL_MC_CAPTURE_EXT_ADDRESS 0x0e54 40 40 #define FSL_MC_ERR_SBE 0x0e58 41 41 42 + #define IMX9_MC_ERR_EN 0x1000 43 + #define IMX9_MC_DATA_ERR_INJECT_OFF 0x100 44 + 42 45 #define DSC_MEM_EN 0x80000000 43 46 #define DSC_ECC_EN 0x20000000 44 47 #define DSC_RD_EN 0x10000000 45 48 #define DSC_DBW_MASK 0x00180000 46 49 #define DSC_DBW_32 0x00080000 47 50 #define DSC_DBW_64 0x00000000 51 + 52 + #define ERR_ECC_EN 0x80000000 53 + #define ERR_INLINE_ECC 0x40000000 48 54 49 55 #define DSC_SDTYPE_MASK 0x07000000 50 56 #define DSC_X32_EN 0x00000020 ··· 71 65 #define DDR_EDI_SBED 0x4 /* single-bit ECC error disable */ 72 66 #define DDR_EDI_MBED 0x8 /* multi-bit ECC error disable */ 73 67 68 + #define TYPE_IMX9 0x1 /* MC used by iMX9 having registers changed */ 69 + 74 70 struct fsl_mc_pdata { 75 71 char *name; 76 72 int edac_idx; 77 73 void __iomem *mc_vbase; 74 + void __iomem *inject_vbase; 78 75 int irq; 76 + u32 orig_ddr_err_disable; 77 + u32 orig_ddr_err_sbe; 78 + bool little_endian; 79 + unsigned long flag; 79 80 }; 80 81 int fsl_mc_err_probe(struct platform_device *op); 81 82 void fsl_mc_err_remove(struct platform_device *op);
+1
drivers/edac/i10nm_base.c
··· 1036 1036 return -ENODEV; 1037 1037 1038 1038 cfg = (struct res_config *)id->driver_data; 1039 + skx_set_res_cfg(cfg); 1039 1040 res_cfg = cfg; 1040 1041 1041 1042 rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
+6 -2
drivers/edac/ie31200_edac.c
··· 19 19 * 0c04: Xeon E3-1200 v3/4th Gen Core Processor DRAM Controller 20 20 * 0c08: Xeon E3-1200 v3 Processor DRAM Controller 21 21 * 1918: Xeon E3-1200 v5 Skylake Host Bridge/DRAM Registers 22 - * 5918: Xeon E3-1200 Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers 22 + * 590f: Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers 23 + * 5918: Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers 23 24 * 190f: 6th Gen Core Dual-Core Processor Host Bridge/DRAM Registers 24 25 * 191f: 6th Gen Core Quad-Core Processor Host Bridge/DRAM Registers 25 26 * 3e..: 8th/9th Gen Core Processor Host Bridge/DRAM Registers ··· 68 67 #define PCI_DEVICE_ID_INTEL_IE31200_HB_8 0x190F 69 68 #define PCI_DEVICE_ID_INTEL_IE31200_HB_9 0x1918 70 69 #define PCI_DEVICE_ID_INTEL_IE31200_HB_10 0x191F 71 - #define PCI_DEVICE_ID_INTEL_IE31200_HB_11 0x5918 70 + #define PCI_DEVICE_ID_INTEL_IE31200_HB_11 0x590f 71 + #define PCI_DEVICE_ID_INTEL_IE31200_HB_12 0x5918 72 72 73 73 /* Coffee Lake-S */ 74 74 #define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK 0x3e00 ··· 90 88 ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_9) || \ 91 89 ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_10) || \ 92 90 ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_11) || \ 91 + ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_12) || \ 93 92 (((did) & PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK) == \ 94 93 PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK)) 95 94 ··· 590 587 { PCI_VEND_DEV(INTEL, IE31200_HB_9), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, 591 588 { PCI_VEND_DEV(INTEL, IE31200_HB_10), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, 592 589 { PCI_VEND_DEV(INTEL, IE31200_HB_11), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, 590 + { PCI_VEND_DEV(INTEL, IE31200_HB_12), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, 593 591 { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_1), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, 594 592 { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_2), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, 595 593 { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_3), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 },
+47 -2
drivers/edac/igen6_edac.c
··· 263 263 #define DID_ARL_UH_SKU2 0x7d20 264 264 #define DID_ARL_UH_SKU3 0x7d30 265 265 266 + /* Compute die IDs for Panther Lake-H with IBECC */ 267 + #define DID_PTL_H_SKU1 0xb000 268 + #define DID_PTL_H_SKU2 0xb001 269 + #define DID_PTL_H_SKU3 0xb002 270 + 266 271 static int get_mchbar(struct pci_dev *pdev, u64 *mchbar) 267 272 { 268 273 union { ··· 610 605 { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU1), (kernel_ulong_t)&mtl_p_cfg }, 611 606 { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU2), (kernel_ulong_t)&mtl_p_cfg }, 612 607 { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU3), (kernel_ulong_t)&mtl_p_cfg }, 608 + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU1), (kernel_ulong_t)&mtl_p_cfg }, 609 + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU2), (kernel_ulong_t)&mtl_p_cfg }, 610 + { PCI_VDEVICE(INTEL, DID_PTL_H_SKU3), (kernel_ulong_t)&mtl_p_cfg }, 613 611 { }, 614 612 }; 615 613 MODULE_DEVICE_TABLE(pci, igen6_pci_tbl); ··· 1178 1170 return -ENODEV; 1179 1171 } 1180 1172 1173 + static void igen6_check(struct mem_ctl_info *mci) 1174 + { 1175 + struct igen6_imc *imc = mci->pvt_info; 1176 + u64 ecclog; 1177 + 1178 + /* errsts_clear() isn't NMI-safe. Delay it in the IRQ context */ 1179 + ecclog = ecclog_read_and_clear(imc); 1180 + if (!ecclog) 1181 + return; 1182 + 1183 + if (!ecclog_gen_pool_add(imc->mc, ecclog)) 1184 + irq_work_queue(&ecclog_irq_work); 1185 + } 1186 + 1181 1187 static int igen6_register_mci(int mc, u64 mchbar, struct pci_dev *pdev) 1182 1188 { 1183 1189 struct edac_mc_layer layers[2]; ··· 1233 1211 mci->edac_cap = EDAC_FLAG_SECDED; 1234 1212 mci->mod_name = EDAC_MOD_STR; 1235 1213 mci->dev_name = pci_name(pdev); 1214 + if (edac_op_state == EDAC_OPSTATE_POLL) 1215 + mci->edac_check = igen6_check; 1236 1216 mci->pvt_info = &igen6_pvt->imc[mc]; 1237 1217 1238 1218 imc = mci->pvt_info; ··· 1269 1245 imc->mci = mci; 1270 1246 return 0; 1271 1247 fail3: 1248 + mci->pvt_info = NULL; 1272 1249 kfree(mci->ctl_name); 1273 1250 fail2: 1274 1251 edac_mc_free(mci); ··· 1294 1269 1295 1270 edac_mc_del_mc(mci->pdev); 1296 1271 kfree(mci->ctl_name); 1272 + mci->pvt_info = NULL; 1297 1273 edac_mc_free(mci); 1298 1274 iounmap(imc->window); 1299 1275 } ··· 1374 1348 unregister_nmi_handler(NMI_SERR, IGEN6_NMI_NAME); 1375 1349 } 1376 1350 1351 + static void opstate_set(struct res_config *cfg, const struct pci_device_id *ent) 1352 + { 1353 + /* 1354 + * Quirk: Certain SoCs' error reporting interrupts don't work. 1355 + * Force polling mode for them to ensure that memory error 1356 + * events can be handled. 1357 + */ 1358 + if (ent->device == DID_ADL_N_SKU4) { 1359 + edac_op_state = EDAC_OPSTATE_POLL; 1360 + return; 1361 + } 1362 + 1363 + /* Set the mode according to the configuration data. */ 1364 + if (cfg->machine_check) 1365 + edac_op_state = EDAC_OPSTATE_INT; 1366 + else 1367 + edac_op_state = EDAC_OPSTATE_NMI; 1368 + } 1369 + 1377 1370 static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1378 1371 { 1379 1372 u64 mchbar; ··· 1409 1364 rc = igen6_pci_setup(pdev, &mchbar); 1410 1365 if (rc) 1411 1366 goto fail; 1367 + 1368 + opstate_set(res_cfg, ent); 1412 1369 1413 1370 for (i = 0; i < res_cfg->num_imc; i++) { 1414 1371 rc = igen6_register_mci(i, mchbar, pdev); ··· 1494 1447 owner = edac_get_owner(); 1495 1448 if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) 1496 1449 return -EBUSY; 1497 - 1498 - edac_op_state = EDAC_OPSTATE_NMI; 1499 1450 1500 1451 rc = pci_register_driver(&igen6_driver); 1501 1452 if (rc)
+1
drivers/edac/layerscape_edac.c
··· 21 21 22 22 static const struct of_device_id fsl_ddr_mc_err_of_match[] = { 23 23 { .compatible = "fsl,qoriq-memory-controller", }, 24 + { .compatible = "nxp,imx9-memory-controller", .data = (void *)TYPE_IMX9, }, 24 25 {}, 25 26 }; 26 27 MODULE_DEVICE_TABLE(of, fsl_ddr_mc_err_of_match);
+39 -18
drivers/edac/skx_common.c
··· 47 47 static u64 skx_tolm, skx_tohm; 48 48 static LIST_HEAD(dev_edac_list); 49 49 static bool skx_mem_cfg_2lm; 50 + static struct res_config *skx_res_cfg; 50 51 51 52 int skx_adxl_get(void) 52 53 { ··· 120 119 } 121 120 EXPORT_SYMBOL_GPL(skx_adxl_put); 122 121 123 - static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem) 122 + static bool skx_adxl_decode(struct decoded_addr *res, enum error_source err_src) 124 123 { 125 124 struct skx_dev *d; 126 125 int i, len = 0; ··· 136 135 return false; 137 136 } 138 137 138 + /* 139 + * GNR with a Flat2LM memory configuration may mistakenly classify 140 + * a near-memory error(DDR5) as a far-memory error(CXL), resulting 141 + * in the incorrect selection of decoded ADXL components. 142 + * To address this, prefetch the decoded far-memory controller ID 143 + * and adjust the error source to near-memory if the far-memory 144 + * controller ID is invalid. 145 + */ 146 + if (skx_res_cfg && skx_res_cfg->type == GNR && err_src == ERR_SRC_2LM_FM) { 147 + res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]]; 148 + if (res->imc == -1) { 149 + err_src = ERR_SRC_2LM_NM; 150 + edac_dbg(0, "Adjust the error source to near-memory.\n"); 151 + } 152 + } 153 + 139 154 res->socket = (int)adxl_values[component_indices[INDEX_SOCKET]]; 140 - if (error_in_1st_level_mem) { 155 + if (err_src == ERR_SRC_2LM_NM) { 141 156 res->imc = (adxl_nm_bitmap & BIT_NM_MEMCTRL) ? 142 157 (int)adxl_values[component_indices[INDEX_NM_MEMCTRL]] : -1; 143 158 res->channel = (adxl_nm_bitmap & BIT_NM_CHANNEL) ? ··· 207 190 skx_mem_cfg_2lm = mem_cfg_2lm; 208 191 } 209 192 EXPORT_SYMBOL_GPL(skx_set_mem_cfg); 193 + 194 + void skx_set_res_cfg(struct res_config *cfg) 195 + { 196 + skx_res_cfg = cfg; 197 + } 198 + EXPORT_SYMBOL_GPL(skx_set_res_cfg); 210 199 211 200 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log) 212 201 { ··· 643 620 optype, skx_msg); 644 621 } 645 622 646 - static bool skx_error_in_1st_level_mem(const struct mce *m) 623 + static enum error_source skx_error_source(const struct mce *m) 647 624 { 648 - u32 errcode; 625 + u32 errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK; 626 + 627 + if (errcode != MCACOD_MEM_CTL_ERR && errcode != MCACOD_EXT_MEM_ERR) 628 + return ERR_SRC_NOT_MEMORY; 649 629 650 630 if (!skx_mem_cfg_2lm) 651 - return false; 631 + return ERR_SRC_1LM; 652 632 653 - errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK; 633 + if (errcode == MCACOD_EXT_MEM_ERR) 634 + return ERR_SRC_2LM_NM; 654 635 655 - return errcode == MCACOD_EXT_MEM_ERR; 656 - } 657 - 658 - static bool skx_error_in_mem(const struct mce *m) 659 - { 660 - u32 errcode; 661 - 662 - errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK; 663 - 664 - return (errcode == MCACOD_MEM_CTL_ERR || errcode == MCACOD_EXT_MEM_ERR); 636 + return ERR_SRC_2LM_FM; 665 637 } 666 638 667 639 int skx_mce_check_error(struct notifier_block *nb, unsigned long val, 668 640 void *data) 669 641 { 670 642 struct mce *mce = (struct mce *)data; 643 + enum error_source err_src; 671 644 struct decoded_addr res; 672 645 struct mem_ctl_info *mci; 673 646 char *type; ··· 671 652 if (mce->kflags & MCE_HANDLED_CEC) 672 653 return NOTIFY_DONE; 673 654 655 + err_src = skx_error_source(mce); 656 + 674 657 /* Ignore unless this is memory related with an address */ 675 - if (!skx_error_in_mem(mce) || !(mce->status & MCI_STATUS_ADDRV)) 658 + if (err_src == ERR_SRC_NOT_MEMORY || !(mce->status & MCI_STATUS_ADDRV)) 676 659 return NOTIFY_DONE; 677 660 678 661 memset(&res, 0, sizeof(res)); ··· 688 667 /* Try driver decoder first */ 689 668 if (!(driver_decode && driver_decode(&res))) { 690 669 /* Then try firmware decoder (ACPI DSM methods) */ 691 - if (!(adxl_component_count && skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce)))) 670 + if (!(adxl_component_count && skx_adxl_decode(&res, err_src))) 692 671 return NOTIFY_DONE; 693 672 } 694 673
+8
drivers/edac/skx_common.h
··· 146 146 INDEX_MAX 147 147 }; 148 148 149 + enum error_source { 150 + ERR_SRC_1LM, 151 + ERR_SRC_2LM_NM, 152 + ERR_SRC_2LM_FM, 153 + ERR_SRC_NOT_MEMORY, 154 + }; 155 + 149 156 #define BIT_NM_MEMCTRL BIT_ULL(INDEX_NM_MEMCTRL) 150 157 #define BIT_NM_CHANNEL BIT_ULL(INDEX_NM_CHANNEL) 151 158 #define BIT_NM_DIMM BIT_ULL(INDEX_NM_DIMM) ··· 241 234 void skx_adxl_put(void); 242 235 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log); 243 236 void skx_set_mem_cfg(bool mem_cfg_2lm); 237 + void skx_set_res_cfg(struct res_config *cfg); 244 238 245 239 int skx_get_src_id(struct skx_dev *d, int off, u8 *id); 246 240 int skx_get_node_id(struct skx_dev *d, u8 *id);
+6 -2
drivers/ras/amd/atl/access.c
··· 70 70 u32 ficaa = 0; 71 71 72 72 node = get_accessible_node(node); 73 - if (node >= amd_nb_num()) 73 + if (node >= amd_nb_num()) { 74 + pr_debug("Node %u is out of bounds\n", node); 74 75 goto out; 76 + } 75 77 76 78 F4 = node_to_amd_nb(node)->link; 77 - if (!F4) 79 + if (!F4) { 80 + pr_debug("DF function 4 not found\n"); 78 81 goto out; 82 + } 79 83 80 84 /* Enable instance-specific access. */ 81 85 if (instance_id != DF_BROADCAST) {