Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tomasz Nowicki and committed by
Tony Luck
9dae3d0d 9a3c4145

+76 -32
+1
arch/x86/kernel/acpi/Makefile
··· 1 1 obj-$(CONFIG_ACPI) += boot.o 2 2 obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o 3 + obj-$(CONFIG_ACPI_APEI) += apei.o 3 4 4 5 ifneq ($(CONFIG_ACPI_PROCESSOR),) 5 6 obj-y += cstate.o
+56
arch/x86/kernel/acpi/apei.c
··· 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 + 19 + int 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 + 51 + void 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 + }
+13
drivers/acpi/apei/apei-base.c
··· 745 745 } 746 746 EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); 747 747 748 + int __weak arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, 749 + void *data) 750 + { 751 + return 1; 752 + } 753 + EXPORT_SYMBOL_GPL(arch_apei_enable_cmcff); 754 + 755 + void __weak arch_apei_report_mem_error(int sev, 756 + struct cper_sec_mem_err *mem_err) 757 + { 758 + } 759 + EXPORT_SYMBOL_GPL(arch_apei_report_mem_error); 760 + 748 761 int apei_osc_setup(void) 749 762 { 750 763 static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
+2 -4
drivers/acpi/apei/ghes.c
··· 49 49 #include <linux/aer.h> 50 50 51 51 #include <acpi/ghes.h> 52 - #include <asm/mce.h> 52 + #include <acpi/apei.h> 53 53 #include <asm/tlbflush.h> 54 54 #include <asm/nmi.h> 55 55 ··· 455 455 mem_err = (struct cper_sec_mem_err *)(gdata+1); 456 456 ghes_edac_report_mem_error(ghes, sev, mem_err); 457 457 458 - #ifdef CONFIG_X86_MCE 459 - apei_mce_report_mem_error(sev, mem_err); 460 - #endif 458 + arch_apei_report_mem_error(sev, mem_err); 461 459 ghes_handle_memory_failure(gdata, sev); 462 460 } 463 461 #ifdef CONFIG_ACPI_APEI_PCIEAER
+1 -28
drivers/acpi/apei/hest.c
··· 36 36 #include <linux/io.h> 37 37 #include <linux/platform_device.h> 38 38 #include <acpi/apei.h> 39 - #include <asm/mce.h> 40 39 41 40 #include "apei-internal.h" 42 41 ··· 127 128 */ 128 129 static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data) 129 130 { 130 - #ifdef CONFIG_X86_MCE 131 - int i; 132 - struct acpi_hest_ia_corrected *cmc; 133 - struct acpi_hest_ia_error_bank *mc_bank; 134 - 135 - if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK) 136 - return 0; 137 - 138 - cmc = (struct acpi_hest_ia_corrected *)hest_hdr; 139 - if (!cmc->enabled) 140 - return 0; 141 - 142 - /* 143 - * We expect HEST to provide a list of MC banks that report errors 144 - * in firmware first mode. Otherwise, return non-zero value to 145 - * indicate that we are done parsing HEST. 146 - */ 147 - if (!(cmc->flags & ACPI_HEST_FIRMWARE_FIRST) || !cmc->num_hardware_banks) 148 - return 1; 149 - 150 - pr_info(HEST_PFX "Enabling Firmware First mode for corrected errors.\n"); 151 - 152 - mc_bank = (struct acpi_hest_ia_error_bank *)(cmc + 1); 153 - for (i = 0; i < cmc->num_hardware_banks; i++, mc_bank++) 154 - mce_disable_bank(mc_bank->bank_number); 155 - #endif 156 - return 1; 131 + return arch_apei_enable_cmcff(hest_hdr, data); 157 132 } 158 133 159 134 struct ghes_arr {
+3
include/acpi/apei.h
··· 42 42 size_t buflen); 43 43 int erst_clear(u64 record_id); 44 44 45 + int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data); 46 + void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err); 47 + 45 48 #endif 46 49 #endif