aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mcheck/p6.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck/p6.c')
-rw-r--r--arch/x86/kernel/cpu/mcheck/p6.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/p6.c b/arch/x86/kernel/cpu/mcheck/p6.c
index 2ac52d7b434b..01e4f8178183 100644
--- a/arch/x86/kernel/cpu/mcheck/p6.c
+++ b/arch/x86/kernel/cpu/mcheck/p6.c
@@ -2,25 +2,23 @@
2 * P6 specific Machine Check Exception Reporting 2 * P6 specific Machine Check Exception Reporting
3 * (C) Copyright 2002 Alan Cox <alan@lxorguk.ukuu.org.uk> 3 * (C) Copyright 2002 Alan Cox <alan@lxorguk.ukuu.org.uk>
4 */ 4 */
5
6#include <linux/init.h>
7#include <linux/types.h>
8#include <linux/kernel.h>
9#include <linux/interrupt.h> 5#include <linux/interrupt.h>
6#include <linux/kernel.h>
7#include <linux/types.h>
8#include <linux/init.h>
10#include <linux/smp.h> 9#include <linux/smp.h>
11 10
12#include <asm/processor.h> 11#include <asm/processor.h>
13#include <asm/system.h> 12#include <asm/system.h>
13#include <asm/mce.h>
14#include <asm/msr.h> 14#include <asm/msr.h>
15 15
16#include "mce.h"
17
18/* Machine Check Handler For PII/PIII */ 16/* Machine Check Handler For PII/PIII */
19static void intel_machine_check(struct pt_regs *regs, long error_code) 17static void intel_machine_check(struct pt_regs *regs, long error_code)
20{ 18{
21 int recover = 1;
22 u32 alow, ahigh, high, low; 19 u32 alow, ahigh, high, low;
23 u32 mcgstl, mcgsth; 20 u32 mcgstl, mcgsth;
21 int recover = 1;
24 int i; 22 int i;
25 23
26 rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); 24 rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
@@ -35,12 +33,16 @@ static void intel_machine_check(struct pt_regs *regs, long error_code)
35 if (high & (1<<31)) { 33 if (high & (1<<31)) {
36 char misc[20]; 34 char misc[20];
37 char addr[24]; 35 char addr[24];
38 misc[0] = addr[0] = '\0'; 36
37 misc[0] = '\0';
38 addr[0] = '\0';
39
39 if (high & (1<<29)) 40 if (high & (1<<29))
40 recover |= 1; 41 recover |= 1;
41 if (high & (1<<25)) 42 if (high & (1<<25))
42 recover |= 2; 43 recover |= 2;
43 high &= ~(1<<31); 44 high &= ~(1<<31);
45
44 if (high & (1<<27)) { 46 if (high & (1<<27)) {
45 rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); 47 rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
46 snprintf(misc, 20, "[%08x%08x]", ahigh, alow); 48 snprintf(misc, 20, "[%08x%08x]", ahigh, alow);
@@ -49,6 +51,7 @@ static void intel_machine_check(struct pt_regs *regs, long error_code)
49 rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); 51 rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
50 snprintf(addr, 24, " at %08x%08x", ahigh, alow); 52 snprintf(addr, 24, " at %08x%08x", ahigh, alow);
51 } 53 }
54
52 printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", 55 printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n",
53 smp_processor_id(), i, high, low, misc, addr); 56 smp_processor_id(), i, high, low, misc, addr);
54 } 57 }
@@ -63,16 +66,17 @@ static void intel_machine_check(struct pt_regs *regs, long error_code)
63 /* 66 /*
64 * Do not clear the MSR_IA32_MCi_STATUS if the error is not 67 * Do not clear the MSR_IA32_MCi_STATUS if the error is not
65 * recoverable/continuable.This will allow BIOS to look at the MSRs 68 * recoverable/continuable.This will allow BIOS to look at the MSRs
66 * for errors if the OS could not log the error. 69 * for errors if the OS could not log the error:
67 */ 70 */
68 for (i = 0; i < nr_mce_banks; i++) { 71 for (i = 0; i < nr_mce_banks; i++) {
69 unsigned int msr; 72 unsigned int msr;
73
70 msr = MSR_IA32_MC0_STATUS+i*4; 74 msr = MSR_IA32_MC0_STATUS+i*4;
71 rdmsr(msr, low, high); 75 rdmsr(msr, low, high);
72 if (high & (1<<31)) { 76 if (high & (1<<31)) {
73 /* Clear it */ 77 /* Clear it: */
74 wrmsr(msr, 0UL, 0UL); 78 wrmsr(msr, 0UL, 0UL);
75 /* Serialize */ 79 /* Serialize: */
76 wmb(); 80 wmb();
77 add_taint(TAINT_MACHINE_CHECK); 81 add_taint(TAINT_MACHINE_CHECK);
78 } 82 }
@@ -81,7 +85,7 @@ static void intel_machine_check(struct pt_regs *regs, long error_code)
81 wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth); 85 wrmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);
82} 86}
83 87
84/* Set up machine check reporting for processors with Intel style MCE */ 88/* Set up machine check reporting for processors with Intel style MCE: */
85void intel_p6_mcheck_init(struct cpuinfo_x86 *c) 89void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
86{ 90{
87 u32 l, h; 91 u32 l, h;
@@ -97,6 +101,7 @@ void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
97 101
98 /* Ok machine check is available */ 102 /* Ok machine check is available */
99 machine_check_vector = intel_machine_check; 103 machine_check_vector = intel_machine_check;
104 /* Make sure the vector pointer is visible before we enable MCEs: */
100 wmb(); 105 wmb();
101 106
102 printk(KERN_INFO "Intel machine check architecture supported.\n"); 107 printk(KERN_INFO "Intel machine check architecture supported.\n");