1 /* 2 * UEFI Common Platform Error Record (CPER) support 3 * 4 * Copyright (C) 2017, The Linux Foundation. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #include <linux/kernel.h> 21 #include <linux/module.h> 22 #include <linux/time.h> 23 #include <linux/cper.h> 24 #include <linux/dmi.h> 25 #include <linux/acpi.h> 26 #include <linux/pci.h> 27 #include <linux/aer.h> 28 #include <linux/printk.h> 29 #include <linux/bcd.h> 30 #include <acpi/ghes.h> 31 #include <ras/ras_event.h> 32 33 static const char * const arm_reg_ctx_strs[] = { 34 "AArch32 general purpose registers", 35 "AArch32 EL1 context registers", 36 "AArch32 EL2 context registers", 37 "AArch32 secure context registers", 38 "AArch64 general purpose registers", 39 "AArch64 EL1 context registers", 40 "AArch64 EL2 context registers", 41 "AArch64 EL3 context registers", 42 "Misc. system register structure", 43 }; 44 45 static const char * const arm_err_trans_type_strs[] = { 46 "Instruction", 47 "Data Access", 48 "Generic", 49 }; 50 51 static const char * const arm_bus_err_op_strs[] = { 52 "Generic error (type cannot be determined)", 53 "Generic read (type of instruction or data request cannot be determined)", 54 "Generic write (type of instruction of data request cannot be determined)", 55 "Data read", 56 "Data write", 57 "Instruction fetch", 58 "Prefetch", 59 }; 60 61 static const char * const arm_cache_err_op_strs[] = { 62 "Generic error (type cannot be determined)", 63 "Generic read (type of instruction or data request cannot be determined)", 64 "Generic write (type of instruction of data request cannot be determined)", 65 "Data read", 66 "Data write", 67 "Instruction fetch", 68 "Prefetch", 69 "Eviction", 70 "Snooping (processor initiated a cache snoop that resulted in an error)", 71 "Snooped (processor raised a cache error caused by another processor or device snooping its cache)", 72 "Management", 73 }; 74 75 static const char * const arm_tlb_err_op_strs[] = { 76 "Generic error (type cannot be determined)", 77 "Generic read (type of instruction or data request cannot be determined)", 78 "Generic write (type of instruction of data request cannot be determined)", 79 "Data read", 80 "Data write", 81 "Instruction fetch", 82 "Prefetch", 83 "Local management operation (processor initiated a TLB management operation that resulted in an error)", 84 "External management operation (processor raised a TLB error caused by another processor or device broadcasting TLB operations)", 85 }; 86 87 static const char * const arm_bus_err_part_type_strs[] = { 88 "Local processor originated request", 89 "Local processor responded to request", 90 "Local processor observed", 91 "Generic", 92 }; 93 94 static const char * const arm_bus_err_addr_space_strs[] = { 95 "External Memory Access", 96 "Internal Memory Access", 97 "Unknown", 98 "Device Memory Access", 99 }; 100 101 static void cper_print_arm_err_info(const char *pfx, u32 type, 102 u64 error_info) 103 { 104 u8 trans_type, op_type, level, participation_type, address_space; 105 u16 mem_attributes; 106 bool proc_context_corrupt, corrected, precise_pc, restartable_pc; 107 bool time_out, access_mode; 108 109 /* If the type is unknown, bail. */ 110 if (type > CPER_ARM_MAX_TYPE) 111 return; 112 113 /* 114 * Vendor type errors have error information values that are vendor 115 * specific. 116 */ 117 if (type == CPER_ARM_VENDOR_ERROR) 118 return; 119 120 if (error_info & CPER_ARM_ERR_VALID_TRANSACTION_TYPE) { 121 trans_type = ((error_info >> CPER_ARM_ERR_TRANSACTION_SHIFT) 122 & CPER_ARM_ERR_TRANSACTION_MASK); 123 if (trans_type < ARRAY_SIZE(arm_err_trans_type_strs)) { 124 printk("%stransaction type: %s\n", pfx, 125 arm_err_trans_type_strs[trans_type]); 126 } 127 } 128 129 if (error_info & CPER_ARM_ERR_VALID_OPERATION_TYPE) { 130 op_type = ((error_info >> CPER_ARM_ERR_OPERATION_SHIFT) 131 & CPER_ARM_ERR_OPERATION_MASK); 132 switch (type) { 133 case CPER_ARM_CACHE_ERROR: 134 if (op_type < ARRAY_SIZE(arm_cache_err_op_strs)) { 135 printk("%soperation type: %s\n", pfx, 136 arm_cache_err_op_strs[op_type]); 137 } 138 break; 139 case CPER_ARM_TLB_ERROR: 140 if (op_type < ARRAY_SIZE(arm_tlb_err_op_strs)) { 141 printk("%soperation type: %s\n", pfx, 142 arm_tlb_err_op_strs[op_type]); 143 } 144 break; 145 case CPER_ARM_BUS_ERROR: 146 if (op_type < ARRAY_SIZE(arm_bus_err_op_strs)) { 147 printk("%soperation type: %s\n", pfx, 148 arm_bus_err_op_strs[op_type]); 149 } 150 break; 151 } 152 } 153 154 if (error_info & CPER_ARM_ERR_VALID_LEVEL) { 155 level = ((error_info >> CPER_ARM_ERR_LEVEL_SHIFT) 156 & CPER_ARM_ERR_LEVEL_MASK); 157 switch (type) { 158 case CPER_ARM_CACHE_ERROR: 159 printk("%scache level: %d\n", pfx, level); 160 break; 161 case CPER_ARM_TLB_ERROR: 162 printk("%sTLB level: %d\n", pfx, level); 163 break; 164 case CPER_ARM_BUS_ERROR: 165 printk("%saffinity level at which the bus error occurred: %d\n", 166 pfx, level); 167 break; 168 } 169 } 170 171 if (error_info & CPER_ARM_ERR_VALID_PROC_CONTEXT_CORRUPT) { 172 proc_context_corrupt = ((error_info >> CPER_ARM_ERR_PC_CORRUPT_SHIFT) 173 & CPER_ARM_ERR_PC_CORRUPT_MASK); 174 if (proc_context_corrupt) 175 printk("%sprocessor context corrupted\n", pfx); 176 else 177 printk("%sprocessor context not corrupted\n", pfx); 178 } 179 180 if (error_info & CPER_ARM_ERR_VALID_CORRECTED) { 181 corrected = ((error_info >> CPER_ARM_ERR_CORRECTED_SHIFT) 182 & CPER_ARM_ERR_CORRECTED_MASK); 183 if (corrected) 184 printk("%sthe error has been corrected\n", pfx); 185 else 186 printk("%sthe error has not been corrected\n", pfx); 187 } 188 189 if (error_info & CPER_ARM_ERR_VALID_PRECISE_PC) { 190 precise_pc = ((error_info >> CPER_ARM_ERR_PRECISE_PC_SHIFT) 191 & CPER_ARM_ERR_PRECISE_PC_MASK); 192 if (precise_pc) 193 printk("%sPC is precise\n", pfx); 194 else 195 printk("%sPC is imprecise\n", pfx); 196 } 197 198 if (error_info & CPER_ARM_ERR_VALID_RESTARTABLE_PC) { 199 restartable_pc = ((error_info >> CPER_ARM_ERR_RESTARTABLE_PC_SHIFT) 200 & CPER_ARM_ERR_RESTARTABLE_PC_MASK); 201 if (restartable_pc) 202 printk("%sProgram execution can be restarted reliably at the PC associated with the error.\n", pfx); 203 } 204 205 /* The rest of the fields are specific to bus errors */ 206 if (type != CPER_ARM_BUS_ERROR) 207 return; 208 209 if (error_info & CPER_ARM_ERR_VALID_PARTICIPATION_TYPE) { 210 participation_type = ((error_info >> CPER_ARM_ERR_PARTICIPATION_TYPE_SHIFT) 211 & CPER_ARM_ERR_PARTICIPATION_TYPE_MASK); 212 if (participation_type < ARRAY_SIZE(arm_bus_err_part_type_strs)) { 213 printk("%sparticipation type: %s\n", pfx, 214 arm_bus_err_part_type_strs[participation_type]); 215 } 216 } 217 218 if (error_info & CPER_ARM_ERR_VALID_TIME_OUT) { 219 time_out = ((error_info >> CPER_ARM_ERR_TIME_OUT_SHIFT) 220 & CPER_ARM_ERR_TIME_OUT_MASK); 221 if (time_out) 222 printk("%srequest timed out\n", pfx); 223 } 224 225 if (error_info & CPER_ARM_ERR_VALID_ADDRESS_SPACE) { 226 address_space = ((error_info >> CPER_ARM_ERR_ADDRESS_SPACE_SHIFT) 227 & CPER_ARM_ERR_ADDRESS_SPACE_MASK); 228 if (address_space < ARRAY_SIZE(arm_bus_err_addr_space_strs)) { 229 printk("%saddress space: %s\n", pfx, 230 arm_bus_err_addr_space_strs[address_space]); 231 } 232 } 233 234 if (error_info & CPER_ARM_ERR_VALID_MEM_ATTRIBUTES) { 235 mem_attributes = ((error_info >> CPER_ARM_ERR_MEM_ATTRIBUTES_SHIFT) 236 & CPER_ARM_ERR_MEM_ATTRIBUTES_MASK); 237 printk("%smemory access attributes:0x%x\n", pfx, mem_attributes); 238 } 239 240 if (error_info & CPER_ARM_ERR_VALID_ACCESS_MODE) { 241 access_mode = ((error_info >> CPER_ARM_ERR_ACCESS_MODE_SHIFT) 242 & CPER_ARM_ERR_ACCESS_MODE_MASK); 243 if (access_mode) 244 printk("%saccess mode: normal\n", pfx); 245 else 246 printk("%saccess mode: secure\n", pfx); 247 } 248 } 249 250 void cper_print_proc_arm(const char *pfx, 251 const struct cper_sec_proc_arm *proc) 252 { 253 int i, len, max_ctx_type; 254 struct cper_arm_err_info *err_info; 255 struct cper_arm_ctx_info *ctx_info; 256 char newpfx[64], infopfx[64]; 257 258 printk("%sMIDR: 0x%016llx\n", pfx, proc->midr); 259 260 len = proc->section_length - (sizeof(*proc) + 261 proc->err_info_num * (sizeof(*err_info))); 262 if (len < 0) { 263 printk("%ssection length: %d\n", pfx, proc->section_length); 264 printk("%ssection length is too small\n", pfx); 265 printk("%sfirmware-generated error record is incorrect\n", pfx); 266 printk("%sERR_INFO_NUM is %d\n", pfx, proc->err_info_num); 267 return; 268 } 269 270 if (proc->validation_bits & CPER_ARM_VALID_MPIDR) 271 printk("%sMultiprocessor Affinity Register (MPIDR): 0x%016llx\n", 272 pfx, proc->mpidr); 273 274 if (proc->validation_bits & CPER_ARM_VALID_AFFINITY_LEVEL) 275 printk("%serror affinity level: %d\n", pfx, 276 proc->affinity_level); 277 278 if (proc->validation_bits & CPER_ARM_VALID_RUNNING_STATE) { 279 printk("%srunning state: 0x%x\n", pfx, proc->running_state); 280 printk("%sPower State Coordination Interface state: %d\n", 281 pfx, proc->psci_state); 282 } 283 284 snprintf(newpfx, sizeof(newpfx), "%s ", pfx); 285 286 err_info = (struct cper_arm_err_info *)(proc + 1); 287 for (i = 0; i < proc->err_info_num; i++) { 288 printk("%sError info structure %d:\n", pfx, i); 289 290 printk("%snum errors: %d\n", pfx, err_info->multiple_error + 1); 291 292 if (err_info->validation_bits & CPER_ARM_INFO_VALID_FLAGS) { 293 if (err_info->flags & CPER_ARM_INFO_FLAGS_FIRST) 294 printk("%sfirst error captured\n", newpfx); 295 if (err_info->flags & CPER_ARM_INFO_FLAGS_LAST) 296 printk("%slast error captured\n", newpfx); 297 if (err_info->flags & CPER_ARM_INFO_FLAGS_PROPAGATED) 298 printk("%spropagated error captured\n", 299 newpfx); 300 if (err_info->flags & CPER_ARM_INFO_FLAGS_OVERFLOW) 301 printk("%soverflow occurred, error info is incomplete\n", 302 newpfx); 303 } 304 305 printk("%serror_type: %d, %s\n", newpfx, err_info->type, 306 err_info->type < ARRAY_SIZE(cper_proc_error_type_strs) ? 307 cper_proc_error_type_strs[err_info->type] : "unknown"); 308 if (err_info->validation_bits & CPER_ARM_INFO_VALID_ERR_INFO) { 309 printk("%serror_info: 0x%016llx\n", newpfx, 310 err_info->error_info); 311 snprintf(infopfx, sizeof(infopfx), "%s ", newpfx); 312 cper_print_arm_err_info(infopfx, err_info->type, 313 err_info->error_info); 314 } 315 if (err_info->validation_bits & CPER_ARM_INFO_VALID_VIRT_ADDR) 316 printk("%svirtual fault address: 0x%016llx\n", 317 newpfx, err_info->virt_fault_addr); 318 if (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR) 319 printk("%sphysical fault address: 0x%016llx\n", 320 newpfx, err_info->physical_fault_addr); 321 err_info += 1; 322 } 323 324 ctx_info = (struct cper_arm_ctx_info *)err_info; 325 max_ctx_type = ARRAY_SIZE(arm_reg_ctx_strs) - 1; 326 for (i = 0; i < proc->context_info_num; i++) { 327 int size = sizeof(*ctx_info) + ctx_info->size; 328 329 printk("%sContext info structure %d:\n", pfx, i); 330 if (len < size) { 331 printk("%ssection length is too small\n", newpfx); 332 printk("%sfirmware-generated error record is incorrect\n", pfx); 333 return; 334 } 335 if (ctx_info->type > max_ctx_type) { 336 printk("%sInvalid context type: %d (max: %d)\n", 337 newpfx, ctx_info->type, max_ctx_type); 338 return; 339 } 340 printk("%sregister context type: %s\n", newpfx, 341 arm_reg_ctx_strs[ctx_info->type]); 342 print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4, 343 (ctx_info + 1), ctx_info->size, 0); 344 len -= size; 345 ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + size); 346 } 347 348 if (len > 0) { 349 printk("%sVendor specific error info has %u bytes:\n", pfx, 350 len); 351 print_hex_dump(newpfx, "", DUMP_PREFIX_OFFSET, 16, 4, ctx_info, 352 len, true); 353 } 354 } 355