Loading drivers/acpi/apei/ghes.c +46 −33 Original line number Original line Diff line number Diff line Loading @@ -414,6 +414,51 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int #endif #endif } } /* * PCIe AER errors need to be sent to the AER driver for reporting and * recovery. The GHES severities map to the following AER severities and * require the following handling: * * GHES_SEV_CORRECTABLE -> AER_CORRECTABLE * These need to be reported by the AER driver but no recovery is * necessary. * GHES_SEV_RECOVERABLE -> AER_NONFATAL * GHES_SEV_RECOVERABLE && CPER_SEC_RESET -> AER_FATAL * These both need to be reported and recovered from by the AER driver. * GHES_SEV_PANIC does not make it to this handling since the kernel must * panic. */ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) { #ifdef CONFIG_ACPI_APEI_PCIEAER struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { unsigned int devfn; int aer_severity; devfn = PCI_DEVFN(pcie_err->device_id.device, pcie_err->device_id.function); aer_severity = cper_severity_to_aer(gdata->error_severity); /* * If firmware reset the component to contain * the error, we must reinitialize it before * use, so treat it as a fatal AER error. */ if (gdata->flags & CPER_SEC_RESET) aer_severity = AER_FATAL; aer_recover_queue(pcie_err->device_id.segment, pcie_err->device_id.bus, devfn, aer_severity, (struct aer_capability_regs *) pcie_err->aer_info); } #endif } static void ghes_do_proc(struct ghes *ghes, static void ghes_do_proc(struct ghes *ghes, const struct acpi_hest_generic_status *estatus) const struct acpi_hest_generic_status *estatus) { { Loading Loading @@ -441,38 +486,9 @@ static void ghes_do_proc(struct ghes *ghes, arch_apei_report_mem_error(sev, mem_err); arch_apei_report_mem_error(sev, mem_err); ghes_handle_memory_failure(gdata, sev); ghes_handle_memory_failure(gdata, sev); } } #ifdef CONFIG_ACPI_APEI_PCIEAER else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); ghes_handle_aer(gdata); if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE && pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { unsigned int devfn; int aer_severity; devfn = PCI_DEVFN(pcie_err->device_id.device, pcie_err->device_id.function); aer_severity = cper_severity_to_aer(gdata->error_severity); /* * If firmware reset the component to contain * the error, we must reinitialize it before * use, so treat it as a fatal AER error. */ if (gdata->flags & CPER_SEC_RESET) aer_severity = AER_FATAL; aer_recover_queue(pcie_err->device_id.segment, pcie_err->device_id.bus, devfn, aer_severity, (struct aer_capability_regs *) pcie_err->aer_info); } } } #endif else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); Loading Loading @@ -870,7 +886,6 @@ static void ghes_print_queued_estatus(void) struct ghes_estatus_node *estatus_node; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic *generic; struct acpi_hest_generic *generic; struct acpi_hest_generic_status *estatus; struct acpi_hest_generic_status *estatus; u32 len, node_len; llnode = llist_del_all(&ghes_estatus_llist); llnode = llist_del_all(&ghes_estatus_llist); /* /* Loading @@ -882,8 +897,6 @@ static void ghes_print_queued_estatus(void) estatus_node = llist_entry(llnode, struct ghes_estatus_node, estatus_node = llist_entry(llnode, struct ghes_estatus_node, llnode); llnode); estatus = GHES_ESTATUS_FROM_NODE(estatus_node); estatus = GHES_ESTATUS_FROM_NODE(estatus_node); len = cper_estatus_len(estatus); node_len = GHES_ESTATUS_NODE_LEN(len); generic = estatus_node->generic; generic = estatus_node->generic; ghes_print_estatus(NULL, generic, estatus); ghes_print_estatus(NULL, generic, estatus); llnode = llnode->next; llnode = llnode->next; Loading Loading
drivers/acpi/apei/ghes.c +46 −33 Original line number Original line Diff line number Diff line Loading @@ -414,6 +414,51 @@ static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int #endif #endif } } /* * PCIe AER errors need to be sent to the AER driver for reporting and * recovery. The GHES severities map to the following AER severities and * require the following handling: * * GHES_SEV_CORRECTABLE -> AER_CORRECTABLE * These need to be reported by the AER driver but no recovery is * necessary. * GHES_SEV_RECOVERABLE -> AER_NONFATAL * GHES_SEV_RECOVERABLE && CPER_SEC_RESET -> AER_FATAL * These both need to be reported and recovered from by the AER driver. * GHES_SEV_PANIC does not make it to this handling since the kernel must * panic. */ static void ghes_handle_aer(struct acpi_hest_generic_data *gdata) { #ifdef CONFIG_ACPI_APEI_PCIEAER struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); if (pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { unsigned int devfn; int aer_severity; devfn = PCI_DEVFN(pcie_err->device_id.device, pcie_err->device_id.function); aer_severity = cper_severity_to_aer(gdata->error_severity); /* * If firmware reset the component to contain * the error, we must reinitialize it before * use, so treat it as a fatal AER error. */ if (gdata->flags & CPER_SEC_RESET) aer_severity = AER_FATAL; aer_recover_queue(pcie_err->device_id.segment, pcie_err->device_id.bus, devfn, aer_severity, (struct aer_capability_regs *) pcie_err->aer_info); } #endif } static void ghes_do_proc(struct ghes *ghes, static void ghes_do_proc(struct ghes *ghes, const struct acpi_hest_generic_status *estatus) const struct acpi_hest_generic_status *estatus) { { Loading Loading @@ -441,38 +486,9 @@ static void ghes_do_proc(struct ghes *ghes, arch_apei_report_mem_error(sev, mem_err); arch_apei_report_mem_error(sev, mem_err); ghes_handle_memory_failure(gdata, sev); ghes_handle_memory_failure(gdata, sev); } } #ifdef CONFIG_ACPI_APEI_PCIEAER else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { struct cper_sec_pcie *pcie_err = acpi_hest_get_payload(gdata); ghes_handle_aer(gdata); if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE && pcie_err->validation_bits & CPER_PCIE_VALID_DEVICE_ID && pcie_err->validation_bits & CPER_PCIE_VALID_AER_INFO) { unsigned int devfn; int aer_severity; devfn = PCI_DEVFN(pcie_err->device_id.device, pcie_err->device_id.function); aer_severity = cper_severity_to_aer(gdata->error_severity); /* * If firmware reset the component to contain * the error, we must reinitialize it before * use, so treat it as a fatal AER error. */ if (gdata->flags & CPER_SEC_RESET) aer_severity = AER_FATAL; aer_recover_queue(pcie_err->device_id.segment, pcie_err->device_id.bus, devfn, aer_severity, (struct aer_capability_regs *) pcie_err->aer_info); } } } #endif else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); Loading Loading @@ -870,7 +886,6 @@ static void ghes_print_queued_estatus(void) struct ghes_estatus_node *estatus_node; struct ghes_estatus_node *estatus_node; struct acpi_hest_generic *generic; struct acpi_hest_generic *generic; struct acpi_hest_generic_status *estatus; struct acpi_hest_generic_status *estatus; u32 len, node_len; llnode = llist_del_all(&ghes_estatus_llist); llnode = llist_del_all(&ghes_estatus_llist); /* /* Loading @@ -882,8 +897,6 @@ static void ghes_print_queued_estatus(void) estatus_node = llist_entry(llnode, struct ghes_estatus_node, estatus_node = llist_entry(llnode, struct ghes_estatus_node, llnode); llnode); estatus = GHES_ESTATUS_FROM_NODE(estatus_node); estatus = GHES_ESTATUS_FROM_NODE(estatus_node); len = cper_estatus_len(estatus); node_len = GHES_ESTATUS_NODE_LEN(len); generic = estatus_node->generic; generic = estatus_node->generic; ghes_print_estatus(NULL, generic, estatus); ghes_print_estatus(NULL, generic, estatus); llnode = llnode->next; llnode = llnode->next; Loading