Commit 57b47f9d authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[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: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f5cda072
......@@ -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);
}
}
......
......@@ -48,6 +48,7 @@ static void mce_checkregs (void *info)
/* Serialize */
wmb();
add_taint(TAINT_MACHINE_CHECK);
}
}
}
......
......@@ -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);
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment