aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mcheck/mce.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck/mce.c')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 2afcbd253e1d..b772dd6ad450 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -437,6 +437,14 @@ static inline void mce_gather_info(struct mce *m, struct pt_regs *regs)
437 if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) { 437 if (m->mcgstatus & (MCG_STATUS_RIPV|MCG_STATUS_EIPV)) {
438 m->ip = regs->ip; 438 m->ip = regs->ip;
439 m->cs = regs->cs; 439 m->cs = regs->cs;
440
441 /*
442 * When in VM86 mode make the cs look like ring 3
443 * always. This is a lie, but it's better than passing
444 * the additional vm86 bit around everywhere.
445 */
446 if (v8086_mode(regs))
447 m->cs |= 3;
440 } 448 }
441 /* Use accurate RIP reporting if available. */ 449 /* Use accurate RIP reporting if available. */
442 if (rip_msr) 450 if (rip_msr)
@@ -641,16 +649,18 @@ EXPORT_SYMBOL_GPL(machine_check_poll);
641 * Do a quick check if any of the events requires a panic. 649 * Do a quick check if any of the events requires a panic.
642 * This decides if we keep the events around or clear them. 650 * This decides if we keep the events around or clear them.
643 */ 651 */
644static int mce_no_way_out(struct mce *m, char **msg) 652static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp)
645{ 653{
646 int i; 654 int i, ret = 0;
647 655
648 for (i = 0; i < banks; i++) { 656 for (i = 0; i < banks; i++) {
649 m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); 657 m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
658 if (m->status & MCI_STATUS_VAL)
659 __set_bit(i, validp);
650 if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) 660 if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
651 return 1; 661 ret = 1;
652 } 662 }
653 return 0; 663 return ret;
654} 664}
655 665
656/* 666/*
@@ -1013,6 +1023,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1013 */ 1023 */
1014 int kill_it = 0; 1024 int kill_it = 0;
1015 DECLARE_BITMAP(toclear, MAX_NR_BANKS); 1025 DECLARE_BITMAP(toclear, MAX_NR_BANKS);
1026 DECLARE_BITMAP(valid_banks, MAX_NR_BANKS);
1016 char *msg = "Unknown"; 1027 char *msg = "Unknown";
1017 1028
1018 atomic_inc(&mce_entry); 1029 atomic_inc(&mce_entry);
@@ -1027,7 +1038,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1027 final = &__get_cpu_var(mces_seen); 1038 final = &__get_cpu_var(mces_seen);
1028 *final = m; 1039 *final = m;
1029 1040
1030 no_way_out = mce_no_way_out(&m, &msg); 1041 memset(valid_banks, 0, sizeof(valid_banks));
1042 no_way_out = mce_no_way_out(&m, &msg, valid_banks);
1031 1043
1032 barrier(); 1044 barrier();
1033 1045
@@ -1047,6 +1059,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1047 order = mce_start(&no_way_out); 1059 order = mce_start(&no_way_out);
1048 for (i = 0; i < banks; i++) { 1060 for (i = 0; i < banks; i++) {
1049 __clear_bit(i, toclear); 1061 __clear_bit(i, toclear);
1062 if (!test_bit(i, valid_banks))
1063 continue;
1050 if (!mce_banks[i].ctl) 1064 if (!mce_banks[i].ctl)
1051 continue; 1065 continue;
1052 1066