1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2018, Advanced Micro Devices, Inc. 3 4 #include <linux/cper.h> 5 6 /* 7 * We don't need a "CPER_IA" prefix since these are all locally defined. 8 * This will save us a lot of line space. 9 */ 10 #define VALID_LAPIC_ID BIT_ULL(0) 11 #define VALID_CPUID_INFO BIT_ULL(1) 12 #define VALID_PROC_ERR_INFO_NUM(bits) (((bits) & GENMASK_ULL(7, 2)) >> 2) 13 #define VALID_PROC_CXT_INFO_NUM(bits) (((bits) & GENMASK_ULL(13, 8)) >> 8) 14 15 #define INFO_ERR_STRUCT_TYPE_CACHE \ 16 GUID_INIT(0xA55701F5, 0xE3EF, 0x43DE, 0xAC, 0x72, 0x24, 0x9B, \ 17 0x57, 0x3F, 0xAD, 0x2C) 18 #define INFO_ERR_STRUCT_TYPE_TLB \ 19 GUID_INIT(0xFC06B535, 0x5E1F, 0x4562, 0x9F, 0x25, 0x0A, 0x3B, \ 20 0x9A, 0xDB, 0x63, 0xC3) 21 #define INFO_ERR_STRUCT_TYPE_BUS \ 22 GUID_INIT(0x1CF3F8B3, 0xC5B1, 0x49a2, 0xAA, 0x59, 0x5E, 0xEF, \ 23 0x92, 0xFF, 0xA6, 0x3C) 24 #define INFO_ERR_STRUCT_TYPE_MS \ 25 GUID_INIT(0x48AB7F57, 0xDC34, 0x4f6c, 0xA7, 0xD3, 0xB0, 0xB5, \ 26 0xB0, 0xA7, 0x43, 0x14) 27 28 #define INFO_VALID_CHECK_INFO BIT_ULL(0) 29 #define INFO_VALID_TARGET_ID BIT_ULL(1) 30 #define INFO_VALID_REQUESTOR_ID BIT_ULL(2) 31 #define INFO_VALID_RESPONDER_ID BIT_ULL(3) 32 #define INFO_VALID_IP BIT_ULL(4) 33 34 #define CHECK_VALID_TRANS_TYPE BIT_ULL(0) 35 #define CHECK_VALID_OPERATION BIT_ULL(1) 36 #define CHECK_VALID_LEVEL BIT_ULL(2) 37 #define CHECK_VALID_PCC BIT_ULL(3) 38 #define CHECK_VALID_UNCORRECTED BIT_ULL(4) 39 #define CHECK_VALID_PRECISE_IP BIT_ULL(5) 40 #define CHECK_VALID_RESTARTABLE_IP BIT_ULL(6) 41 #define CHECK_VALID_OVERFLOW BIT_ULL(7) 42 43 #define CHECK_VALID_BUS_PART_TYPE BIT_ULL(8) 44 #define CHECK_VALID_BUS_TIME_OUT BIT_ULL(9) 45 #define CHECK_VALID_BUS_ADDR_SPACE BIT_ULL(10) 46 47 #define CHECK_VALID_BITS(check) (((check) & GENMASK_ULL(15, 0))) 48 #define CHECK_TRANS_TYPE(check) (((check) & GENMASK_ULL(17, 16)) >> 16) 49 #define CHECK_OPERATION(check) (((check) & GENMASK_ULL(21, 18)) >> 18) 50 #define CHECK_LEVEL(check) (((check) & GENMASK_ULL(24, 22)) >> 22) 51 #define CHECK_PCC BIT_ULL(25) 52 #define CHECK_UNCORRECTED BIT_ULL(26) 53 #define CHECK_PRECISE_IP BIT_ULL(27) 54 #define CHECK_RESTARTABLE_IP BIT_ULL(28) 55 #define CHECK_OVERFLOW BIT_ULL(29) 56 57 #define CHECK_BUS_PART_TYPE(check) (((check) & GENMASK_ULL(31, 30)) >> 30) 58 #define CHECK_BUS_TIME_OUT BIT_ULL(32) 59 #define CHECK_BUS_ADDR_SPACE(check) (((check) & GENMASK_ULL(34, 33)) >> 33) 60 61 #define CHECK_VALID_MS_ERR_TYPE BIT_ULL(0) 62 #define CHECK_VALID_MS_PCC BIT_ULL(1) 63 #define CHECK_VALID_MS_UNCORRECTED BIT_ULL(2) 64 #define CHECK_VALID_MS_PRECISE_IP BIT_ULL(3) 65 #define CHECK_VALID_MS_RESTARTABLE_IP BIT_ULL(4) 66 #define CHECK_VALID_MS_OVERFLOW BIT_ULL(5) 67 68 #define CHECK_MS_ERR_TYPE(check) (((check) & GENMASK_ULL(18, 16)) >> 16) 69 #define CHECK_MS_PCC BIT_ULL(19) 70 #define CHECK_MS_UNCORRECTED BIT_ULL(20) 71 #define CHECK_MS_PRECISE_IP BIT_ULL(21) 72 #define CHECK_MS_RESTARTABLE_IP BIT_ULL(22) 73 #define CHECK_MS_OVERFLOW BIT_ULL(23) 74 75 #define CTX_TYPE_MSR 1 76 #define CTX_TYPE_MMREG 7 77 78 enum err_types { 79 ERR_TYPE_CACHE = 0, 80 ERR_TYPE_TLB, 81 ERR_TYPE_BUS, 82 ERR_TYPE_MS, 83 N_ERR_TYPES 84 }; 85 86 static enum err_types cper_get_err_type(const guid_t *err_type) 87 { 88 if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_CACHE)) 89 return ERR_TYPE_CACHE; 90 else if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_TLB)) 91 return ERR_TYPE_TLB; 92 else if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_BUS)) 93 return ERR_TYPE_BUS; 94 else if (guid_equal(err_type, &INFO_ERR_STRUCT_TYPE_MS)) 95 return ERR_TYPE_MS; 96 else 97 return N_ERR_TYPES; 98 } 99 100 static const char * const ia_check_trans_type_strs[] = { 101 "Instruction", 102 "Data Access", 103 "Generic", 104 }; 105 106 static const char * const ia_check_op_strs[] = { 107 "generic error", 108 "generic read", 109 "generic write", 110 "data read", 111 "data write", 112 "instruction fetch", 113 "prefetch", 114 "eviction", 115 "snoop", 116 }; 117 118 static const char * const ia_check_bus_part_type_strs[] = { 119 "Local Processor originated request", 120 "Local Processor responded to request", 121 "Local Processor observed", 122 "Generic", 123 }; 124 125 static const char * const ia_check_bus_addr_space_strs[] = { 126 "Memory Access", 127 "Reserved", 128 "I/O", 129 "Other Transaction", 130 }; 131 132 static const char * const ia_check_ms_error_type_strs[] = { 133 "No Error", 134 "Unclassified", 135 "Microcode ROM Parity Error", 136 "External Error", 137 "FRC Error", 138 "Internal Unclassified", 139 }; 140 141 static const char * const ia_reg_ctx_strs[] = { 142 "Unclassified Data", 143 "MSR Registers (Machine Check and other MSRs)", 144 "32-bit Mode Execution Context", 145 "64-bit Mode Execution Context", 146 "FXSAVE Context", 147 "32-bit Mode Debug Registers (DR0-DR7)", 148 "64-bit Mode Debug Registers (DR0-DR7)", 149 "Memory Mapped Registers", 150 }; 151 152 static inline void print_bool(char *str, const char *pfx, u64 check, u64 bit) 153 { 154 printk("%s%s: %s\n", pfx, str, (check & bit) ? "true" : "false"); 155 } 156 157 static void print_err_info_ms(const char *pfx, u16 validation_bits, u64 check) 158 { 159 if (validation_bits & CHECK_VALID_MS_ERR_TYPE) { 160 u8 err_type = CHECK_MS_ERR_TYPE(check); 161 162 printk("%sError Type: %u, %s\n", pfx, err_type, 163 err_type < ARRAY_SIZE(ia_check_ms_error_type_strs) ? 164 ia_check_ms_error_type_strs[err_type] : "unknown"); 165 } 166 167 if (validation_bits & CHECK_VALID_MS_PCC) 168 print_bool("Processor Context Corrupt", pfx, check, CHECK_MS_PCC); 169 170 if (validation_bits & CHECK_VALID_MS_UNCORRECTED) 171 print_bool("Uncorrected", pfx, check, CHECK_MS_UNCORRECTED); 172 173 if (validation_bits & CHECK_VALID_MS_PRECISE_IP) 174 print_bool("Precise IP", pfx, check, CHECK_MS_PRECISE_IP); 175 176 if (validation_bits & CHECK_VALID_MS_RESTARTABLE_IP) 177 print_bool("Restartable IP", pfx, check, CHECK_MS_RESTARTABLE_IP); 178 179 if (validation_bits & CHECK_VALID_MS_OVERFLOW) 180 print_bool("Overflow", pfx, check, CHECK_MS_OVERFLOW); 181 } 182 183 static void print_err_info(const char *pfx, u8 err_type, u64 check) 184 { 185 u16 validation_bits = CHECK_VALID_BITS(check); 186 187 /* 188 * The MS Check structure varies a lot from the others, so use a 189 * separate function for decoding. 190 */ 191 if (err_type == ERR_TYPE_MS) 192 return print_err_info_ms(pfx, validation_bits, check); 193 194 if (validation_bits & CHECK_VALID_TRANS_TYPE) { 195 u8 trans_type = CHECK_TRANS_TYPE(check); 196 197 printk("%sTransaction Type: %u, %s\n", pfx, trans_type, 198 trans_type < ARRAY_SIZE(ia_check_trans_type_strs) ? 199 ia_check_trans_type_strs[trans_type] : "unknown"); 200 } 201 202 if (validation_bits & CHECK_VALID_OPERATION) { 203 u8 op = CHECK_OPERATION(check); 204 205 /* 206 * CACHE has more operation types than TLB or BUS, though the 207 * name and the order are the same. 208 */ 209 u8 max_ops = (err_type == ERR_TYPE_CACHE) ? 9 : 7; 210 211 printk("%sOperation: %u, %s\n", pfx, op, 212 op < max_ops ? ia_check_op_strs[op] : "unknown"); 213 } 214 215 if (validation_bits & CHECK_VALID_LEVEL) 216 printk("%sLevel: %llu\n", pfx, CHECK_LEVEL(check)); 217 218 if (validation_bits & CHECK_VALID_PCC) 219 print_bool("Processor Context Corrupt", pfx, check, CHECK_PCC); 220 221 if (validation_bits & CHECK_VALID_UNCORRECTED) 222 print_bool("Uncorrected", pfx, check, CHECK_UNCORRECTED); 223 224 if (validation_bits & CHECK_VALID_PRECISE_IP) 225 print_bool("Precise IP", pfx, check, CHECK_PRECISE_IP); 226 227 if (validation_bits & CHECK_VALID_RESTARTABLE_IP) 228 print_bool("Restartable IP", pfx, check, CHECK_RESTARTABLE_IP); 229 230 if (validation_bits & CHECK_VALID_OVERFLOW) 231 print_bool("Overflow", pfx, check, CHECK_OVERFLOW); 232 233 if (err_type != ERR_TYPE_BUS) 234 return; 235 236 if (validation_bits & CHECK_VALID_BUS_PART_TYPE) { 237 u8 part_type = CHECK_BUS_PART_TYPE(check); 238 239 printk("%sParticipation Type: %u, %s\n", pfx, part_type, 240 part_type < ARRAY_SIZE(ia_check_bus_part_type_strs) ? 241 ia_check_bus_part_type_strs[part_type] : "unknown"); 242 } 243 244 if (validation_bits & CHECK_VALID_BUS_TIME_OUT) 245 print_bool("Time Out", pfx, check, CHECK_BUS_TIME_OUT); 246 247 if (validation_bits & CHECK_VALID_BUS_ADDR_SPACE) { 248 u8 addr_space = CHECK_BUS_ADDR_SPACE(check); 249 250 printk("%sAddress Space: %u, %s\n", pfx, addr_space, 251 addr_space < ARRAY_SIZE(ia_check_bus_addr_space_strs) ? 252 ia_check_bus_addr_space_strs[addr_space] : "unknown"); 253 } 254 } 255 256 void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc) 257 { 258 int i; 259 struct cper_ia_err_info *err_info; 260 struct cper_ia_proc_ctx *ctx_info; 261 char newpfx[64], infopfx[64]; 262 u8 err_type; 263 264 if (proc->validation_bits & VALID_LAPIC_ID) 265 printk("%sLocal APIC_ID: 0x%llx\n", pfx, proc->lapic_id); 266 267 if (proc->validation_bits & VALID_CPUID_INFO) { 268 printk("%sCPUID Info:\n", pfx); 269 print_hex_dump(pfx, "", DUMP_PREFIX_OFFSET, 16, 4, proc->cpuid, 270 sizeof(proc->cpuid), 0); 271 } 272 273 snprintf(newpfx, sizeof(newpfx), "%s ", pfx); 274 275 err_info = (struct cper_ia_err_info *)(proc + 1); 276 for (i = 0; i < VALID_PROC_ERR_INFO_NUM(proc->validation_bits); i++) { 277 printk("%sError Information Structure %d:\n", pfx, i); 278 279 err_type = cper_get_err_type(&err_info->err_type); 280 printk("%sError Structure Type: %s\n", newpfx, 281 err_type < ARRAY_SIZE(cper_proc_error_type_strs) ? 282 cper_proc_error_type_strs[err_type] : "unknown"); 283 284 if (err_type >= N_ERR_TYPES) { 285 printk("%sError Structure Type: %pUl\n", newpfx, 286 &err_info->err_type); 287 } 288 289 if (err_info->validation_bits & INFO_VALID_CHECK_INFO) { 290 printk("%sCheck Information: 0x%016llx\n", newpfx, 291 err_info->check_info); 292 293 if (err_type < N_ERR_TYPES) { 294 snprintf(infopfx, sizeof(infopfx), "%s ", 295 newpfx); 296 297 print_err_info(infopfx, err_type, 298 err_info->check_info); 299 } 300 } 301 302 if (err_info->validation_bits & INFO_VALID_TARGET_ID) { 303 printk("%sTarget Identifier: 0x%016llx\n", 304 newpfx, err_info->target_id); 305 } 306 307 if (err_info->validation_bits & INFO_VALID_REQUESTOR_ID) { 308 printk("%sRequestor Identifier: 0x%016llx\n", 309 newpfx, err_info->requestor_id); 310 } 311 312 if (err_info->validation_bits & INFO_VALID_RESPONDER_ID) { 313 printk("%sResponder Identifier: 0x%016llx\n", 314 newpfx, err_info->responder_id); 315 } 316 317 if (err_info->validation_bits & INFO_VALID_IP) { 318 printk("%sInstruction Pointer: 0x%016llx\n", 319 newpfx, err_info->ip); 320 } 321 322 err_info++; 323 } 324 325 ctx_info = (struct cper_ia_proc_ctx *)err_info; 326 for (i = 0; i < VALID_PROC_CXT_INFO_NUM(proc->validation_bits); i++) { 327 int size = sizeof(*ctx_info) + ctx_info->reg_arr_size; 328 int groupsize = 4; 329 330 printk("%sContext Information Structure %d:\n", pfx, i); 331 332 printk("%sRegister Context Type: %s\n", newpfx, 333 ctx_info->reg_ctx_type < ARRAY_SIZE(ia_reg_ctx_strs) ? 334 ia_reg_ctx_strs[ctx_info->reg_ctx_type] : "unknown"); 335 336 printk("%sRegister Array Size: 0x%04x\n", newpfx, 337 ctx_info->reg_arr_size); 338 339 if (ctx_info->reg_ctx_type == CTX_TYPE_MSR) { 340 groupsize = 8; /* MSRs are 8 bytes wide. */ 341 printk("%sMSR Address: 0x%08x\n", newpfx, 342 ctx_info->msr_addr); 343 } 344 345 if (ctx_info->reg_ctx_type == CTX_TYPE_MMREG) { 346 printk("%sMM Register Address: 0x%016llx\n", newpfx, 347 ctx_info->mm_reg_addr); 348 } 349 350 printk("%sRegister Array:\n", newpfx); 351 print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, groupsize, 352 (ctx_info + 1), ctx_info->reg_arr_size, 0); 353 354 ctx_info = (struct cper_ia_proc_ctx *)((long)ctx_info + size); 355 } 356 } 357