Skip to content

Commit fd08619

Browse files
committed
Merge back APEI material for v4.16.
2 parents bb82e0b + 24bc8f0 commit fd08619

File tree

1 file changed

+46
-33
lines changed

1 file changed

+46
-33
lines changed

drivers/acpi/apei/ghes.c

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,51 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int
414414
#endif
415415
}
416416

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+
*/
431+
static 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+
417462
static void ghes_do_proc(struct ghes *ghes,
418463
const struct acpi_hest_generic_status *estatus)
419464
{
@@ -441,38 +486,9 @@ static void ghes_do_proc(struct ghes *ghes,
441486
arch_apei_report_mem_error(sev, mem_err);
442487
ghes_handle_memory_failure(gdata, sev);
443488
}
444-
#ifdef CONFIG_ACPI_APEI_PCIEAER
445489
else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
446-
struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(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-
490+
ghes_handle_aer(gdata);
474491
}
475-
#endif
476492
else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
477493
struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
478494

@@ -870,7 +886,6 @@ static void ghes_print_queued_estatus(void)
870886
struct ghes_estatus_node *estatus_node;
871887
struct acpi_hest_generic *generic;
872888
struct acpi_hest_generic_status *estatus;
873-
u32 len, node_len;
874889

875890
llnode = llist_del_all(&ghes_estatus_llist);
876891
/*
@@ -882,8 +897,6 @@ static void ghes_print_queued_estatus(void)
882897
estatus_node = llist_entry(llnode, struct ghes_estatus_node,
883898
llnode);
884899
estatus = GHES_ESTATUS_FROM_NODE(estatus_node);
885-
len = cper_estatus_len(estatus);
886-
node_len = GHES_ESTATUS_NODE_LEN(len);
887900
generic = estatus_node->generic;
888901
ghes_print_estatus(NULL, generic, estatus);
889902
llnode = llnode->next;

0 commit comments

Comments
 (0)