27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/time.h>
50 static const char *cper_severity_strs[] = {
57 static const char *cper_severity_str(
unsigned int severity)
59 return severity <
ARRAY_SIZE(cper_severity_strs) ?
60 cper_severity_strs[severity] :
"unknown";
75 const char *strs[],
unsigned int strs_size)
81 for (i = 0; i < strs_size; i++) {
82 if (!(bits & (1
U << i)))
87 if (len && len +
strlen(str) + 2 > 80) {
92 len =
snprintf(buf,
sizeof(buf),
"%s%s", pfx, str);
94 len +=
snprintf(buf+len,
sizeof(buf)-len,
", %s", str);
100 static const char *cper_proc_type_strs[] = {
105 static const char *cper_proc_isa_strs[] = {
111 static const char *cper_proc_error_type_strs[] = {
115 "micro-architectural error",
118 static const char *cper_proc_op_strs[] = {
119 "unknown or generic",
122 "instruction execution",
125 static const char *cper_proc_flag_strs[] = {
132 static void cper_print_proc_generic(
const char *pfx,
138 cper_proc_type_strs[proc->
proc_type] :
"unknown");
142 cper_proc_isa_strs[proc->
proc_isa] :
"unknown");
146 cper_proc_error_type_strs,
152 cper_proc_op_strs[proc->
operation] :
"unknown");
165 printk(
"%s""target_address: 0x%016llx\n",
168 printk(
"%s""requestor_id: 0x%016llx\n",
171 printk(
"%s""responder_id: 0x%016llx\n",
174 printk(
"%s""IP: 0x%016llx\n", pfx, proc->
ip);
177 static const char *cper_mem_err_type_strs[] = {
182 "single-symbol chipkill ECC",
183 "multi-symbol chipkill ECC",
191 "scrub corrected error",
192 "scrub uncorrected error",
200 printk(
"%s""physical_address: 0x%016llx\n",
203 printk(
"%s""physical_address_mask: 0x%016llx\n",
229 printk(
"%s""error_type: %d, %s\n", pfx, etype,
231 cper_mem_err_type_strs[etype] :
"unknown");
235 static const char *cper_pcie_port_type_strs[] = {
237 "legacy PCI end point",
241 "upstream switch port",
242 "downstream switch port",
243 "PCIe to PCI/PCI-X bridge",
244 "PCI/PCI-X to PCIe bridge",
245 "root complex integrated endpoint device",
246 "root complex event collector",
249 static void cper_print_pcie(
const char *pfx,
const struct cper_sec_pcie *pcie,
255 cper_pcie_port_type_strs[pcie->
port_type] :
"unknown");
257 printk(
"%s""version: %d.%d\n", pfx,
260 printk(
"%s""command: 0x%04x, status: 0x%04x\n", pfx,
264 printk(
"%s""device_id: %04x:%02x:%02x.%x\n", pfx,
267 printk(
"%s""slot: %d\n", pfx,
269 printk(
"%s""secondary_bus: 0x%02x\n", pfx,
271 printk(
"%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
274 printk(
"%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]);
277 printk(
"%s""serial number: 0x%04x, 0x%04x\n", pfx,
281 "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
282 pfx, pcie->
bridge.secondary_status, pcie->
bridge.control);
283 #ifdef CONFIG_ACPI_APEI_PCIEAER
291 static const char *apei_estatus_section_flag_strs[] = {
293 "containment warning",
295 "threshold exceeded",
296 "resource not accessible",
300 static void apei_estatus_print_section(
307 printk(
"%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity,
308 cper_severity_str(severity));
319 printk(
"%s""section_type: general processor error\n", pfx);
321 cper_print_proc_generic(pfx, proc_err);
323 goto err_section_too_small;
326 printk(
"%s""section_type: memory error\n", pfx);
328 cper_print_mem(pfx, mem_err);
330 goto err_section_too_small;
333 printk(
"%s""section_type: PCIe error\n", pfx);
335 cper_print_pcie(pfx, pcie, gdata);
337 goto err_section_too_small;
339 printk(
"%s""section type: unknown, %pUl\n", pfx, sec_type);
343 err_section_too_small:
355 printk(
"%s""APEI generic hardware error status\n", pfx);
357 printk(
"%s""severity: %d, %s\n", pfx, severity,
358 cper_severity_str(severity));
361 while (data_len >
sizeof(*gdata)) {
363 apei_estatus_print_section(pfx, gdata, sec_no);
364 data_len -= gedata_len +
sizeof(*gdata);
365 gdata = (
void *)(gdata + 1) + gedata_len;
395 while (data_len >
sizeof(*gdata)) {
397 if (gedata_len > data_len -
sizeof(*gdata))
399 data_len -= gedata_len +
sizeof(*gdata);
400 gdata = (
void *)(gdata + 1) + gedata_len;