diff options
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck')
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/k7.c | 25 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_32.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_64.c | 45 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce_amd_64.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/p4.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/p5.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/p6.c | 23 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/winchip.c | 2 |
9 files changed, 84 insertions, 75 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/k7.c b/arch/x86/kernel/cpu/mcheck/k7.c index eef63e3630c2..e633c9c2b764 100644 --- a/arch/x86/kernel/cpu/mcheck/k7.c +++ b/arch/x86/kernel/cpu/mcheck/k7.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include "mce.h" | 16 | #include "mce.h" |
17 | 17 | ||
18 | /* Machine Check Handler For AMD Athlon/Duron */ | 18 | /* Machine Check Handler For AMD Athlon/Duron */ |
19 | static fastcall void k7_machine_check(struct pt_regs * regs, long error_code) | 19 | static void k7_machine_check(struct pt_regs * regs, long error_code) |
20 | { | 20 | { |
21 | int recover=1; | 21 | int recover=1; |
22 | u32 alow, ahigh, high, low; | 22 | u32 alow, ahigh, high, low; |
@@ -27,29 +27,32 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code) | |||
27 | if (mcgstl & (1<<0)) /* Recoverable ? */ | 27 | if (mcgstl & (1<<0)) /* Recoverable ? */ |
28 | recover=0; | 28 | recover=0; |
29 | 29 | ||
30 | printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", | 30 | printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", |
31 | smp_processor_id(), mcgsth, mcgstl); | 31 | smp_processor_id(), mcgsth, mcgstl); |
32 | 32 | ||
33 | for (i=1; i<nr_mce_banks; i++) { | 33 | for (i = 1; i < nr_mce_banks; i++) { |
34 | rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high); | 34 | rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); |
35 | if (high&(1<<31)) { | 35 | if (high&(1<<31)) { |
36 | char misc[20]; | ||
37 | char addr[24]; | ||
38 | misc[0] = addr[0] = '\0'; | ||
36 | if (high & (1<<29)) | 39 | if (high & (1<<29)) |
37 | recover |= 1; | 40 | recover |= 1; |
38 | if (high & (1<<25)) | 41 | if (high & (1<<25)) |
39 | recover |= 2; | 42 | recover |= 2; |
40 | printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low); | ||
41 | high &= ~(1<<31); | 43 | high &= ~(1<<31); |
42 | if (high & (1<<27)) { | 44 | if (high & (1<<27)) { |
43 | rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh); | 45 | rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); |
44 | printk ("[%08x%08x]", ahigh, alow); | 46 | snprintf(misc, 20, "[%08x%08x]", ahigh, alow); |
45 | } | 47 | } |
46 | if (high & (1<<26)) { | 48 | if (high & (1<<26)) { |
47 | rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh); | 49 | rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); |
48 | printk (" at %08x%08x", ahigh, alow); | 50 | snprintf(addr, 24, " at %08x%08x", ahigh, alow); |
49 | } | 51 | } |
50 | printk ("\n"); | 52 | printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", |
53 | smp_processor_id(), i, high, low, misc, addr); | ||
51 | /* Clear it */ | 54 | /* Clear it */ |
52 | wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); | 55 | wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); |
53 | /* Serialize */ | 56 | /* Serialize */ |
54 | wmb(); | 57 | wmb(); |
55 | add_taint(TAINT_MACHINE_CHECK); | 58 | add_taint(TAINT_MACHINE_CHECK); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.h b/arch/x86/kernel/cpu/mcheck/mce.h index 81fb6e2d35f3..ae9f628838f1 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.h +++ b/arch/x86/kernel/cpu/mcheck/mce.h | |||
@@ -8,7 +8,7 @@ void intel_p6_mcheck_init(struct cpuinfo_x86 *c); | |||
8 | void winchip_mcheck_init(struct cpuinfo_x86 *c); | 8 | void winchip_mcheck_init(struct cpuinfo_x86 *c); |
9 | 9 | ||
10 | /* Call the installed machine check handler for this CPU setup. */ | 10 | /* Call the installed machine check handler for this CPU setup. */ |
11 | extern fastcall void (*machine_check_vector)(struct pt_regs *, long error_code); | 11 | extern void (*machine_check_vector)(struct pt_regs *, long error_code); |
12 | 12 | ||
13 | extern int nr_mce_banks; | 13 | extern int nr_mce_banks; |
14 | 14 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_32.c b/arch/x86/kernel/cpu/mcheck/mce_32.c index 34c781eddee4..a5182dcd94ae 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_32.c +++ b/arch/x86/kernel/cpu/mcheck/mce_32.c | |||
@@ -22,13 +22,13 @@ int nr_mce_banks; | |||
22 | EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ | 22 | EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ |
23 | 23 | ||
24 | /* Handle unconfigured int18 (should never happen) */ | 24 | /* Handle unconfigured int18 (should never happen) */ |
25 | static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_code) | 25 | static void unexpected_machine_check(struct pt_regs * regs, long error_code) |
26 | { | 26 | { |
27 | printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id()); | 27 | printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id()); |
28 | } | 28 | } |
29 | 29 | ||
30 | /* Call the installed machine check handler for this CPU setup. */ | 30 | /* Call the installed machine check handler for this CPU setup. */ |
31 | void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; | 31 | void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check; |
32 | 32 | ||
33 | /* This has to be run for each processor */ | 33 | /* This has to be run for each processor */ |
34 | void mcheck_init(struct cpuinfo_x86 *c) | 34 | void mcheck_init(struct cpuinfo_x86 *c) |
diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c index 242e8668dbeb..9a699ed03598 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c | |||
@@ -63,7 +63,7 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait); | |||
63 | * separate MCEs from kernel messages to avoid bogus bug reports. | 63 | * separate MCEs from kernel messages to avoid bogus bug reports. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | struct mce_log mcelog = { | 66 | static struct mce_log mcelog = { |
67 | MCE_LOG_SIGNATURE, | 67 | MCE_LOG_SIGNATURE, |
68 | MCE_LOG_LEN, | 68 | MCE_LOG_LEN, |
69 | }; | 69 | }; |
@@ -80,7 +80,7 @@ void mce_log(struct mce *mce) | |||
80 | /* When the buffer fills up discard new entries. Assume | 80 | /* When the buffer fills up discard new entries. Assume |
81 | that the earlier errors are the more interesting. */ | 81 | that the earlier errors are the more interesting. */ |
82 | if (entry >= MCE_LOG_LEN) { | 82 | if (entry >= MCE_LOG_LEN) { |
83 | set_bit(MCE_OVERFLOW, &mcelog.flags); | 83 | set_bit(MCE_OVERFLOW, (unsigned long *)&mcelog.flags); |
84 | return; | 84 | return; |
85 | } | 85 | } |
86 | /* Old left over entry. Skip. */ | 86 | /* Old left over entry. Skip. */ |
@@ -110,12 +110,12 @@ static void print_mce(struct mce *m) | |||
110 | KERN_EMERG | 110 | KERN_EMERG |
111 | "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", | 111 | "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n", |
112 | m->cpu, m->mcgstatus, m->bank, m->status); | 112 | m->cpu, m->mcgstatus, m->bank, m->status); |
113 | if (m->rip) { | 113 | if (m->ip) { |
114 | printk(KERN_EMERG "RIP%s %02x:<%016Lx> ", | 114 | printk(KERN_EMERG "RIP%s %02x:<%016Lx> ", |
115 | !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", | 115 | !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", |
116 | m->cs, m->rip); | 116 | m->cs, m->ip); |
117 | if (m->cs == __KERNEL_CS) | 117 | if (m->cs == __KERNEL_CS) |
118 | print_symbol("{%s}", m->rip); | 118 | print_symbol("{%s}", m->ip); |
119 | printk("\n"); | 119 | printk("\n"); |
120 | } | 120 | } |
121 | printk(KERN_EMERG "TSC %Lx ", m->tsc); | 121 | printk(KERN_EMERG "TSC %Lx ", m->tsc); |
@@ -156,16 +156,16 @@ static int mce_available(struct cpuinfo_x86 *c) | |||
156 | static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) | 156 | static inline void mce_get_rip(struct mce *m, struct pt_regs *regs) |
157 | { | 157 | { |
158 | if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) { | 158 | if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) { |
159 | m->rip = regs->rip; | 159 | m->ip = regs->ip; |
160 | m->cs = regs->cs; | 160 | m->cs = regs->cs; |
161 | } else { | 161 | } else { |
162 | m->rip = 0; | 162 | m->ip = 0; |
163 | m->cs = 0; | 163 | m->cs = 0; |
164 | } | 164 | } |
165 | if (rip_msr) { | 165 | if (rip_msr) { |
166 | /* Assume the RIP in the MSR is exact. Is this true? */ | 166 | /* Assume the RIP in the MSR is exact. Is this true? */ |
167 | m->mcgstatus |= MCG_STATUS_EIPV; | 167 | m->mcgstatus |= MCG_STATUS_EIPV; |
168 | rdmsrl(rip_msr, m->rip); | 168 | rdmsrl(rip_msr, m->ip); |
169 | m->cs = 0; | 169 | m->cs = 0; |
170 | } | 170 | } |
171 | } | 171 | } |
@@ -192,10 +192,10 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
192 | 192 | ||
193 | atomic_inc(&mce_entry); | 193 | atomic_inc(&mce_entry); |
194 | 194 | ||
195 | if (regs) | 195 | if ((regs |
196 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, | 196 | && notify_die(DIE_NMI, "machine check", regs, error_code, |
197 | SIGKILL); | 197 | 18, SIGKILL) == NOTIFY_STOP) |
198 | if (!banks) | 198 | || !banks) |
199 | goto out2; | 199 | goto out2; |
200 | 200 | ||
201 | memset(&m, 0, sizeof(struct mce)); | 201 | memset(&m, 0, sizeof(struct mce)); |
@@ -288,7 +288,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
288 | * instruction which caused the MCE. | 288 | * instruction which caused the MCE. |
289 | */ | 289 | */ |
290 | if (m.mcgstatus & MCG_STATUS_EIPV) | 290 | if (m.mcgstatus & MCG_STATUS_EIPV) |
291 | user_space = panicm.rip && (panicm.cs & 3); | 291 | user_space = panicm.ip && (panicm.cs & 3); |
292 | 292 | ||
293 | /* | 293 | /* |
294 | * If we know that the error was in user space, send a | 294 | * If we know that the error was in user space, send a |
@@ -564,7 +564,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | |||
564 | loff_t *off) | 564 | loff_t *off) |
565 | { | 565 | { |
566 | unsigned long *cpu_tsc; | 566 | unsigned long *cpu_tsc; |
567 | static DECLARE_MUTEX(mce_read_sem); | 567 | static DEFINE_MUTEX(mce_read_mutex); |
568 | unsigned next; | 568 | unsigned next; |
569 | char __user *buf = ubuf; | 569 | char __user *buf = ubuf; |
570 | int i, err; | 570 | int i, err; |
@@ -573,12 +573,12 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | |||
573 | if (!cpu_tsc) | 573 | if (!cpu_tsc) |
574 | return -ENOMEM; | 574 | return -ENOMEM; |
575 | 575 | ||
576 | down(&mce_read_sem); | 576 | mutex_lock(&mce_read_mutex); |
577 | next = rcu_dereference(mcelog.next); | 577 | next = rcu_dereference(mcelog.next); |
578 | 578 | ||
579 | /* Only supports full reads right now */ | 579 | /* Only supports full reads right now */ |
580 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { | 580 | if (*off != 0 || usize < MCE_LOG_LEN*sizeof(struct mce)) { |
581 | up(&mce_read_sem); | 581 | mutex_unlock(&mce_read_mutex); |
582 | kfree(cpu_tsc); | 582 | kfree(cpu_tsc); |
583 | return -EINVAL; | 583 | return -EINVAL; |
584 | } | 584 | } |
@@ -621,7 +621,7 @@ static ssize_t mce_read(struct file *filp, char __user *ubuf, size_t usize, | |||
621 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); | 621 | memset(&mcelog.entry[i], 0, sizeof(struct mce)); |
622 | } | 622 | } |
623 | } | 623 | } |
624 | up(&mce_read_sem); | 624 | mutex_unlock(&mce_read_mutex); |
625 | kfree(cpu_tsc); | 625 | kfree(cpu_tsc); |
626 | return err ? -EFAULT : buf - ubuf; | 626 | return err ? -EFAULT : buf - ubuf; |
627 | } | 627 | } |
@@ -634,8 +634,7 @@ static unsigned int mce_poll(struct file *file, poll_table *wait) | |||
634 | return 0; | 634 | return 0; |
635 | } | 635 | } |
636 | 636 | ||
637 | static int mce_ioctl(struct inode *i, struct file *f,unsigned int cmd, | 637 | static long mce_ioctl(struct file *f, unsigned int cmd, unsigned long arg) |
638 | unsigned long arg) | ||
639 | { | 638 | { |
640 | int __user *p = (int __user *)arg; | 639 | int __user *p = (int __user *)arg; |
641 | 640 | ||
@@ -664,7 +663,7 @@ static const struct file_operations mce_chrdev_ops = { | |||
664 | .release = mce_release, | 663 | .release = mce_release, |
665 | .read = mce_read, | 664 | .read = mce_read, |
666 | .poll = mce_poll, | 665 | .poll = mce_poll, |
667 | .ioctl = mce_ioctl, | 666 | .unlocked_ioctl = mce_ioctl, |
668 | }; | 667 | }; |
669 | 668 | ||
670 | static struct miscdevice mce_log_device = { | 669 | static struct miscdevice mce_log_device = { |
@@ -855,8 +854,8 @@ static void mce_remove_device(unsigned int cpu) | |||
855 | } | 854 | } |
856 | 855 | ||
857 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ | 856 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ |
858 | static int | 857 | static int __cpuinit mce_cpu_callback(struct notifier_block *nfb, |
859 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 858 | unsigned long action, void *hcpu) |
860 | { | 859 | { |
861 | unsigned int cpu = (unsigned long)hcpu; | 860 | unsigned int cpu = (unsigned long)hcpu; |
862 | 861 | ||
@@ -873,7 +872,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
873 | return NOTIFY_OK; | 872 | return NOTIFY_OK; |
874 | } | 873 | } |
875 | 874 | ||
876 | static struct notifier_block mce_cpu_notifier = { | 875 | static struct notifier_block mce_cpu_notifier __cpuinitdata = { |
877 | .notifier_call = mce_cpu_callback, | 876 | .notifier_call = mce_cpu_callback, |
878 | }; | 877 | }; |
879 | 878 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c index 753588755fee..32671da8184e 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c +++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c | |||
@@ -118,6 +118,7 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
118 | { | 118 | { |
119 | unsigned int bank, block; | 119 | unsigned int bank, block; |
120 | unsigned int cpu = smp_processor_id(); | 120 | unsigned int cpu = smp_processor_id(); |
121 | u8 lvt_off; | ||
121 | u32 low = 0, high = 0, address = 0; | 122 | u32 low = 0, high = 0, address = 0; |
122 | 123 | ||
123 | for (bank = 0; bank < NR_BANKS; ++bank) { | 124 | for (bank = 0; bank < NR_BANKS; ++bank) { |
@@ -153,14 +154,13 @@ void __cpuinit mce_amd_feature_init(struct cpuinfo_x86 *c) | |||
153 | if (shared_bank[bank] && c->cpu_core_id) | 154 | if (shared_bank[bank] && c->cpu_core_id) |
154 | break; | 155 | break; |
155 | #endif | 156 | #endif |
157 | lvt_off = setup_APIC_eilvt_mce(THRESHOLD_APIC_VECTOR, | ||
158 | APIC_EILVT_MSG_FIX, 0); | ||
159 | |||
156 | high &= ~MASK_LVTOFF_HI; | 160 | high &= ~MASK_LVTOFF_HI; |
157 | high |= K8_APIC_EXT_LVT_ENTRY_THRESHOLD << 20; | 161 | high |= lvt_off << 20; |
158 | wrmsr(address, low, high); | 162 | wrmsr(address, low, high); |
159 | 163 | ||
160 | setup_APIC_extended_lvt(K8_APIC_EXT_LVT_ENTRY_THRESHOLD, | ||
161 | THRESHOLD_APIC_VECTOR, | ||
162 | K8_APIC_EXT_INT_MSG_FIX, 0); | ||
163 | |||
164 | threshold_defaults.address = address; | 164 | threshold_defaults.address = address; |
165 | threshold_restart_bank(&threshold_defaults, 0, 0); | 165 | threshold_restart_bank(&threshold_defaults, 0, 0); |
166 | } | 166 | } |
@@ -450,7 +450,8 @@ recurse: | |||
450 | if (err) | 450 | if (err) |
451 | goto out_free; | 451 | goto out_free; |
452 | 452 | ||
453 | kobject_uevent(&b->kobj, KOBJ_ADD); | 453 | if (b) |
454 | kobject_uevent(&b->kobj, KOBJ_ADD); | ||
454 | 455 | ||
455 | return err; | 456 | return err; |
456 | 457 | ||
@@ -554,7 +555,7 @@ static __cpuinit int threshold_create_device(unsigned int cpu) | |||
554 | int err = 0; | 555 | int err = 0; |
555 | 556 | ||
556 | for (bank = 0; bank < NR_BANKS; ++bank) { | 557 | for (bank = 0; bank < NR_BANKS; ++bank) { |
557 | if (!(per_cpu(bank_map, cpu) & 1 << bank)) | 558 | if (!(per_cpu(bank_map, cpu) & (1 << bank))) |
558 | continue; | 559 | continue; |
559 | err = threshold_create_bank(cpu, bank); | 560 | err = threshold_create_bank(cpu, bank); |
560 | if (err) | 561 | if (err) |
@@ -637,14 +638,14 @@ static void threshold_remove_device(unsigned int cpu) | |||
637 | unsigned int bank; | 638 | unsigned int bank; |
638 | 639 | ||
639 | for (bank = 0; bank < NR_BANKS; ++bank) { | 640 | for (bank = 0; bank < NR_BANKS; ++bank) { |
640 | if (!(per_cpu(bank_map, cpu) & 1 << bank)) | 641 | if (!(per_cpu(bank_map, cpu) & (1 << bank))) |
641 | continue; | 642 | continue; |
642 | threshold_remove_bank(cpu, bank); | 643 | threshold_remove_bank(cpu, bank); |
643 | } | 644 | } |
644 | } | 645 | } |
645 | 646 | ||
646 | /* get notified when a cpu comes on/off */ | 647 | /* get notified when a cpu comes on/off */ |
647 | static int threshold_cpu_callback(struct notifier_block *nfb, | 648 | static int __cpuinit threshold_cpu_callback(struct notifier_block *nfb, |
648 | unsigned long action, void *hcpu) | 649 | unsigned long action, void *hcpu) |
649 | { | 650 | { |
650 | /* cpu was unsigned int to begin with */ | 651 | /* cpu was unsigned int to begin with */ |
@@ -669,7 +670,7 @@ static int threshold_cpu_callback(struct notifier_block *nfb, | |||
669 | return NOTIFY_OK; | 670 | return NOTIFY_OK; |
670 | } | 671 | } |
671 | 672 | ||
672 | static struct notifier_block threshold_cpu_notifier = { | 673 | static struct notifier_block threshold_cpu_notifier __cpuinitdata = { |
673 | .notifier_call = threshold_cpu_callback, | 674 | .notifier_call = threshold_cpu_callback, |
674 | }; | 675 | }; |
675 | 676 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/p4.c b/arch/x86/kernel/cpu/mcheck/p4.c index be4dabfee1f5..cb03345554a5 100644 --- a/arch/x86/kernel/cpu/mcheck/p4.c +++ b/arch/x86/kernel/cpu/mcheck/p4.c | |||
@@ -57,7 +57,7 @@ static void intel_thermal_interrupt(struct pt_regs *regs) | |||
57 | /* Thermal interrupt handler for this CPU setup */ | 57 | /* Thermal interrupt handler for this CPU setup */ |
58 | static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt; | 58 | static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt; |
59 | 59 | ||
60 | fastcall void smp_thermal_interrupt(struct pt_regs *regs) | 60 | void smp_thermal_interrupt(struct pt_regs *regs) |
61 | { | 61 | { |
62 | irq_enter(); | 62 | irq_enter(); |
63 | vendor_thermal_interrupt(regs); | 63 | vendor_thermal_interrupt(regs); |
@@ -141,7 +141,7 @@ static inline void intel_get_extended_msrs(struct intel_mce_extended_msrs *r) | |||
141 | rdmsr (MSR_IA32_MCG_EIP, r->eip, h); | 141 | rdmsr (MSR_IA32_MCG_EIP, r->eip, h); |
142 | } | 142 | } |
143 | 143 | ||
144 | static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) | 144 | static void intel_machine_check(struct pt_regs * regs, long error_code) |
145 | { | 145 | { |
146 | int recover=1; | 146 | int recover=1; |
147 | u32 alow, ahigh, high, low; | 147 | u32 alow, ahigh, high, low; |
@@ -152,38 +152,41 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) | |||
152 | if (mcgstl & (1<<0)) /* Recoverable ? */ | 152 | if (mcgstl & (1<<0)) /* Recoverable ? */ |
153 | recover=0; | 153 | recover=0; |
154 | 154 | ||
155 | printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", | 155 | printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", |
156 | smp_processor_id(), mcgsth, mcgstl); | 156 | smp_processor_id(), mcgsth, mcgstl); |
157 | 157 | ||
158 | if (mce_num_extended_msrs > 0) { | 158 | if (mce_num_extended_msrs > 0) { |
159 | struct intel_mce_extended_msrs dbg; | 159 | struct intel_mce_extended_msrs dbg; |
160 | intel_get_extended_msrs(&dbg); | 160 | intel_get_extended_msrs(&dbg); |
161 | printk (KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n", | 161 | printk(KERN_DEBUG "CPU %d: EIP: %08x EFLAGS: %08x\n" |
162 | smp_processor_id(), dbg.eip, dbg.eflags); | 162 | "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n" |
163 | printk (KERN_DEBUG "\teax: %08x ebx: %08x ecx: %08x edx: %08x\n", | 163 | "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n", |
164 | dbg.eax, dbg.ebx, dbg.ecx, dbg.edx); | 164 | smp_processor_id(), dbg.eip, dbg.eflags, |
165 | printk (KERN_DEBUG "\tesi: %08x edi: %08x ebp: %08x esp: %08x\n", | 165 | dbg.eax, dbg.ebx, dbg.ecx, dbg.edx, |
166 | dbg.esi, dbg.edi, dbg.ebp, dbg.esp); | 166 | dbg.esi, dbg.edi, dbg.ebp, dbg.esp); |
167 | } | 167 | } |
168 | 168 | ||
169 | for (i=0; i<nr_mce_banks; i++) { | 169 | for (i = 0; i < nr_mce_banks; i++) { |
170 | rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high); | 170 | rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); |
171 | if (high & (1<<31)) { | 171 | if (high & (1<<31)) { |
172 | char misc[20]; | ||
173 | char addr[24]; | ||
174 | misc[0] = addr[0] = '\0'; | ||
172 | if (high & (1<<29)) | 175 | if (high & (1<<29)) |
173 | recover |= 1; | 176 | recover |= 1; |
174 | if (high & (1<<25)) | 177 | if (high & (1<<25)) |
175 | recover |= 2; | 178 | recover |= 2; |
176 | printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low); | ||
177 | high &= ~(1<<31); | 179 | high &= ~(1<<31); |
178 | if (high & (1<<27)) { | 180 | if (high & (1<<27)) { |
179 | rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh); | 181 | rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); |
180 | printk ("[%08x%08x]", ahigh, alow); | 182 | snprintf(misc, 20, "[%08x%08x]", ahigh, alow); |
181 | } | 183 | } |
182 | if (high & (1<<26)) { | 184 | if (high & (1<<26)) { |
183 | rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh); | 185 | rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); |
184 | printk (" at %08x%08x", ahigh, alow); | 186 | snprintf(addr, 24, " at %08x%08x", ahigh, alow); |
185 | } | 187 | } |
186 | printk ("\n"); | 188 | printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", |
189 | smp_processor_id(), i, high, low, misc, addr); | ||
187 | } | 190 | } |
188 | } | 191 | } |
189 | 192 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/p5.c b/arch/x86/kernel/cpu/mcheck/p5.c index 94bc43d950cf..a18310aaae0c 100644 --- a/arch/x86/kernel/cpu/mcheck/p5.c +++ b/arch/x86/kernel/cpu/mcheck/p5.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include "mce.h" | 16 | #include "mce.h" |
17 | 17 | ||
18 | /* Machine check handler for Pentium class Intel */ | 18 | /* Machine check handler for Pentium class Intel */ |
19 | static fastcall void pentium_machine_check(struct pt_regs * regs, long error_code) | 19 | static void pentium_machine_check(struct pt_regs * regs, long error_code) |
20 | { | 20 | { |
21 | u32 loaddr, hi, lotype; | 21 | u32 loaddr, hi, lotype; |
22 | rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi); | 22 | rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi); |
diff --git a/arch/x86/kernel/cpu/mcheck/p6.c b/arch/x86/kernel/cpu/mcheck/p6.c index deeae42ce199..74342604d30e 100644 --- a/arch/x86/kernel/cpu/mcheck/p6.c +++ b/arch/x86/kernel/cpu/mcheck/p6.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include "mce.h" | 16 | #include "mce.h" |
17 | 17 | ||
18 | /* Machine Check Handler For PII/PIII */ | 18 | /* Machine Check Handler For PII/PIII */ |
19 | static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) | 19 | static void intel_machine_check(struct pt_regs * regs, long error_code) |
20 | { | 20 | { |
21 | int recover=1; | 21 | int recover=1; |
22 | u32 alow, ahigh, high, low; | 22 | u32 alow, ahigh, high, low; |
@@ -27,27 +27,30 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code) | |||
27 | if (mcgstl & (1<<0)) /* Recoverable ? */ | 27 | if (mcgstl & (1<<0)) /* Recoverable ? */ |
28 | recover=0; | 28 | recover=0; |
29 | 29 | ||
30 | printk (KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", | 30 | printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", |
31 | smp_processor_id(), mcgsth, mcgstl); | 31 | smp_processor_id(), mcgsth, mcgstl); |
32 | 32 | ||
33 | for (i=0; i<nr_mce_banks; i++) { | 33 | for (i = 0; i < nr_mce_banks; i++) { |
34 | rdmsr (MSR_IA32_MC0_STATUS+i*4,low, high); | 34 | rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); |
35 | if (high & (1<<31)) { | 35 | if (high & (1<<31)) { |
36 | char misc[20]; | ||
37 | char addr[24]; | ||
38 | misc[0] = addr[0] = '\0'; | ||
36 | if (high & (1<<29)) | 39 | if (high & (1<<29)) |
37 | recover |= 1; | 40 | recover |= 1; |
38 | if (high & (1<<25)) | 41 | if (high & (1<<25)) |
39 | recover |= 2; | 42 | recover |= 2; |
40 | printk (KERN_EMERG "Bank %d: %08x%08x", i, high, low); | ||
41 | high &= ~(1<<31); | 43 | high &= ~(1<<31); |
42 | if (high & (1<<27)) { | 44 | if (high & (1<<27)) { |
43 | rdmsr (MSR_IA32_MC0_MISC+i*4, alow, ahigh); | 45 | rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); |
44 | printk ("[%08x%08x]", ahigh, alow); | 46 | snprintf(misc, 20, "[%08x%08x]", ahigh, alow); |
45 | } | 47 | } |
46 | if (high & (1<<26)) { | 48 | if (high & (1<<26)) { |
47 | rdmsr (MSR_IA32_MC0_ADDR+i*4, alow, ahigh); | 49 | rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); |
48 | printk (" at %08x%08x", ahigh, alow); | 50 | snprintf(addr, 24, " at %08x%08x", ahigh, alow); |
49 | } | 51 | } |
50 | printk ("\n"); | 52 | printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", |
53 | smp_processor_id(), i, high, low, misc, addr); | ||
51 | } | 54 | } |
52 | } | 55 | } |
53 | 56 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/winchip.c b/arch/x86/kernel/cpu/mcheck/winchip.c index 9e424b6c293d..3d428d5afc52 100644 --- a/arch/x86/kernel/cpu/mcheck/winchip.c +++ b/arch/x86/kernel/cpu/mcheck/winchip.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "mce.h" | 15 | #include "mce.h" |
16 | 16 | ||
17 | /* Machine check handler for WinChip C6 */ | 17 | /* Machine check handler for WinChip C6 */ |
18 | static fastcall void winchip_machine_check(struct pt_regs * regs, long error_code) | 18 | static void winchip_machine_check(struct pt_regs * regs, long error_code) |
19 | { | 19 | { |
20 | printk(KERN_EMERG "CPU0: Machine Check Exception.\n"); | 20 | printk(KERN_EMERG "CPU0: Machine Check Exception.\n"); |
21 | add_taint(TAINT_MACHINE_CHECK); | 21 | add_taint(TAINT_MACHINE_CHECK); |