Merge tag 'edac_urgent_for_v6.16_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC fix from Borislav Petkov:

- Consider secondary address mask registers in amd64_edac in order to
get the correct total memory size of the system

* tag 'edac_urgent_for_v6.16_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
EDAC/amd64: Fix size calculation for Non-Power-of-Two DIMMs

Changed files
+36 -21
drivers
+36 -21
drivers/edac/amd64_edac.c
··· 1209 1209 if (csrow_enabled(2 * dimm + 1, ctrl, pvt)) 1210 1210 cs_mode |= CS_ODD_PRIMARY; 1211 1211 1212 - /* Asymmetric dual-rank DIMM support. */ 1212 + if (csrow_sec_enabled(2 * dimm, ctrl, pvt)) 1213 + cs_mode |= CS_EVEN_SECONDARY; 1214 + 1213 1215 if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt)) 1214 1216 cs_mode |= CS_ODD_SECONDARY; 1215 1217 ··· 1232 1230 return cs_mode; 1233 1231 } 1234 1232 1235 - static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode, 1236 - int csrow_nr, int dimm) 1233 + static int calculate_cs_size(u32 mask, unsigned int cs_mode) 1237 1234 { 1238 - u32 msb, weight, num_zero_bits; 1239 - u32 addr_mask_deinterleaved; 1240 - int size = 0; 1235 + int msb, weight, num_zero_bits; 1236 + u32 deinterleaved_mask; 1237 + 1238 + if (!mask) 1239 + return 0; 1241 1240 1242 1241 /* 1243 1242 * The number of zero bits in the mask is equal to the number of bits ··· 1251 1248 * without swapping with the most significant bit. This can be handled 1252 1249 * by keeping the MSB where it is and ignoring the single zero bit. 1253 1250 */ 1254 - msb = fls(addr_mask_orig) - 1; 1255 - weight = hweight_long(addr_mask_orig); 1251 + msb = fls(mask) - 1; 1252 + weight = hweight_long(mask); 1256 1253 num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE); 1257 1254 1258 1255 /* Take the number of zero bits off from the top of the mask. */ 1259 - addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1); 1256 + deinterleaved_mask = GENMASK(msb - num_zero_bits, 1); 1257 + edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", deinterleaved_mask); 1258 + 1259 + return (deinterleaved_mask >> 2) + 1; 1260 + } 1261 + 1262 + static int __addr_mask_to_cs_size(u32 addr_mask, u32 addr_mask_sec, 1263 + unsigned int cs_mode, int csrow_nr, int dimm) 1264 + { 1265 + int size; 1260 1266 1261 1267 edac_dbg(1, "CS%d DIMM%d AddrMasks:\n", csrow_nr, dimm); 1262 - edac_dbg(1, " Original AddrMask: 0x%x\n", addr_mask_orig); 1263 - edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", addr_mask_deinterleaved); 1268 + edac_dbg(1, " Primary AddrMask: 0x%x\n", addr_mask); 1264 1269 1265 1270 /* Register [31:1] = Address [39:9]. Size is in kBs here. */ 1266 - size = (addr_mask_deinterleaved >> 2) + 1; 1271 + size = calculate_cs_size(addr_mask, cs_mode); 1272 + 1273 + edac_dbg(1, " Secondary AddrMask: 0x%x\n", addr_mask_sec); 1274 + size += calculate_cs_size(addr_mask_sec, cs_mode); 1267 1275 1268 1276 /* Return size in MBs. */ 1269 1277 return size >> 10; ··· 1283 1269 static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, 1284 1270 unsigned int cs_mode, int csrow_nr) 1285 1271 { 1272 + u32 addr_mask = 0, addr_mask_sec = 0; 1286 1273 int cs_mask_nr = csrow_nr; 1287 - u32 addr_mask_orig; 1288 1274 int dimm, size = 0; 1289 1275 1290 1276 /* No Chip Selects are enabled. */ ··· 1322 1308 if (!pvt->flags.zn_regs_v2) 1323 1309 cs_mask_nr >>= 1; 1324 1310 1325 - /* Asymmetric dual-rank DIMM support. */ 1326 - if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY)) 1327 - addr_mask_orig = pvt->csels[umc].csmasks_sec[cs_mask_nr]; 1328 - else 1329 - addr_mask_orig = pvt->csels[umc].csmasks[cs_mask_nr]; 1311 + if (cs_mode & (CS_EVEN_PRIMARY | CS_ODD_PRIMARY)) 1312 + addr_mask = pvt->csels[umc].csmasks[cs_mask_nr]; 1330 1313 1331 - return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, dimm); 1314 + if (cs_mode & (CS_EVEN_SECONDARY | CS_ODD_SECONDARY)) 1315 + addr_mask_sec = pvt->csels[umc].csmasks_sec[cs_mask_nr]; 1316 + 1317 + return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, dimm); 1332 1318 } 1333 1319 1334 1320 static void umc_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) ··· 3526 3512 static int gpu_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, 3527 3513 unsigned int cs_mode, int csrow_nr) 3528 3514 { 3529 - u32 addr_mask_orig = pvt->csels[umc].csmasks[csrow_nr]; 3515 + u32 addr_mask = pvt->csels[umc].csmasks[csrow_nr]; 3516 + u32 addr_mask_sec = pvt->csels[umc].csmasks_sec[csrow_nr]; 3530 3517 3531 - return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, csrow_nr >> 1); 3518 + return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, csrow_nr >> 1); 3532 3519 } 3533 3520 3534 3521 static void gpu_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)