ACPI, APEI, GHES: Cleanup ghes memory error handling

Cleanup the logic in ghes_handle_memory_failure(). While at it, add
proper PFN validity check for UC error and cleanup the code logic to
make it simpler and cleaner.

Signed-off-by: Chen, Gong <gong.chen@linux.intel.com>
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/1385363701-12387-2-git-send-email-gong.chen@linux.intel.com
[ Boris: massage commit message. ]
Signed-off-by: Borislav Petkov <bp@suse.de>
This commit is contained in:
Chen, Gong 2013-11-25 02:15:01 -05:00 committed by Borislav Petkov
parent d3ab3edc02
commit ca104edc17
1 changed files with 20 additions and 16 deletions

View File

@ -413,27 +413,31 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
{ {
#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
unsigned long pfn; unsigned long pfn;
int flags = -1;
int sec_sev = ghes_severity(gdata->error_severity); int sec_sev = ghes_severity(gdata->error_severity);
struct cper_sec_mem_err *mem_err; struct cper_sec_mem_err *mem_err;
mem_err = (struct cper_sec_mem_err *)(gdata + 1); mem_err = (struct cper_sec_mem_err *)(gdata + 1);
if (!(mem_err->validation_bits & CPER_MEM_VALID_PA))
return;
pfn = mem_err->physical_addr >> PAGE_SHIFT;
if (!pfn_valid(pfn)) {
pr_warn_ratelimited(FW_WARN GHES_PFX
"Invalid address in generic error data: %#llx\n",
mem_err->physical_addr);
return;
}
/* iff following two events can be handled properly by now */
if (sec_sev == GHES_SEV_CORRECTED && if (sec_sev == GHES_SEV_CORRECTED &&
(gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED) && (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED))
(mem_err->validation_bits & CPER_MEM_VALID_PA)) { flags = MF_SOFT_OFFLINE;
pfn = mem_err->physical_addr >> PAGE_SHIFT; if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE)
if (pfn_valid(pfn)) flags = 0;
memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE);
else if (printk_ratelimit()) if (flags != -1)
pr_warn(FW_WARN GHES_PFX memory_failure_queue(pfn, 0, flags);
"Invalid address in generic error data: %#llx\n",
mem_err->physical_addr);
}
if (sev == GHES_SEV_RECOVERABLE &&
sec_sev == GHES_SEV_RECOVERABLE &&
mem_err->validation_bits & CPER_MEM_VALID_PA) {
pfn = mem_err->physical_addr >> PAGE_SHIFT;
memory_failure_queue(pfn, 0, 0);
}
#endif #endif
} }