From: Andi Kleen This patch adds machine check tainting. When a handled machine check occurs the oops gets a new 'M' flag. This is useful to ignore machines with hardware problems in oops reports. On i386 a thermal failure also sets this flag. Done for x86-64 and i386 so far. Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- 25-akpm/arch/i386/kernel/cpu/mcheck/k7.c | 1 + 25-akpm/arch/i386/kernel/cpu/mcheck/non-fatal.c | 1 + 25-akpm/arch/i386/kernel/cpu/mcheck/p4.c | 3 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/p5.c | 1 + 25-akpm/arch/i386/kernel/cpu/mcheck/p6.c | 1 + 25-akpm/arch/i386/kernel/cpu/mcheck/winchip.c | 1 + 25-akpm/arch/x86_64/kernel/mce.c | 2 ++ 25-akpm/include/linux/kernel.h | 1 + 25-akpm/kernel/panic.c | 3 ++- 9 files changed, 13 insertions(+), 1 deletion(-) diff -puN arch/i386/kernel/cpu/mcheck/k7.c~x86-64-i386-add-mce-tainting arch/i386/kernel/cpu/mcheck/k7.c --- 25/arch/i386/kernel/cpu/mcheck/k7.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/k7.c Tue Oct 5 16:10:07 2004 @@ -54,6 +54,7 @@ static asmlinkage void k7_machine_check( wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); /* Serialize */ wmb(); + tainted |= TAINT_MACHINE_CHECK; } } diff -puN arch/i386/kernel/cpu/mcheck/non-fatal.c~x86-64-i386-add-mce-tainting arch/i386/kernel/cpu/mcheck/non-fatal.c --- 25/arch/i386/kernel/cpu/mcheck/non-fatal.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/non-fatal.c Tue Oct 5 16:10:07 2004 @@ -48,6 +48,7 @@ static void mce_checkregs (void *info) /* Serialize */ wmb(); + tainted |= TAINT_MACHINE_CHECK; } } } diff -puN arch/i386/kernel/cpu/mcheck/p4.c~x86-64-i386-add-mce-tainting arch/i386/kernel/cpu/mcheck/p4.c --- 25/arch/i386/kernel/cpu/mcheck/p4.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/p4.c Tue Oct 5 16:10:07 2004 @@ -40,6 +40,7 @@ static void unexpected_thermal_interrupt { printk(KERN_ERR "CPU%d: Unexpected LVT TMR interrupt!\n", smp_processor_id()); + tainted |= TAINT_MACHINE_CHECK; } /* P4/Xeon Thermal transition interrupt handler */ @@ -60,6 +61,7 @@ static void intel_thermal_interrupt(stru printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu); printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n", cpu); + tainted |= TAINT_MACHINE_CHECK; } else { printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); } @@ -222,6 +224,7 @@ static asmlinkage void intel_machine_che wrmsr(msr, 0UL, 0UL); /* Serialize */ wmb(); + tainted |= TAINT_MACHINE_CHECK; } } mcgstl &= ~(1<<2); diff -puN arch/i386/kernel/cpu/mcheck/p5.c~x86-64-i386-add-mce-tainting arch/i386/kernel/cpu/mcheck/p5.c --- 25/arch/i386/kernel/cpu/mcheck/p5.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/p5.c Tue Oct 5 16:10:07 2004 @@ -25,6 +25,7 @@ static asmlinkage void pentium_machine_c printk(KERN_EMERG "CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype); if(lotype&(1<<5)) printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id()); + tainted |= TAINT_MACHINE_CHECK; } /* Set up machine check reporting for processors with Intel style MCE */ diff -puN arch/i386/kernel/cpu/mcheck/p6.c~x86-64-i386-add-mce-tainting arch/i386/kernel/cpu/mcheck/p6.c --- 25/arch/i386/kernel/cpu/mcheck/p6.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/p6.c Tue Oct 5 16:10:07 2004 @@ -72,6 +72,7 @@ static asmlinkage void intel_machine_che wrmsr (msr, 0UL, 0UL); /* Serialize */ wmb(); + tainted |= TAINT_MACHINE_CHECK; } } mcgstl &= ~(1<<2); diff -puN arch/i386/kernel/cpu/mcheck/winchip.c~x86-64-i386-add-mce-tainting arch/i386/kernel/cpu/mcheck/winchip.c --- 25/arch/i386/kernel/cpu/mcheck/winchip.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/i386/kernel/cpu/mcheck/winchip.c Tue Oct 5 16:10:07 2004 @@ -19,6 +19,7 @@ static asmlinkage void winchip_machine_check(struct pt_regs * regs, long error_code) { printk(KERN_EMERG "CPU0: Machine Check Exception.\n"); + tainted |= TAINT_MACHINE_CHECK; } /* Set up machine check reporting on the Winchip C6 series */ diff -puN arch/x86_64/kernel/mce.c~x86-64-i386-add-mce-tainting arch/x86_64/kernel/mce.c --- 25/arch/x86_64/kernel/mce.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/arch/x86_64/kernel/mce.c Tue Oct 5 16:10:07 2004 @@ -191,6 +191,8 @@ void do_machine_check(struct pt_regs * r panicm = m; panicm_found = 1; } + + tainted |= TAINT_MACHINE_CHECK; } /* Never do anything final in the polling timer */ diff -puN include/linux/kernel.h~x86-64-i386-add-mce-tainting include/linux/kernel.h --- 25/include/linux/kernel.h~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/include/linux/kernel.h Tue Oct 5 16:10:07 2004 @@ -146,6 +146,7 @@ extern enum system_states { SYSTEM_RESTART, } system_state; +#define TAINT_MACHINE_CHECK (1<<10) #define TAINT_PROPRIETARY_MODULE (1<<0) #define TAINT_FORCED_MODULE (1<<1) #define TAINT_UNSAFE_SMP (1<<2) diff -puN kernel/panic.c~x86-64-i386-add-mce-tainting kernel/panic.c --- 25/kernel/panic.c~x86-64-i386-add-mce-tainting Tue Oct 5 16:10:07 2004 +++ 25-akpm/kernel/panic.c Tue Oct 5 16:10:07 2004 @@ -125,7 +125,8 @@ const char *print_tainted(void) { static char buf[20]; if (tainted) { - snprintf(buf, sizeof(buf), "Tainted: %c%c%c", + snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c", + tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G', tainted & TAINT_FORCED_MODULE ? 'F' : ' ', tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); _