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_urgent_for_v6.10_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras

Pull EDAC fixes from Borislav Petkov:

- Fix two issues with MI300 address translation logic

* tag 'edac_urgent_for_v6.10_rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
RAS/AMD/ATL: Use system settings for MI300 DRAM to normalized address translation
RAS/AMD/ATL: Fix MI300 bank hash

+116 -48
+1 -1
drivers/ras/amd/atl/internal.h
··· 224 224 225 225 int get_df_system_info(void); 226 226 int determine_node_id(struct addr_ctx *ctx, u8 socket_num, u8 die_num); 227 - int get_addr_hash_mi300(void); 227 + int get_umc_info_mi300(void); 228 228 229 229 int get_address_map(struct addr_ctx *ctx); 230 230
+1 -1
drivers/ras/amd/atl/system.c
··· 127 127 if (reg == DF_FUNC0_ID_MI300) { 128 128 df_cfg.flags.heterogeneous = 1; 129 129 130 - if (get_addr_hash_mi300()) 130 + if (get_umc_info_mi300()) 131 131 return -EINVAL; 132 132 } 133 133
+114 -46
drivers/ras/amd/atl/umc.c
··· 68 68 }; 69 69 70 70 #define NUM_BANK_BITS 4 71 + #define NUM_COL_BITS 5 72 + #define NUM_SID_BITS 2 71 73 72 74 static struct { 73 75 /* UMC::CH::AddrHashBank */ ··· 82 80 u8 bank_xor; 83 81 } addr_hash; 84 82 83 + static struct { 84 + u8 bank[NUM_BANK_BITS]; 85 + u8 col[NUM_COL_BITS]; 86 + u8 sid[NUM_SID_BITS]; 87 + u8 num_row_lo; 88 + u8 num_row_hi; 89 + u8 row_lo; 90 + u8 row_hi; 91 + u8 pc; 92 + } bit_shifts; 93 + 85 94 #define MI300_UMC_CH_BASE 0x90000 95 + #define MI300_ADDR_CFG (MI300_UMC_CH_BASE + 0x30) 96 + #define MI300_ADDR_SEL (MI300_UMC_CH_BASE + 0x40) 97 + #define MI300_COL_SEL_LO (MI300_UMC_CH_BASE + 0x50) 98 + #define MI300_ADDR_SEL_2 (MI300_UMC_CH_BASE + 0xA4) 86 99 #define MI300_ADDR_HASH_BANK0 (MI300_UMC_CH_BASE + 0xC8) 87 100 #define MI300_ADDR_HASH_PC (MI300_UMC_CH_BASE + 0xE0) 88 101 #define MI300_ADDR_HASH_PC2 (MI300_UMC_CH_BASE + 0xE4) ··· 107 90 #define ADDR_HASH_ROW_XOR GENMASK(31, 14) 108 91 #define ADDR_HASH_BANK_XOR GENMASK(5, 0) 109 92 93 + #define ADDR_CFG_NUM_ROW_LO GENMASK(11, 8) 94 + #define ADDR_CFG_NUM_ROW_HI GENMASK(15, 12) 95 + 96 + #define ADDR_SEL_BANK0 GENMASK(3, 0) 97 + #define ADDR_SEL_BANK1 GENMASK(7, 4) 98 + #define ADDR_SEL_BANK2 GENMASK(11, 8) 99 + #define ADDR_SEL_BANK3 GENMASK(15, 12) 100 + #define ADDR_SEL_BANK4 GENMASK(20, 16) 101 + #define ADDR_SEL_ROW_LO GENMASK(27, 24) 102 + #define ADDR_SEL_ROW_HI GENMASK(31, 28) 103 + 104 + #define COL_SEL_LO_COL0 GENMASK(3, 0) 105 + #define COL_SEL_LO_COL1 GENMASK(7, 4) 106 + #define COL_SEL_LO_COL2 GENMASK(11, 8) 107 + #define COL_SEL_LO_COL3 GENMASK(15, 12) 108 + #define COL_SEL_LO_COL4 GENMASK(19, 16) 109 + 110 + #define ADDR_SEL_2_BANK5 GENMASK(4, 0) 111 + #define ADDR_SEL_2_CHAN GENMASK(15, 12) 112 + 110 113 /* 111 114 * Read UMC::CH::AddrHash{Bank,PC,PC2} registers to get XOR bits used 112 - * for hashing. Do this during module init, since the values will not 113 - * change during run time. 115 + * for hashing. 116 + * 117 + * Also, read UMC::CH::Addr{Cfg,Sel,Sel2} and UMC::CH:ColSelLo registers to 118 + * get the values needed to reconstruct the normalized address. Apply additional 119 + * offsets to the raw register values, as needed. 120 + * 121 + * Do this during module init, since the values will not change during run time. 114 122 * 115 123 * These registers are instantiated for each UMC across each AMD Node. 116 124 * However, they should be identically programmed due to the fixed hardware 117 125 * design of MI300 systems. So read the values from Node 0 UMC 0 and keep a 118 126 * single global structure for simplicity. 119 127 */ 120 - int get_addr_hash_mi300(void) 128 + int get_umc_info_mi300(void) 121 129 { 122 130 u32 temp; 123 131 int ret; ··· 172 130 173 131 addr_hash.bank_xor = FIELD_GET(ADDR_HASH_BANK_XOR, temp); 174 132 133 + ret = amd_smn_read(0, MI300_ADDR_CFG, &temp); 134 + if (ret) 135 + return ret; 136 + 137 + bit_shifts.num_row_hi = FIELD_GET(ADDR_CFG_NUM_ROW_HI, temp); 138 + bit_shifts.num_row_lo = 10 + FIELD_GET(ADDR_CFG_NUM_ROW_LO, temp); 139 + 140 + ret = amd_smn_read(0, MI300_ADDR_SEL, &temp); 141 + if (ret) 142 + return ret; 143 + 144 + bit_shifts.bank[0] = 5 + FIELD_GET(ADDR_SEL_BANK0, temp); 145 + bit_shifts.bank[1] = 5 + FIELD_GET(ADDR_SEL_BANK1, temp); 146 + bit_shifts.bank[2] = 5 + FIELD_GET(ADDR_SEL_BANK2, temp); 147 + bit_shifts.bank[3] = 5 + FIELD_GET(ADDR_SEL_BANK3, temp); 148 + /* Use BankBit4 for the SID0 position. */ 149 + bit_shifts.sid[0] = 5 + FIELD_GET(ADDR_SEL_BANK4, temp); 150 + bit_shifts.row_lo = 12 + FIELD_GET(ADDR_SEL_ROW_LO, temp); 151 + bit_shifts.row_hi = 24 + FIELD_GET(ADDR_SEL_ROW_HI, temp); 152 + 153 + ret = amd_smn_read(0, MI300_COL_SEL_LO, &temp); 154 + if (ret) 155 + return ret; 156 + 157 + bit_shifts.col[0] = 2 + FIELD_GET(COL_SEL_LO_COL0, temp); 158 + bit_shifts.col[1] = 2 + FIELD_GET(COL_SEL_LO_COL1, temp); 159 + bit_shifts.col[2] = 2 + FIELD_GET(COL_SEL_LO_COL2, temp); 160 + bit_shifts.col[3] = 2 + FIELD_GET(COL_SEL_LO_COL3, temp); 161 + bit_shifts.col[4] = 2 + FIELD_GET(COL_SEL_LO_COL4, temp); 162 + 163 + ret = amd_smn_read(0, MI300_ADDR_SEL_2, &temp); 164 + if (ret) 165 + return ret; 166 + 167 + /* Use BankBit5 for the SID1 position. */ 168 + bit_shifts.sid[1] = 5 + FIELD_GET(ADDR_SEL_2_BANK5, temp); 169 + bit_shifts.pc = 5 + FIELD_GET(ADDR_SEL_2_CHAN, temp); 170 + 175 171 return 0; 176 172 } 177 173 ··· 226 146 * The MCA address format is as follows: 227 147 * MCA_ADDR[27:0] = {S[1:0], P[0], R[14:0], B[3:0], C[4:0], Z[0]} 228 148 * 229 - * The normalized address format is fixed in hardware and is as follows: 230 - * NA[30:0] = {S[1:0], R[13:0], C4, B[1:0], B[3:2], C[3:2], P, C[1:0], Z[4:0]} 231 - * 232 149 * Additionally, the PC and Bank bits may be hashed. This must be accounted for before 233 150 * reconstructing the normalized address. 234 151 */ ··· 235 158 #define MI300_UMC_MCA_PC BIT(25) 236 159 #define MI300_UMC_MCA_SID GENMASK(27, 26) 237 160 238 - #define MI300_NA_COL_1_0 GENMASK(6, 5) 239 - #define MI300_NA_PC BIT(7) 240 - #define MI300_NA_COL_3_2 GENMASK(9, 8) 241 - #define MI300_NA_BANK_3_2 GENMASK(11, 10) 242 - #define MI300_NA_BANK_1_0 GENMASK(13, 12) 243 - #define MI300_NA_COL_4 BIT(14) 244 - #define MI300_NA_ROW GENMASK(28, 15) 245 - #define MI300_NA_SID GENMASK(30, 29) 246 - 247 161 static unsigned long convert_dram_to_norm_addr_mi300(unsigned long addr) 248 162 { 249 - u16 i, col, row, bank, pc, sid, temp; 163 + u16 i, col, row, bank, pc, sid; 164 + u32 temp; 250 165 251 166 col = FIELD_GET(MI300_UMC_MCA_COL, addr); 252 167 bank = FIELD_GET(MI300_UMC_MCA_BANK, addr); ··· 258 189 259 190 /* Calculate hash for PC bit. */ 260 191 if (addr_hash.pc.xor_enable) { 261 - /* Bits SID[1:0] act as Bank[6:5] for PC hash, so apply them here. */ 262 - bank |= sid << 5; 263 - 264 192 temp = bitwise_xor_bits(col & addr_hash.pc.col_xor); 265 193 temp ^= bitwise_xor_bits(row & addr_hash.pc.row_xor); 266 - temp ^= bitwise_xor_bits(bank & addr_hash.bank_xor); 194 + /* Bits SID[1:0] act as Bank[5:4] for PC hash, so apply them here. */ 195 + temp ^= bitwise_xor_bits((bank | sid << NUM_BANK_BITS) & addr_hash.bank_xor); 267 196 pc ^= temp; 268 - 269 - /* Drop SID bits for the sake of debug printing later. */ 270 - bank &= 0x1F; 271 197 } 272 198 273 199 /* Reconstruct the normalized address starting with NA[4:0] = 0 */ 274 200 addr = 0; 275 201 276 - /* NA[6:5] = Column[1:0] */ 277 - temp = col & 0x3; 278 - addr |= FIELD_PREP(MI300_NA_COL_1_0, temp); 202 + /* Column bits */ 203 + for (i = 0; i < NUM_COL_BITS; i++) { 204 + temp = (col >> i) & 0x1; 205 + addr |= temp << bit_shifts.col[i]; 206 + } 279 207 280 - /* NA[7] = PC */ 281 - addr |= FIELD_PREP(MI300_NA_PC, pc); 208 + /* Bank bits */ 209 + for (i = 0; i < NUM_BANK_BITS; i++) { 210 + temp = (bank >> i) & 0x1; 211 + addr |= temp << bit_shifts.bank[i]; 212 + } 282 213 283 - /* NA[9:8] = Column[3:2] */ 284 - temp = (col >> 2) & 0x3; 285 - addr |= FIELD_PREP(MI300_NA_COL_3_2, temp); 214 + /* Row lo bits */ 215 + for (i = 0; i < bit_shifts.num_row_lo; i++) { 216 + temp = (row >> i) & 0x1; 217 + addr |= temp << (i + bit_shifts.row_lo); 218 + } 286 219 287 - /* NA[11:10] = Bank[3:2] */ 288 - temp = (bank >> 2) & 0x3; 289 - addr |= FIELD_PREP(MI300_NA_BANK_3_2, temp); 220 + /* Row hi bits */ 221 + for (i = 0; i < bit_shifts.num_row_hi; i++) { 222 + temp = (row >> (i + bit_shifts.num_row_lo)) & 0x1; 223 + addr |= temp << (i + bit_shifts.row_hi); 224 + } 290 225 291 - /* NA[13:12] = Bank[1:0] */ 292 - temp = bank & 0x3; 293 - addr |= FIELD_PREP(MI300_NA_BANK_1_0, temp); 226 + /* PC bit */ 227 + addr |= pc << bit_shifts.pc; 294 228 295 - /* NA[14] = Column[4] */ 296 - temp = (col >> 4) & 0x1; 297 - addr |= FIELD_PREP(MI300_NA_COL_4, temp); 298 - 299 - /* NA[28:15] = Row[13:0] */ 300 - addr |= FIELD_PREP(MI300_NA_ROW, row); 301 - 302 - /* NA[30:29] = SID[1:0] */ 303 - addr |= FIELD_PREP(MI300_NA_SID, sid); 229 + /* SID bits */ 230 + for (i = 0; i < NUM_SID_BITS; i++) { 231 + temp = (sid >> i) & 0x1; 232 + addr |= temp << bit_shifts.sid[i]; 233 + } 304 234 305 235 pr_debug("Addr=0x%016lx", addr); 306 236 pr_debug("Bank=%u Row=%u Column=%u PC=%u SID=%u", bank, row, col, pc, sid);