aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Nowicki <tomasz.nowicki@linaro.org>2014-07-22 05:20:11 -0400
committerTony Luck <tony.luck@intel.com>2014-07-22 18:05:06 -0400
commit9dae3d0d9e64c3cb8bb172f041d4e66d4b92088a (patch)
tree9fb86bab5f8f16f1812455b05efe61bb19311838
parent9a3c4145af32125c5ee39c0272662b47307a8323 (diff)
apei, mce: Factor out APEI architecture specific MCE calls.
This commit abstracts MCE calls and provides weak corresponding default implementation for those architectures which do not need arch specific actions. Each platform willing to do additional architectural actions should provides desired function definition. It allows us to avoid wrap code into #ifdef in generic code and prevent new platform from introducing dummy stub function too. Initially, there are two APEI arch-specific calls: - arch_apei_enable_cmcff() - arch_apei_report_mem_error() Both interact with MCE driver for X86 architecture. Signed-off-by: Tomasz Nowicki <tomasz.nowicki@linaro.org> Acked-by: Borislav Petkov <bp@suse.de> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/x86/kernel/acpi/Makefile1
-rw-r--r--arch/x86/kernel/acpi/apei.c56
-rw-r--r--drivers/acpi/apei/apei-base.c13
-rw-r--r--drivers/acpi/apei/ghes.c6
-rw-r--r--drivers/acpi/apei/hest.c29
-rw-r--r--include/acpi/apei.h3
6 files changed, 76 insertions, 32 deletions
diff --git a/arch/x86/kernel/acpi/Makefile b/arch/x86/kernel/acpi/Makefile
index 163b22581472..3242e591fa82 100644
--- a/arch/x86/kernel/acpi/Makefile
+++ b/arch/x86/kernel/acpi/Makefile
@@ -1,5 +1,6 @@
1obj-$(CONFIG_ACPI) += boot.o 1obj-$(CONFIG_ACPI) += boot.o
2obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o 2obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
3obj-$(CONFIG_ACPI_APEI) += apei.o
3 4
4ifneq ($(CONFIG_ACPI_PROCESSOR),) 5ifneq ($(CONFIG_ACPI_PROCESSOR),)
5obj-y += cstate.o 6obj-y += cstate.o
diff --git a/arch/x86/kernel/acpi/apei.c b/arch/x86/kernel/acpi/apei.c
new file mode 100644
index 000000000000..12b13de55255
--- /dev/null
+++ b/arch/x86/kernel/acpi/apei.c
@@ -0,0 +1,56 @@
1/*
2 * Arch-specific APEI-related functions.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#include <acpi/apei.h>
16
17#include <asm/mce.h>
18
19int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data)
20{
21#ifdef CONFIG_X86_MCE
22 int i;
23 struct acpi_hest_ia_corrected *cmc;
24 struct acpi_hest_ia_error_bank *mc_bank;
25
26 if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
27 return 0;
28
29 cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
30 if (!cmc->enabled)
31 return 0;
32
33 /*
34 * We expect HEST to provide a list of MC banks that report errors
35 * in firmware first mode. Otherwise, return non-zero value to
36 * indicate that we are done parsing HEST.
37 */
38 if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) ||
39 !cmc->num_hardware_banks)
40 return 1;
41
42 pr_info("HEST: Enabling Firmware First mode for corrected errors.\n");
43
44 mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1);
45 for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++)
46 mce_disable_bank(mc_bank->bank_number);
47#endif
48 return 1;
49}
50
51void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
52{
53#ifdef CONFIG_X86_MCE
54 apei_mce_report_mem_error(sev, mem_err);
55#endif
56}
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 8678dfe5366b..2cd7bdd6c8b3 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -745,6 +745,19 @@ struct dentry *apei_get_debugfs_dir(void)
745} 745}
746EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); 746EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);
747 747
748int __weak arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr,
749 void *data)
750{
751 return 1;
752}
753EXPORT_SYMBOL_GPL(arch_apei_enable_cmcff);
754
755void __weak arch_apei_report_mem_error(int sev,
756 struct cper_sec_mem_err *mem_err)
757{
758}
759EXPORT_SYMBOL_GPL(arch_apei_report_mem_error);
760
748int apei_osc_setup(void) 761int apei_osc_setup(void)
749{ 762{
750 static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c"; 763 static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index dab7cb7349df..352170a74a2e 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -49,7 +49,7 @@
49#include <linux/aer.h> 49#include <linux/aer.h>
50 50
51#include <acpi/ghes.h> 51#include <acpi/ghes.h>
52#include <asm/mce.h> 52#include <acpi/apei.h>
53#include <asm/tlbflush.h> 53#include <asm/tlbflush.h>
54#include <asm/nmi.h> 54#include <asm/nmi.h>
55 55
@@ -455,9 +455,7 @@ static void ghes_do_proc(struct ghes *ghes,
455 mem_err = (struct cper_sec_mem_err *)(gdata+1); 455 mem_err = (struct cper_sec_mem_err *)(gdata+1);
456 ghes_edac_report_mem_error(ghes, sev, mem_err); 456 ghes_edac_report_mem_error(ghes, sev, mem_err);
457 457
458#ifdef CONFIG_X86_MCE 458 arch_apei_report_mem_error(sev, mem_err);
459 apei_mce_report_mem_error(sev, mem_err);
460#endif
461 ghes_handle_memory_failure(gdata, sev); 459 ghes_handle_memory_failure(gdata, sev);
462 } 460 }
463#ifdef CONFIG_ACPI_APEI_PCIEAER 461#ifdef CONFIG_ACPI_APEI_PCIEAER
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index f5e37f32c71f..06e9b411a0a2 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -36,7 +36,6 @@
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <acpi/apei.h> 38#include <acpi/apei.h>
39#include <asm/mce.h>
40 39
41#include "apei-internal.h" 40#include "apei-internal.h"
42 41
@@ -128,33 +127,7 @@ EXPORT_SYMBOL_GPL(apei_hest_parse);
128 */ 127 */
129static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data) 128static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data)
130{ 129{
131#ifdef CONFIG_X86_MCE 130 return arch_apei_enable_cmcff(hest_hdr, data);
132 int i;
133 struct acpi_hest_ia_corrected *cmc;
134 struct acpi_hest_ia_error_bank *mc_bank;
135
136 if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
137 return 0;
138
139 cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
140 if (!cmc->enabled)
141 return 0;
142
143 /*
144 * We expect HEST to provide a list of MC banks that report errors
145 * in firmware first mode. Otherwise, return non-zero value to
146 * indicate that we are done parsing HEST.
147 */
148 if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) || !cmc->num_hardware_banks)
149 return 1;
150
151 pr_info(HEST_PFX "Enabling Firmware First mode for corrected errors.\n");
152
153 mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1);
154 for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++)
155 mce_disable_bank(mc_bank->bank_number);
156#endif
157 return 1;
158} 131}
159 132
160struct ghes_arr { 133struct ghes_arr {
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index 04f349d8da73..8a23c95109c6 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -42,5 +42,8 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
42 size_t buflen); 42 size_t buflen);
43int erst_clear(u64 record_id); 43int erst_clear(u64 record_id);
44 44
45int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
46void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
47
45#endif 48#endif
46#endif 49#endif