diff options
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/mce.h | 10 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 12 |
2 files changed, 20 insertions, 2 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index b4a04b60b740..ba1f8890cf51 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -36,13 +36,19 @@ struct mce { | |||
36 | __u64 mcgstatus; | 36 | __u64 mcgstatus; |
37 | __u64 ip; | 37 | __u64 ip; |
38 | __u64 tsc; /* cpu time stamp counter */ | 38 | __u64 tsc; /* cpu time stamp counter */ |
39 | __u64 res1; /* for future extension */ | 39 | __u64 time; /* wall time_t when error was detected */ |
40 | __u64 res2; /* dito. */ | 40 | __u8 cpuvendor; /* cpu vendor as encoded in system.h */ |
41 | __u8 pad1; | ||
42 | __u16 pad2; | ||
43 | __u32 cpuid; /* CPUID 1 EAX */ | ||
41 | __u8 cs; /* code segment */ | 44 | __u8 cs; /* code segment */ |
42 | __u8 bank; /* machine check bank */ | 45 | __u8 bank; /* machine check bank */ |
43 | __u8 cpu; /* cpu number; obsolete; use extcpu now */ | 46 | __u8 cpu; /* cpu number; obsolete; use extcpu now */ |
44 | __u8 finished; /* entry is valid */ | 47 | __u8 finished; /* entry is valid */ |
45 | __u32 extcpu; /* linux cpu number that detected the error */ | 48 | __u32 extcpu; /* linux cpu number that detected the error */ |
49 | __u32 socketid; /* CPU socket ID */ | ||
50 | __u32 apicid; /* CPU initial apic ID */ | ||
51 | __u64 mcgcap; /* MCGCAP MSR: machine check capabilities of CPU */ | ||
46 | }; | 52 | }; |
47 | 53 | ||
48 | /* | 54 | /* |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 2c4dd6c422c3..ba68449c22a1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -96,6 +96,15 @@ void mce_setup(struct mce *m) | |||
96 | memset(m, 0, sizeof(struct mce)); | 96 | memset(m, 0, sizeof(struct mce)); |
97 | m->cpu = m->extcpu = smp_processor_id(); | 97 | m->cpu = m->extcpu = smp_processor_id(); |
98 | rdtscll(m->tsc); | 98 | rdtscll(m->tsc); |
99 | /* We hope get_seconds stays lockless */ | ||
100 | m->time = get_seconds(); | ||
101 | m->cpuvendor = boot_cpu_data.x86_vendor; | ||
102 | m->cpuid = cpuid_eax(1); | ||
103 | #ifdef CONFIG_SMP | ||
104 | m->socketid = cpu_data(m->extcpu).phys_proc_id; | ||
105 | #endif | ||
106 | m->apicid = cpu_data(m->extcpu).initial_apicid; | ||
107 | rdmsrl(MSR_IA32_MCG_CAP, m->mcgcap); | ||
99 | } | 108 | } |
100 | 109 | ||
101 | DEFINE_PER_CPU(struct mce, injectm); | 110 | DEFINE_PER_CPU(struct mce, injectm); |
@@ -173,6 +182,9 @@ static void print_mce(struct mce *m) | |||
173 | if (m->misc) | 182 | if (m->misc) |
174 | printk("MISC %llx ", m->misc); | 183 | printk("MISC %llx ", m->misc); |
175 | printk("\n"); | 184 | printk("\n"); |
185 | printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", | ||
186 | m->cpuvendor, m->cpuid, m->time, m->socketid, | ||
187 | m->apicid); | ||
176 | printk(KERN_EMERG "This is not a software problem!\n"); | 188 | printk(KERN_EMERG "This is not a software problem!\n"); |
177 | printk(KERN_EMERG "Run through mcelog --ascii to decode " | 189 | printk(KERN_EMERG "Run through mcelog --ascii to decode " |
178 | "and contact your hardware vendor\n"); | 190 | "and contact your hardware vendor\n"); |