]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
apei, mce: Factor out APEI architecture specific MCE calls.
authorTomasz Nowicki <tomasz.nowicki@linaro.org>
Tue, 22 Jul 2014 09:20:11 +0000 (11:20 +0200)
committerTony Luck <tony.luck@intel.com>
Tue, 22 Jul 2014 22:05:06 +0000 (15:05 -0700)
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>
arch/x86/kernel/acpi/Makefile
arch/x86/kernel/acpi/apei.c [new file with mode: 0644]
drivers/acpi/apei/apei-base.c
drivers/acpi/apei/ghes.c
drivers/acpi/apei/hest.c
include/acpi/apei.h

index 163b225814728721ff0d424d8407493a6d92430d..3242e591fa8207ec6d1c0b3aef0a9fce91987d9d 100644 (file)
@@ -1,5 +1,6 @@
 obj-$(CONFIG_ACPI)             += boot.o
 obj-$(CONFIG_ACPI_SLEEP)       += sleep.o wakeup_$(BITS).o
+obj-$(CONFIG_ACPI_APEI)                += apei.o
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                          += cstate.o
diff --git a/arch/x86/kernel/acpi/apei.c b/arch/x86/kernel/acpi/apei.c
new file mode 100644 (file)
index 0000000..12b13de
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Arch-specific APEI-related functions.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <acpi/apei.h>
+
+#include <asm/mce.h>
+
+int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data)
+{
+#ifdef CONFIG_X86_MCE
+       int i;
+       struct acpi_hest_ia_corrected *cmc;
+       struct acpi_hest_ia_error_bank *mc_bank;
+
+       if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
+               return 0;
+
+       cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
+       if (!cmc->enabled)
+               return 0;
+
+       /*
+        * We expect HEST to provide a list of MC banks that report errors
+        * in firmware first mode. Otherwise, return non-zero value to
+        * indicate that we are done parsing HEST.
+        */
+       if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) ||
+           !cmc->num_hardware_banks)
+               return 1;
+
+       pr_info("HEST: Enabling Firmware First mode for corrected errors.\n");
+
+       mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1);
+       for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++)
+               mce_disable_bank(mc_bank->bank_number);
+#endif
+       return 1;
+}
+
+void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
+{
+#ifdef CONFIG_X86_MCE
+       apei_mce_report_mem_error(sev, mem_err);
+#endif
+}
index 8678dfe5366b9ac55c18b0d732eae431039ccdc5..2cd7bdd6c8b3cc3882f7ed2abc54b2d471716021 100644 (file)
@@ -745,6 +745,19 @@ struct dentry *apei_get_debugfs_dir(void)
 }
 EXPORT_SYMBOL_GPL(apei_get_debugfs_dir);
 
+int __weak arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr,
+                                 void *data)
+{
+       return 1;
+}
+EXPORT_SYMBOL_GPL(arch_apei_enable_cmcff);
+
+void __weak arch_apei_report_mem_error(int sev,
+                                      struct cper_sec_mem_err *mem_err)
+{
+}
+EXPORT_SYMBOL_GPL(arch_apei_report_mem_error);
+
 int apei_osc_setup(void)
 {
        static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
index dab7cb7349df7e62ee24f32493d8d5a8065ad3d9..352170a74a2ea8f4c37352978ed30d93fc8ca17d 100644 (file)
@@ -49,7 +49,7 @@
 #include <linux/aer.h>
 
 #include <acpi/ghes.h>
-#include <asm/mce.h>
+#include <acpi/apei.h>
 #include <asm/tlbflush.h>
 #include <asm/nmi.h>
 
@@ -455,9 +455,7 @@ static void ghes_do_proc(struct ghes *ghes,
                        mem_err = (struct cper_sec_mem_err *)(gdata+1);
                        ghes_edac_report_mem_error(ghes, sev, mem_err);
 
-#ifdef CONFIG_X86_MCE
-                       apei_mce_report_mem_error(sev, mem_err);
-#endif
+                       arch_apei_report_mem_error(sev, mem_err);
                        ghes_handle_memory_failure(gdata, sev);
                }
 #ifdef CONFIG_ACPI_APEI_PCIEAER
index f5e37f32c71ff09b3035d156f10ee7cd06dff88c..06e9b411a0a2c4b0956c3794d09c721a1b87c32d 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <acpi/apei.h>
-#include <asm/mce.h>
 
 #include "apei-internal.h"
 
@@ -128,33 +127,7 @@ EXPORT_SYMBOL_GPL(apei_hest_parse);
  */
 static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data)
 {
-#ifdef CONFIG_X86_MCE
-       int i;
-       struct acpi_hest_ia_corrected *cmc;
-       struct acpi_hest_ia_error_bank *mc_bank;
-
-       if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
-               return 0;
-
-       cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
-       if (!cmc->enabled)
-               return 0;
-
-       /*
-        * We expect HEST to provide a list of MC banks that report errors
-        * in firmware first mode. Otherwise, return non-zero value to
-        * indicate that we are done parsing HEST.
-        */
-       if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) || !cmc->num_hardware_banks)
-               return 1;
-
-       pr_info(HEST_PFX "Enabling Firmware First mode for corrected errors.\n");
-
-       mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1);
-       for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++)
-               mce_disable_bank(mc_bank->bank_number);
-#endif
-       return 1;
+       return arch_apei_enable_cmcff(hest_hdr, data);
 }
 
 struct ghes_arr {
index 04f349d8da7339427002e82b887f903f96e0157e..8a23c95109c6183ce78d844ecce3913871275491 100644 (file)
@@ -42,5 +42,8 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record,
                  size_t buflen);
 int erst_clear(u64 record_id);
 
+int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
+void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
+
 #endif
 #endif