···3131 (e.g. BIOS or hardware monitoring applications), conflicting3232 with OS's error handling, and you cannot deactivate the agent,3333 then this option will be a help.3434+ mce=no_lmce3535+ Do not opt-in to Local MCE delivery. Use legacy method3636+ to broadcast MCEs.3437 mce=bootlog3538 Enable logging of machine checks left over from booting.3639 Disabled by default on AMD because some BIOS leave bogus ones.
···3434#ifdef CONFIG_X86_MCE_THRESHOLD3535 unsigned int irq_threshold_count;3636#endif3737+#ifdef CONFIG_X86_MCE_AMD3838+ unsigned int irq_deferred_error_count;3939+#endif3740#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)3841 unsigned int irq_hv_callback_count;3942#endif
···8383 */8484#define X86_PLATFORM_IPI_VECTOR 0xf785858686-/* Vector for KVM to deliver posted interrupt IPI */8787-#ifdef CONFIG_HAVE_KVM8888-#define POSTED_INTR_VECTOR 0xf28986#define POSTED_INTR_WAKEUP_VECTOR 0xf19090-#endif9191-9287/*9388 * IRQ work vector:9489 */9590#define IRQ_WORK_VECTOR 0xf696919792#define UV_BAU_MESSAGE 0xf59393+#define DEFERRED_ERROR_VECTOR 0xf498949995/* Vector on which hypervisor callbacks will be delivered */10096#define HYPERVISOR_CALLBACK_VECTOR 0xf39797+9898+/* Vector for KVM to deliver posted interrupt IPI */9999+#ifdef CONFIG_HAVE_KVM100100+#define POSTED_INTR_VECTOR 0xf2101101+#endif101102102103/*103104 * Local APIC timer IRQ vector is on a different priority level,
···101101DEFINE_IRQ_VECTOR_EVENT(threshold_apic);102102103103/*104104+ * deferred_error_apic - called when entering/exiting a deferred apic interrupt105105+ * vector handler106106+ */107107+DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);108108+109109+/*104110 * thermal_apic - called when entering/exiting a thermal apic interrupt105111 * vector handler106112 */
···10501050 char *msg = "Unknown";10511051 u64 recover_paddr = ~0ull;10521052 int flags = MF_ACTION_REQUIRED;10531053+ int lmce = 0;1053105410541055 prev_state = ist_enter(regs);10551056···10781077 kill_it = 1;1079107810801079 /*10811081- * Go through all the banks in exclusion of the other CPUs.10821082- * This way we don't report duplicated events on shared banks10831083- * because the first one to see it will clear it.10801080+ * Check if this MCE is signaled to only this logical processor10841081 */10851085- order = mce_start(&no_way_out);10821082+ if (m.mcgstatus & MCG_STATUS_LMCES)10831083+ lmce = 1;10841084+ else {10851085+ /*10861086+ * Go through all the banks in exclusion of the other CPUs.10871087+ * This way we don't report duplicated events on shared banks10881088+ * because the first one to see it will clear it.10891089+ * If this is a Local MCE, then no need to perform rendezvous.10901090+ */10911091+ order = mce_start(&no_way_out);10921092+ }10931093+10861094 for (i = 0; i < cfg->banks; i++) {10871095 __clear_bit(i, toclear);10881096 if (!test_bit(i, valid_banks))···11681158 * Do most of the synchronization with other CPUs.11691159 * When there's any problem use only local no_way_out state.11701160 */11711171- if (mce_end(order) < 0)11721172- no_way_out = worst >= MCE_PANIC_SEVERITY;11611161+ if (!lmce) {11621162+ if (mce_end(order) < 0)11631163+ no_way_out = worst >= MCE_PANIC_SEVERITY;11641164+ } else {11651165+ /*11661166+ * Local MCE skipped calling mce_reign()11671167+ * If we found a fatal error, we need to panic here.11681168+ */11691169+ if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)11701170+ mce_panic("Machine check from unknown source",11711171+ NULL, NULL);11721172+ }1173117311741174 /*11751175 * At insane "tolerant" levels we take no action. Otherwise···16601640 mce_intel_feature_init(c);16611641 mce_adjust_timer = cmci_intel_adjust_timer;16621642 break;16631663- case X86_VENDOR_AMD:16431643+16441644+ case X86_VENDOR_AMD: {16451645+ u32 ebx = cpuid_ebx(0x80000007);16461646+16641647 mce_amd_feature_init(c);16651665- mce_flags.overflow_recov = cpuid_ebx(0x80000007) & 0x1;16481648+ mce_flags.overflow_recov = !!(ebx & BIT(0));16491649+ mce_flags.succor = !!(ebx & BIT(1));16661650 break;16511651+ }16521652+16671653 default:16681654 break;16691655 }···20051979/*20061980 * mce=off Disables machine check20071981 * mce=no_cmci Disables CMCI19821982+ * mce=no_lmce Disables LMCE20081983 * mce=dont_log_ce Clears corrected events silently, no log created for CEs.20091984 * mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.20101985 * mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)···20292002 cfg->disabled = true;20302003 else if (!strcmp(str, "no_cmci"))20312004 cfg->cmci_disabled = true;20052005+ else if (!strcmp(str, "no_lmce"))20062006+ cfg->lmce_disabled = true;20322007 else if (!strcmp(str, "dont_log_ce"))20332008 cfg->dont_log_ce = true;20342009 else if (!strcmp(str, "ignore_ce"))···20402011 else if (!strcmp(str, "bios_cmci_threshold"))20412012 cfg->bios_cmci_threshold = true;20422013 else if (isdigit(str[0])) {20432043- get_option(&str, &(cfg->tolerant));20442044- if (*str == ',') {20452045- ++str;20142014+ if (get_option(&str, &cfg->tolerant) == 2)20462015 get_option(&str, &(cfg->monarch_timeout));20472047- }20482016 } else {20492017 pr_info("mce argument %s ignored. Please use /sys\n", str);20502018 return 0;
+121-20
arch/x86/kernel/cpu/mcheck/mce_amd.c
···11/*22- * (c) 2005-2012 Advanced Micro Devices, Inc.22+ * (c) 2005-2015 Advanced Micro Devices, Inc.33 * Your use of this code is subject to the terms and conditions of the44 * GNU general public license version 2. See "COPYING" or55 * http://www.gnu.org/licenses/gpl.html66 *77 * Written by Jacob Shin - AMD, Inc.88- *98 * Maintained by: Borislav Petkov <bp@alien8.de>109 *1111- * April 20061212- * - added support for AMD Family 0x10 processors1313- * May 20121414- * - major scrubbing1515- *1616- * All MC4_MISCi registers are shared between multi-cores1010+ * All MC4_MISCi registers are shared between cores on a node.1711 */1812#include <linux/interrupt.h>1913#include <linux/notifier.h>···2632#include <asm/idle.h>2733#include <asm/mce.h>2834#include <asm/msr.h>3535+#include <asm/trace/irq_vectors.h>29363037#define NR_BLOCKS 93138#define THRESHOLD_MAX 0xFFF···4247#define MASK_BLKPTR_LO 0xFF0000004348#define MCG_XBLK_ADDR 0xC000040044495050+/* Deferred error settings */5151+#define MSR_CU_DEF_ERR 0xC00004105252+#define MASK_DEF_LVTOFF 0x000000F05353+#define MASK_DEF_INT_TYPE 0x000000065454+#define DEF_LVT_OFF 0x25555+#define DEF_INT_TYPE_APIC 0x25656+4557static const char * const th_names[] = {4658 "load_store",4759 "insn_fetch",···6260static DEFINE_PER_CPU(unsigned char, bank_map); /* see which banks are on */63616462static void amd_threshold_interrupt(void);6363+static void amd_deferred_error_interrupt(void);6464+6565+static void default_deferred_error_interrupt(void)6666+{6767+ pr_err("Unexpected deferred interrupt at vector %x\n", DEFERRED_ERROR_VECTOR);6868+}6969+void (*deferred_error_int_vector)(void) = default_deferred_error_interrupt;65706671/*6772 * CPU Initialization···205196 threshold_restart_bank(&tr);206197};207198208208-static int setup_APIC_mce(int reserved, int new)199199+static int setup_APIC_mce_threshold(int reserved, int new)209200{210201 if (reserved < 0 && !setup_APIC_eilvt(new, THRESHOLD_APIC_VECTOR,211202 APIC_EILVT_MSG_FIX, 0))212203 return new;213204214205 return reserved;206206+}207207+208208+static int setup_APIC_deferred_error(int reserved, int new)209209+{210210+ if (reserved < 0 && !setup_APIC_eilvt(new, DEFERRED_ERROR_VECTOR,211211+ APIC_EILVT_MSG_FIX, 0))212212+ return new;213213+214214+ return reserved;215215+}216216+217217+static void deferred_error_interrupt_enable(struct cpuinfo_x86 *c)218218+{219219+ u32 low = 0, high = 0;220220+ int def_offset = -1, def_new;221221+222222+ if (rdmsr_safe(MSR_CU_DEF_ERR, &low, &high))223223+ return;224224+225225+ def_new = (low & MASK_DEF_LVTOFF) >> 4;226226+ if (!(low & MASK_DEF_LVTOFF)) {227227+ pr_err(FW_BUG "Your BIOS is not setting up LVT offset 0x2 for deferred error IRQs correctly.\n");228228+ def_new = DEF_LVT_OFF;229229+ low = (low & ~MASK_DEF_LVTOFF) | (DEF_LVT_OFF << 4);230230+ }231231+232232+ def_offset = setup_APIC_deferred_error(def_offset, def_new);233233+ if ((def_offset == def_new) &&234234+ (deferred_error_int_vector != amd_deferred_error_interrupt))235235+ deferred_error_int_vector = amd_deferred_error_interrupt;236236+237237+ low = (low & ~MASK_DEF_INT_TYPE) | DEF_INT_TYPE_APIC;238238+ wrmsr(MSR_CU_DEF_ERR, low, high);215239}216240217241/* cpu init entry point, called from mce.c with preempt off */···294252295253 b.interrupt_enable = 1;296254 new = (high & MASK_LVTOFF_HI) >> 20;297297- offset = setup_APIC_mce(offset, new);255255+ offset = setup_APIC_mce_threshold(offset, new);298256299257 if ((offset == new) &&300258 (mce_threshold_vector != amd_threshold_interrupt))···303261init:304262 mce_threshold_block_init(&b, offset);305263 }264264+ }265265+266266+ if (mce_flags.succor)267267+ deferred_error_interrupt_enable(c);268268+}269269+270270+static void __log_error(unsigned int bank, bool threshold_err, u64 misc)271271+{272272+ struct mce m;273273+ u64 status;274274+275275+ rdmsrl(MSR_IA32_MCx_STATUS(bank), status);276276+ if (!(status & MCI_STATUS_VAL))277277+ return;278278+279279+ mce_setup(&m);280280+281281+ m.status = status;282282+ m.bank = bank;283283+284284+ if (threshold_err)285285+ m.misc = misc;286286+287287+ if (m.status & MCI_STATUS_ADDRV)288288+ rdmsrl(MSR_IA32_MCx_ADDR(bank), m.addr);289289+290290+ mce_log(&m);291291+ wrmsrl(MSR_IA32_MCx_STATUS(bank), 0);292292+}293293+294294+static inline void __smp_deferred_error_interrupt(void)295295+{296296+ inc_irq_stat(irq_deferred_error_count);297297+ deferred_error_int_vector();298298+}299299+300300+asmlinkage __visible void smp_deferred_error_interrupt(void)301301+{302302+ entering_irq();303303+ __smp_deferred_error_interrupt();304304+ exiting_ack_irq();305305+}306306+307307+asmlinkage __visible void smp_trace_deferred_error_interrupt(void)308308+{309309+ entering_irq();310310+ trace_deferred_error_apic_entry(DEFERRED_ERROR_VECTOR);311311+ __smp_deferred_error_interrupt();312312+ trace_deferred_error_apic_exit(DEFERRED_ERROR_VECTOR);313313+ exiting_ack_irq();314314+}315315+316316+/* APIC interrupt handler for deferred errors */317317+static void amd_deferred_error_interrupt(void)318318+{319319+ u64 status;320320+ unsigned int bank;321321+322322+ for (bank = 0; bank < mca_cfg.banks; ++bank) {323323+ rdmsrl(MSR_IA32_MCx_STATUS(bank), status);324324+325325+ if (!(status & MCI_STATUS_VAL) ||326326+ !(status & MCI_STATUS_DEFERRED))327327+ continue;328328+329329+ __log_error(bank, false, 0);330330+ break;306331 }307332}308333···382273 * the interrupt goes off when error_count reaches threshold_limit.383274 * the handler will simply log mcelog w/ software defined bank number.384275 */276276+385277static void amd_threshold_interrupt(void)386278{387279 u32 low = 0, high = 0, address = 0;388280 int cpu = smp_processor_id();389281 unsigned int bank, block;390390- struct mce m;391282392283 /* assume first bank caused it */393284 for (bank = 0; bank < mca_cfg.banks; ++bank) {···430321 return;431322432323log:433433- mce_setup(&m);434434- rdmsrl(MSR_IA32_MCx_STATUS(bank), m.status);435435- if (!(m.status & MCI_STATUS_VAL))436436- return;437437- m.misc = ((u64)high << 32) | low;438438- m.bank = bank;439439- mce_log(&m);440440-441441- wrmsrl(MSR_IA32_MCx_STATUS(bank), 0);324324+ __log_error(bank, true, ((u64)high << 32) | low);442325}443326444327/*
+44
arch/x86/kernel/cpu/mcheck/mce_intel.c
···9191 return !!(cap & MCG_CMCI_P);9292}93939494+static bool lmce_supported(void)9595+{9696+ u64 tmp;9797+9898+ if (mca_cfg.lmce_disabled)9999+ return false;100100+101101+ rdmsrl(MSR_IA32_MCG_CAP, tmp);102102+103103+ /*104104+ * LMCE depends on recovery support in the processor. Hence both105105+ * MCG_SER_P and MCG_LMCE_P should be present in MCG_CAP.106106+ */107107+ if ((tmp & (MCG_SER_P | MCG_LMCE_P)) !=108108+ (MCG_SER_P | MCG_LMCE_P))109109+ return false;110110+111111+ /*112112+ * BIOS should indicate support for LMCE by setting bit 20 in113113+ * IA32_FEATURE_CONTROL without which touching MCG_EXT_CTL will114114+ * generate a #GP fault.115115+ */116116+ rdmsrl(MSR_IA32_FEATURE_CONTROL, tmp);117117+ if ((tmp & (FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_LMCE)) ==118118+ (FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_LMCE))119119+ return true;120120+121121+ return false;122122+}123123+94124bool mce_intel_cmci_poll(void)95125{96126 if (__this_cpu_read(cmci_storm_state) == CMCI_STORM_NONE)···435405 cmci_recheck();436406}437407408408+void intel_init_lmce(void)409409+{410410+ u64 val;411411+412412+ if (!lmce_supported())413413+ return;414414+415415+ rdmsrl(MSR_IA32_MCG_EXT_CTL, val);416416+417417+ if (!(val & MCG_EXT_CTL_LMCE_EN))418418+ wrmsrl(MSR_IA32_MCG_EXT_CTL, val | MCG_EXT_CTL_LMCE_EN);419419+}420420+438421void mce_intel_feature_init(struct cpuinfo_x86 *c)439422{440423 intel_init_thermal(c);441424 intel_init_cmci();425425+ intel_init_lmce();442426}
···135135 alloc_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt);136136#endif137137138138+#ifdef CONFIG_X86_MCE_AMD139139+ alloc_intr_gate(DEFERRED_ERROR_VECTOR, deferred_error_interrupt);140140+#endif141141+138142#ifdef CONFIG_X86_LOCAL_APIC139143 /* self generated IPI for local APIC timer */140144 alloc_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
-12
arch/x86/kernel/traps.c
···813813do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)814814{815815 conditional_sti(regs);816816-#if 0817817- /* No need to warn about this any longer. */818818- pr_info("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");819819-#endif820820-}821821-822822-asmlinkage __visible void __attribute__((weak)) smp_thermal_interrupt(void)823823-{824824-}825825-826826-asmlinkage __visible void __attribute__((weak)) smp_threshold_interrupt(void)827827-{828816}829817830818/*