From 57b47f9da9d62a94f76928872c9ac93721c006de Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 18 Oct 2004 18:14:38 -0700 Subject: [PATCH] [PATCH] x86-64/i386: add mce tainting 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: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mcheck/k7.c | 1 + arch/i386/kernel/cpu/mcheck/non-fatal.c | 1 + arch/i386/kernel/cpu/mcheck/p4.c | 3 +++ arch/i386/kernel/cpu/mcheck/p5.c | 1 + arch/i386/kernel/cpu/mcheck/p6.c | 1 + arch/i386/kernel/cpu/mcheck/winchip.c | 1 + arch/x86_64/kernel/mce.c | 2 ++ include/linux/kernel.h | 2 ++ kernel/panic.c | 12 ++++++++++-- 9 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/cpu/mcheck/k7.c b/arch/i386/kernel/cpu/mcheck/k7.c index 304bf420f0f1d..dcf9f068a5edc 100644 --- a/arch/i386/kernel/cpu/mcheck/k7.c +++ b/arch/i386/kernel/cpu/mcheck/k7.c @@ -54,6 +54,7 @@ static asmlinkage void k7_machine_check(struct pt_regs * regs, long error_code) wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); /* Serialize */ wmb(); + add_taint(TAINT_MACHINE_CHECK); } } diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c index a1664bb1577e6..7864ddfccf077 100644 --- a/arch/i386/kernel/cpu/mcheck/non-fatal.c +++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c @@ -48,6 +48,7 @@ static void mce_checkregs (void *info) /* Serialize */ wmb(); + add_taint(TAINT_MACHINE_CHECK); } } } diff --git a/arch/i386/kernel/cpu/mcheck/p4.c b/arch/i386/kernel/cpu/mcheck/p4.c index b31fc006f1bfe..51175846dd297 100644 --- a/arch/i386/kernel/cpu/mcheck/p4.c +++ b/arch/i386/kernel/cpu/mcheck/p4.c @@ -40,6 +40,7 @@ static void unexpected_thermal_interrupt(struct pt_regs *regs) { printk(KERN_ERR "CPU%d: Unexpected LVT TMR interrupt!\n", smp_processor_id()); + add_taint(TAINT_MACHINE_CHECK); } /* P4/Xeon Thermal transition interrupt handler */ @@ -60,6 +61,7 @@ static void intel_thermal_interrupt(struct pt_regs *regs) printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu); printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n", cpu); + add_taint(TAINT_MACHINE_CHECK); } else { printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); } @@ -222,6 +224,7 @@ static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_cod wrmsr(msr, 0UL, 0UL); /* Serialize */ wmb(); + add_taint(TAINT_MACHINE_CHECK); } } mcgstl &= ~(1<<2); diff --git a/arch/i386/kernel/cpu/mcheck/p5.c b/arch/i386/kernel/cpu/mcheck/p5.c index c92cd661c5ef7..e62b1f888a4e7 100644 --- a/arch/i386/kernel/cpu/mcheck/p5.c +++ b/arch/i386/kernel/cpu/mcheck/p5.c @@ -25,6 +25,7 @@ static asmlinkage void pentium_machine_check(struct pt_regs * regs, long error_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()); + add_taint(TAINT_MACHINE_CHECK); } /* Set up machine check reporting for processors with Intel style MCE */ diff --git a/arch/i386/kernel/cpu/mcheck/p6.c b/arch/i386/kernel/cpu/mcheck/p6.c index d63e9578c96c7..c8778643b666e 100644 --- a/arch/i386/kernel/cpu/mcheck/p6.c +++ b/arch/i386/kernel/cpu/mcheck/p6.c @@ -72,6 +72,7 @@ static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_cod wrmsr (msr, 0UL, 0UL); /* Serialize */ wmb(); + add_taint(TAINT_MACHINE_CHECK); } } mcgstl &= ~(1<<2); diff --git a/arch/i386/kernel/cpu/mcheck/winchip.c b/arch/i386/kernel/cpu/mcheck/winchip.c index ddb579da43ddd..64090175f4f5f 100644 --- a/arch/i386/kernel/cpu/mcheck/winchip.c +++ b/arch/i386/kernel/cpu/mcheck/winchip.c @@ -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"); + add_taint(TAINT_MACHINE_CHECK); } /* Set up machine check reporting on the Winchip C6 series */ diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index cf1fe8b7fa5bb..c771dc8e3f60a 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -191,6 +191,8 @@ void do_machine_check(struct pt_regs * regs, long error_code) panicm = m; panicm_found = 1; } + + tainted |= TAINT_MACHINE_CHECK; } /* Never do anything final in the polling timer */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 40307a28bb4b7..f60ba2c96469c 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -136,6 +136,7 @@ extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in extern int panic_on_oops; extern int tainted; extern const char *print_tainted(void); +extern void add_taint(unsigned); /* Values used for system_state */ extern enum system_states { @@ -150,6 +151,7 @@ extern enum system_states { #define TAINT_FORCED_MODULE (1<<1) #define TAINT_UNSAFE_SMP (1<<2) #define TAINT_FORCED_RMMOD (1<<3) +#define TAINT_MACHINE_CHECK (1<<4) extern void dump_stack(void); diff --git a/kernel/panic.c b/kernel/panic.c index fce7f4030d0a7..a98656f049b37 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -110,6 +110,7 @@ EXPORT_SYMBOL(panic); * 'P' - Proprietary module has been loaded. * 'F' - Module has been forcibly loaded. * 'S' - SMP with CPUs not designed for SMP. + * 'M' - Machine had a machine check experience. * * The string is overwritten by the next call to print_taint(). */ @@ -118,12 +119,19 @@ 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_PROPRIETARY_MODULE ? 'P' : 'G', tainted & TAINT_FORCED_MODULE ? 'F' : ' ', - tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); + tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', + tainted & TAINT_MACHINE_CHECK ? 'M' : ' '); } else snprintf(buf, sizeof(buf), "Not tainted"); return(buf); } + +void add_taint(unsigned flag) +{ + tainted |= flag; +} +EXPORT_SYMBOL(add_taint); -- 2.53.0