aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2011-07-13 01:14:28 -0400
committerLen Brown <len.brown@intel.com>2011-08-03 11:15:58 -0400
commitba61ca4aab47441f1c6cec28a9a6aa0489fd1df3 (patch)
tree04859a2c04f238b41e535c8e64977aefa99e28d2 /drivers/acpi
parentea8f5fb8a71fddaf5f3a17100d3247855701f732 (diff)
ACPI, APEI, GHES: Add hardware memory error recovery support
memory_failure_queue() is called when recoverable memory errors are notified by firmware to do the recovery work. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/apei/Kconfig7
-rw-r--r--drivers/acpi/apei/ghes.c24
2 files changed, 24 insertions, 7 deletions
diff --git a/drivers/acpi/apei/Kconfig b/drivers/acpi/apei/Kconfig
index 35596eaaca17..c34aa51af4ee 100644
--- a/drivers/acpi/apei/Kconfig
+++ b/drivers/acpi/apei/Kconfig
@@ -32,6 +32,13 @@ config ACPI_APEI_PCIEAER
32 PCIe AER errors may be reported via APEI firmware first mode. 32 PCIe AER errors may be reported via APEI firmware first mode.
33 Turn on this option to enable the corresponding support. 33 Turn on this option to enable the corresponding support.
34 34
35config ACPI_APEI_MEMORY_FAILURE
36 bool "APEI memory error recovering support"
37 depends on ACPI_APEI && MEMORY_FAILURE
38 help
39 Memory errors may be reported via APEI firmware first mode.
40 Turn on this option to enable the memory recovering support.
41
35config ACPI_APEI_EINJ 42config ACPI_APEI_EINJ
36 tristate "APEI Error INJection (EINJ)" 43 tristate "APEI Error INJection (EINJ)"
37 depends on ACPI_APEI && DEBUG_FS 44 depends on ACPI_APEI && DEBUG_FS
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 931410d31a96..e92c47c46f91 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -451,20 +451,30 @@ static void ghes_clear_estatus(struct ghes *ghes)
451 451
452static void ghes_do_proc(const struct acpi_hest_generic_status *estatus) 452static void ghes_do_proc(const struct acpi_hest_generic_status *estatus)
453{ 453{
454 int sev, processed = 0; 454 int sev, sec_sev;
455 struct acpi_hest_generic_data *gdata; 455 struct acpi_hest_generic_data *gdata;
456 456
457 sev = ghes_severity(estatus->error_severity); 457 sev = ghes_severity(estatus->error_severity);
458 apei_estatus_for_each_section(estatus, gdata) { 458 apei_estatus_for_each_section(estatus, gdata) {
459#ifdef CONFIG_X86_MCE 459 sec_sev = ghes_severity(gdata->error_severity);
460 if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, 460 if (!uuid_le_cmp(*(uuid_le *)gdata->section_type,
461 CPER_SEC_PLATFORM_MEM)) { 461 CPER_SEC_PLATFORM_MEM)) {
462 apei_mce_report_mem_error( 462 struct cper_sec_mem_err *mem_err;
463 sev == GHES_SEV_CORRECTED, 463 mem_err = (struct cper_sec_mem_err *)(gdata+1);
464 (struct cper_sec_mem_err *)(gdata+1)); 464#ifdef CONFIG_X86_MCE
465 processed = 1; 465 apei_mce_report_mem_error(sev == GHES_SEV_CORRECTED,
466 } 466 mem_err);
467#endif 467#endif
468#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
469 if (sev == GHES_SEV_RECOVERABLE &&
470 sec_sev == GHES_SEV_RECOVERABLE &&
471 mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) {
472 unsigned long pfn;
473 pfn = mem_err->physical_addr >> PAGE_SHIFT;
474 memory_failure_queue(pfn, 0, 0);
475 }
476#endif
477 }
468 } 478 }
469} 479}
470 480