From: Andi Kleen <ak@muc.de>

Add a new "M" tainted bit in oopses for machine checks.

This shows in a oops when the machine had already a machine check.  That
information may be useful to see if the machine has hardware trouble and if
it's really worth to invest much time into a mysterious oops.

Support for i386 and x86-64 so far.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/i386/kernel/cpu/mcheck/k7.c      |    2 ++
 25-akpm/arch/i386/kernel/cpu/mcheck/p4.c      |    2 ++
 25-akpm/arch/i386/kernel/cpu/mcheck/p5.c      |    2 ++
 25-akpm/arch/i386/kernel/cpu/mcheck/p6.c      |    2 ++
 25-akpm/arch/i386/kernel/cpu/mcheck/winchip.c |    1 +
 25-akpm/arch/x86_64/kernel/mce.c              |    1 +
 25-akpm/include/linux/kernel.h                |    1 +
 25-akpm/kernel/panic.c                        |    4 +++-
 8 files changed, 14 insertions(+), 1 deletion(-)

diff -puN arch/i386/kernel/cpu/mcheck/k7.c~add-tainted-bit-for-machine-checks arch/i386/kernel/cpu/mcheck/k7.c
--- 25/arch/i386/kernel/cpu/mcheck/k7.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.400017152 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/k7.c	2004-09-30 22:37:11.414015024 -0700
@@ -64,6 +64,8 @@ static asmlinkage void k7_machine_check(
 	printk (KERN_EMERG "Attempting to continue.\n");
 	mcgstl &= ~(1<<2);
 	wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
+
+	tainted |= TAINT_MACHINE_CHECK;
 }
 
 
diff -puN arch/i386/kernel/cpu/mcheck/p4.c~add-tainted-bit-for-machine-checks arch/i386/kernel/cpu/mcheck/p4.c
--- 25/arch/i386/kernel/cpu/mcheck/p4.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.402016848 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/p4.c	2004-09-30 22:37:11.414015024 -0700
@@ -226,6 +226,8 @@ static asmlinkage void intel_machine_che
 	}
 	mcgstl &= ~(1<<2);
 	wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
+
+	tainted |= TAINT_MACHINE_CHECK;
 }
 
 
diff -puN arch/i386/kernel/cpu/mcheck/p5.c~add-tainted-bit-for-machine-checks arch/i386/kernel/cpu/mcheck/p5.c
--- 25/arch/i386/kernel/cpu/mcheck/p5.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.403016696 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/p5.c	2004-09-30 22:37:11.415014872 -0700
@@ -25,6 +25,8 @@ 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~add-tainted-bit-for-machine-checks arch/i386/kernel/cpu/mcheck/p6.c
--- 25/arch/i386/kernel/cpu/mcheck/p6.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.405016392 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/p6.c	2004-09-30 22:37:11.415014872 -0700
@@ -76,6 +76,8 @@ static asmlinkage void intel_machine_che
 	}
 	mcgstl &= ~(1<<2);
 	wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth);
+
+	tainted |= TAINT_MACHINE_CHECK;
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
diff -puN arch/i386/kernel/cpu/mcheck/winchip.c~add-tainted-bit-for-machine-checks arch/i386/kernel/cpu/mcheck/winchip.c
--- 25/arch/i386/kernel/cpu/mcheck/winchip.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.406016240 -0700
+++ 25-akpm/arch/i386/kernel/cpu/mcheck/winchip.c	2004-09-30 22:37:11.415014872 -0700
@@ -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~add-tainted-bit-for-machine-checks arch/x86_64/kernel/mce.c
--- 25/arch/x86_64/kernel/mce.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.407016088 -0700
+++ 25-akpm/arch/x86_64/kernel/mce.c	2004-09-30 22:37:11.416014720 -0700
@@ -227,6 +227,7 @@ void do_machine_check(struct pt_regs * r
 	}
 
  out:
+	tainted |= TAINT_MACHINE_CHECK;
 	/* Last thing done in the machine check exception to clear state. */
 	wrmsrl(MSR_IA32_MCG_STATUS, 0);
 }
diff -puN include/linux/kernel.h~add-tainted-bit-for-machine-checks include/linux/kernel.h
--- 25/include/linux/kernel.h~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.409015784 -0700
+++ 25-akpm/include/linux/kernel.h	2004-09-30 22:37:11.417014568 -0700
@@ -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~add-tainted-bit-for-machine-checks kernel/panic.c
--- 25/kernel/panic.c~add-tainted-bit-for-machine-checks	2004-09-30 22:37:11.410015632 -0700
+++ 25-akpm/kernel/panic.c	2004-09-30 22:37:11.417014568 -0700
@@ -117,6 +117,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().
  */
@@ -125,7 +126,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' : ' ');
_