aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndi Kleen <andi@firstfloor.org>2009-05-27 15:56:56 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-06-03 17:40:38 -0400
commitd620c67fb92aa11736112f9a03e31d8e3079c57a (patch)
treead624a23926c1cadaa577b36f8eb57f4de055bc0 /arch
parentf6fb0ac0869500323c78fa21992fe1933af61e91 (diff)
x86, mce: support more than 256 CPUs in struct mce
The old struct mce had a limitation to 256 CPUs. But x86 Linux supports more than that now with x2apic. Add a new field extcpu to report the extended number. Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/mce.h4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-inject.c10
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c4
3 files changed, 9 insertions, 9 deletions
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index 0a61946d4396..b4a04b60b740 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -40,9 +40,9 @@ struct mce {
40 __u64 res2; /* dito. */ 40 __u64 res2; /* dito. */
41 __u8 cs; /* code segment */ 41 __u8 cs; /* code segment */
42 __u8 bank; /* machine check bank */ 42 __u8 bank; /* machine check bank */
43 __u8 cpu; /* cpu that raised the error */ 43 __u8 cpu; /* cpu number; obsolete; use extcpu now */
44 __u8 finished; /* entry is valid */ 44 __u8 finished; /* entry is valid */
45 __u32 pad; 45 __u32 extcpu; /* linux cpu number that detected the error */
46}; 46};
47 47
48/* 48/*
diff --git a/arch/x86/kernel/cpu/mcheck/mce-inject.c b/arch/x86/kernel/cpu/mcheck/mce-inject.c
index 7b3a5428396a..7d858fb4ce67 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-inject.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-inject.c
@@ -23,14 +23,14 @@
23/* Update fake mce registers on current CPU. */ 23/* Update fake mce registers on current CPU. */
24static void inject_mce(struct mce *m) 24static void inject_mce(struct mce *m)
25{ 25{
26 struct mce *i = &per_cpu(injectm, m->cpu); 26 struct mce *i = &per_cpu(injectm, m->extcpu);
27 27
28 /* Make sure noone reads partially written injectm */ 28 /* Make sure noone reads partially written injectm */
29 i->finished = 0; 29 i->finished = 0;
30 mb(); 30 mb();
31 m->finished = 0; 31 m->finished = 0;
32 /* First set the fields after finished */ 32 /* First set the fields after finished */
33 i->cpu = m->cpu; 33 i->extcpu = m->extcpu;
34 mb(); 34 mb();
35 /* Now write record in order, finished last (except above) */ 35 /* Now write record in order, finished last (except above) */
36 memcpy(i, m, sizeof(struct mce)); 36 memcpy(i, m, sizeof(struct mce));
@@ -49,7 +49,7 @@ static void raise_mce(unsigned long data)
49{ 49{
50 struct delayed_mce *dm = (struct delayed_mce *)data; 50 struct delayed_mce *dm = (struct delayed_mce *)data;
51 struct mce *m = &dm->m; 51 struct mce *m = &dm->m;
52 int cpu = m->cpu; 52 int cpu = m->extcpu;
53 53
54 inject_mce(m); 54 inject_mce(m);
55 if (m->status & MCI_STATUS_UC) { 55 if (m->status & MCI_STATUS_UC) {
@@ -93,7 +93,7 @@ static ssize_t mce_write(struct file *filp, const char __user *ubuf,
93 if (copy_from_user(&m, ubuf, usize)) 93 if (copy_from_user(&m, ubuf, usize))
94 return -EFAULT; 94 return -EFAULT;
95 95
96 if (m.cpu >= num_possible_cpus() || !cpu_online(m.cpu)) 96 if (m.extcpu >= num_possible_cpus() || !cpu_online(m.extcpu))
97 return -EINVAL; 97 return -EINVAL;
98 98
99 dm = kmalloc(sizeof(struct delayed_mce), GFP_KERNEL); 99 dm = kmalloc(sizeof(struct delayed_mce), GFP_KERNEL);
@@ -108,7 +108,7 @@ static ssize_t mce_write(struct file *filp, const char __user *ubuf,
108 memcpy(&dm->m, &m, sizeof(struct mce)); 108 memcpy(&dm->m, &m, sizeof(struct mce));
109 setup_timer(&dm->timer, raise_mce, (unsigned long)dm); 109 setup_timer(&dm->timer, raise_mce, (unsigned long)dm);
110 dm->timer.expires = jiffies + 2; 110 dm->timer.expires = jiffies + 2;
111 add_timer_on(&dm->timer, m.cpu); 111 add_timer_on(&dm->timer, m.extcpu);
112 return usize; 112 return usize;
113} 113}
114 114
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 3db047e7a0fb..2c4dd6c422c3 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -94,7 +94,7 @@ static inline int skip_bank_init(int i)
94void mce_setup(struct mce *m) 94void mce_setup(struct mce *m)
95{ 95{
96 memset(m, 0, sizeof(struct mce)); 96 memset(m, 0, sizeof(struct mce));
97 m->cpu = smp_processor_id(); 97 m->cpu = m->extcpu = smp_processor_id();
98 rdtscll(m->tsc); 98 rdtscll(m->tsc);
99} 99}
100 100
@@ -158,7 +158,7 @@ static void print_mce(struct mce *m)
158 KERN_EMERG "HARDWARE ERROR\n" 158 KERN_EMERG "HARDWARE ERROR\n"
159 KERN_EMERG 159 KERN_EMERG
160 "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", 160 "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
161 m->cpu, m->mcgstatus, m->bank, m->status); 161 m->extcpu, m->mcgstatus, m->bank, m->status);
162 if (m->ip) { 162 if (m->ip) {
163 printk(KERN_EMERG "RIP%s %02x:<%016Lx> ", 163 printk(KERN_EMERG "RIP%s %02x:<%016Lx> ",
164 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", 164 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",