121afaf18SBorislav Petkov // SPDX-License-Identifier: GPL-2.0 221afaf18SBorislav Petkov /* 321afaf18SBorislav Petkov * P5 specific Machine Check Exception Reporting 421afaf18SBorislav Petkov * (C) Copyright 2002 Alan Cox <alan@lxorguk.ukuu.org.uk> 521afaf18SBorislav Petkov */ 621afaf18SBorislav Petkov #include <linux/interrupt.h> 721afaf18SBorislav Petkov #include <linux/kernel.h> 821afaf18SBorislav Petkov #include <linux/types.h> 921afaf18SBorislav Petkov #include <linux/smp.h> 100d00449cSPeter Zijlstra #include <linux/hardirq.h> 1121afaf18SBorislav Petkov 1221afaf18SBorislav Petkov #include <asm/processor.h> 1321afaf18SBorislav Petkov #include <asm/traps.h> 1421afaf18SBorislav Petkov #include <asm/tlbflush.h> 1521afaf18SBorislav Petkov #include <asm/mce.h> 1621afaf18SBorislav Petkov #include <asm/msr.h> 1721afaf18SBorislav Petkov 183bfaf95cSBorislav Petkov #include "internal.h" 193bfaf95cSBorislav Petkov 2021afaf18SBorislav Petkov /* By default disabled */ 2121afaf18SBorislav Petkov int mce_p5_enabled __read_mostly; 2221afaf18SBorislav Petkov 2321afaf18SBorislav Petkov /* Machine check handler for Pentium class Intel CPUs: */ 2421afaf18SBorislav Petkov static void pentium_machine_check(struct pt_regs *regs, long error_code) 2521afaf18SBorislav Petkov { 2621afaf18SBorislav Petkov u32 loaddr, hi, lotype; 2721afaf18SBorislav Petkov 280d00449cSPeter Zijlstra nmi_enter(); 2921afaf18SBorislav Petkov 3021afaf18SBorislav Petkov rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi); 3121afaf18SBorislav Petkov rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi); 3221afaf18SBorislav Petkov 3321afaf18SBorislav Petkov pr_emerg("CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", 3421afaf18SBorislav Petkov smp_processor_id(), loaddr, lotype); 3521afaf18SBorislav Petkov 3621afaf18SBorislav Petkov if (lotype & (1<<5)) { 3721afaf18SBorislav Petkov pr_emerg("CPU#%d: Possible thermal failure (CPU on fire ?).\n", 3821afaf18SBorislav Petkov smp_processor_id()); 3921afaf18SBorislav Petkov } 4021afaf18SBorislav Petkov 4121afaf18SBorislav Petkov add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); 4221afaf18SBorislav Petkov 430d00449cSPeter Zijlstra nmi_exit(); 4421afaf18SBorislav Petkov } 4521afaf18SBorislav Petkov 4621afaf18SBorislav Petkov /* Set up machine check reporting for processors with Intel style MCE: */ 4721afaf18SBorislav Petkov void intel_p5_mcheck_init(struct cpuinfo_x86 *c) 4821afaf18SBorislav Petkov { 4921afaf18SBorislav Petkov u32 l, h; 5021afaf18SBorislav Petkov 5121afaf18SBorislav Petkov /* Default P5 to off as its often misconnected: */ 5221afaf18SBorislav Petkov if (!mce_p5_enabled) 5321afaf18SBorislav Petkov return; 5421afaf18SBorislav Petkov 5521afaf18SBorislav Petkov /* Check for MCE support: */ 5621afaf18SBorislav Petkov if (!cpu_has(c, X86_FEATURE_MCE)) 5721afaf18SBorislav Petkov return; 5821afaf18SBorislav Petkov 5921afaf18SBorislav Petkov machine_check_vector = pentium_machine_check; 6021afaf18SBorislav Petkov /* Make sure the vector pointer is visible before we enable MCEs: */ 6121afaf18SBorislav Petkov wmb(); 6221afaf18SBorislav Petkov 6321afaf18SBorislav Petkov /* Read registers before enabling: */ 6421afaf18SBorislav Petkov rdmsr(MSR_IA32_P5_MC_ADDR, l, h); 6521afaf18SBorislav Petkov rdmsr(MSR_IA32_P5_MC_TYPE, l, h); 6621afaf18SBorislav Petkov pr_info("Intel old style machine check architecture supported.\n"); 6721afaf18SBorislav Petkov 6821afaf18SBorislav Petkov /* Enable MCE: */ 6921afaf18SBorislav Petkov cr4_set_bits(X86_CR4_MCE); 7021afaf18SBorislav Petkov pr_info("Intel old style machine check reporting enabled on CPU#%d.\n", 7121afaf18SBorislav Petkov smp_processor_id()); 7221afaf18SBorislav Petkov } 73