aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/apei/ghes.c79
1 files changed, 46 insertions, 33 deletions
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 6402f7fad3bb..16c4a10b7506 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -414,6 +414,51 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
414#endif 414#endif
415} 415}
416 416
417/*
418 * PCIe AER errors need to be sent to the AER driver for reporting and
419 * recovery. The GHES severities map to the following AER severities and
420 * require the following handling:
421 *
422 * GHES_SEV_CORRECTABLE -> AER_CORRECTABLE
423 * These need to be reported by the AER driver but no recovery is
424 * necessary.
425 * GHES_SEV_RECOVERABLE -> AER_NONFATAL
426 * GHES_SEV_RECOVERABLE && CPER_SEC_RESET -> AER_FATAL
427 * These both need to be reported and recovered from by the AER driver.
428 * GHES_SEV_PANIC does not make it to this handling since the kernel must
429 * panic.
430 */
431static void ghes_handle_aer(struct acpi_hest_generic_data *gdata)
432{
433#ifdef CONFIG_ACPI_APEI_PCIEAER
434 struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata);
435
436 if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
437 pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
438 unsigned int devfn;
439 int aer_severity;
440
441 devfn = PCI_DEVFN(pcie_err->device_id.device,
442 pcie_err->device_id.function);
443 aer_severity = cper_severity_to_aer(gdata->error_severity);
444
445 /*
446 * If firmware reset the component to contain
447 * the error, we must reinitialize it before
448 * use, so treat it as a fatal AER error.
449 */
450 if (gdata->flags & CPER_SEC_RESET)
451 aer_severity = AER_FATAL;
452
453 aer_recover_queue(pcie_err->device_id.segment,
454 pcie_err->device_id.bus,
455 devfn, aer_severity,
456 (struct aer_capability_regs *)
457 pcie_err->aer_info);
458 }
459#endif
460}
461
417static void ghes_do_proc(struct ghes *ghes, 462static void ghes_do_proc(struct ghes *ghes,
418 const struct acpi_hest_generic_status *estatus) 463 const struct acpi_hest_generic_status *estatus)
419{ 464{
@@ -441,38 +486,9 @@ static void ghes_do_proc(struct ghes *ghes,
441 arch_apei_report_mem_error(sev, mem_err); 486 arch_apei_report_mem_error(sev, mem_err);
442 ghes_handle_memory_failure(gdata, sev); 487 ghes_handle_memory_failure(gdata, sev);
443 } 488 }
444#ifdef CONFIG_ACPI_APEI_PCIEAER
445 else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { 489 else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
446 struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); 490 ghes_handle_aer(gdata);
447
448 if (sev == GHES_SEV_RECOVERABLE &&
449 sec_sev == GHES_SEV_RECOVERABLE &&
450 pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID &&
451 pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) {
452 unsigned int devfn;
453 int aer_severity;
454
455 devfn = PCI_DEVFN(pcie_err->device_id.device,
456 pcie_err->device_id.function);
457 aer_severity = cper_severity_to_aer(gdata->error_severity);
458
459 /*
460 * If firmware reset the component to contain
461 * the error, we must reinitialize it before
462 * use, so treat it as a fatal AER error.
463 */
464 if (gdata->flags & CPER_SEC_RESET)
465 aer_severity = AER_FATAL;
466
467 aer_recover_queue(pcie_err->device_id.segment,
468 pcie_err->device_id.bus,
469 devfn, aer_severity,
470 (struct aer_capability_regs *)
471 pcie_err->aer_info);
472 }
473
474 } 491 }
475#endif
476 else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { 492 else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
477 struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); 493 struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
478 494
@@ -870,7 +886,6 @@ static void ghes_print_queued_estatus(void)
870 struct ghes_estatus_node *estatus_node; 886 struct ghes_estatus_node *estatus_node;
871 struct acpi_hest_generic *generic; 887 struct acpi_hest_generic *generic;
872 struct acpi_hest_generic_status *estatus; 888 struct acpi_hest_generic_status *estatus;
873 u32 len, node_len;
874 889
875 llnode = llist_del_all(&ghes_estatus_llist); 890 llnode = llist_del_all(&ghes_estatus_llist);
876 /* 891 /*
@@ -882,8 +897,6 @@ static void ghes_print_queued_estatus(void)
882 estatus_node = llist_entry(llnode, struct ghes_estatus_node, 897 estatus_node = llist_entry(llnode, struct ghes_estatus_node,
883 llnode); 898 llnode);
884 estatus = GHES_ESTATUS_FROM_NODE(estatus_node); 899 estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
885 len = cper_estatus_len(estatus);
886 node_len = GHES_ESTATUS_NODE_LEN(len);
887 generic = estatus_node->generic; 900 generic = estatus_node->generic;
888 ghes_print_estatus(NULL, generic, estatus); 901 ghes_print_estatus(NULL, generic, estatus);
889 llnode = llnode->next; 902 llnode = llnode->next;