aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mcheck
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-09-19 11:01:25 -0400
committerIngo Molnar <mingo@kernel.org>2012-09-19 11:01:25 -0400
commitf1f652447694f92beff8a534d94b36ea441c939a (patch)
tree177f029e418d517e39dfa2495a9a67a45381b833 /arch/x86/kernel/cpu/mcheck
parent55babd8f41f122f5f4c7cebf520c766c983282c6 (diff)
parent5698bd757d55b1bb87edd1a9744ab09c142abfc2 (diff)
Merge tag 'v3.6-rc6' into x86/mce
Merge Linux v3.6-rc6, to refresh this tree. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/cpu/mcheck')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-severity.c7
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c43
2 files changed, 40 insertions, 10 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 413c2ced887c..13017626f9a8 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -55,13 +55,6 @@ static struct severity {
55#define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S) 55#define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S)
56#define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR) 56#define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR)
57#define MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV) 57#define MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV)
58#define MCACOD 0xffff
59/* Architecturally defined codes from SDM Vol. 3B Chapter 15 */
60#define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */
61#define MCACOD_SCRUBMSK 0xfff0
62#define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */
63#define MCACOD_DATA 0x0134 /* Data Load */
64#define MCACOD_INSTR 0x0150 /* Instruction Fetch */
65 58
66 MCESEV( 59 MCESEV(
67 NO, "Invalid", 60 NO, "Invalid",
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 8c1beea6cabf..c311122ea838 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -103,6 +103,8 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
103 103
104static DEFINE_PER_CPU(struct work_struct, mce_work); 104static DEFINE_PER_CPU(struct work_struct, mce_work);
105 105
106static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
107
106/* 108/*
107 * CPU/chipset specific EDAC code can register a notifier call here to print 109 * CPU/chipset specific EDAC code can register a notifier call here to print
108 * MCE errors in a human-readable form. 110 * MCE errors in a human-readable form.
@@ -650,14 +652,18 @@ EXPORT_SYMBOL_GPL(machine_check_poll);
650 * Do a quick check if any of the events requires a panic. 652 * Do a quick check if any of the events requires a panic.
651 * This decides if we keep the events around or clear them. 653 * This decides if we keep the events around or clear them.
652 */ 654 */
653static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp) 655static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp,
656 struct pt_regs *regs)
654{ 657{
655 int i, ret = 0; 658 int i, ret = 0;
656 659
657 for (i = 0; i < banks; i++) { 660 for (i = 0; i < banks; i++) {
658 m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); 661 m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i));
659 if (m->status & MCI_STATUS_VAL) 662 if (m->status & MCI_STATUS_VAL) {
660 __set_bit(i, validp); 663 __set_bit(i, validp);
664 if (quirk_no_way_out)
665 quirk_no_way_out(i, m, regs);
666 }
661 if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) 667 if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY)
662 ret = 1; 668 ret = 1;
663 } 669 }
@@ -1040,7 +1046,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
1040 *final = m; 1046 *final = m;
1041 1047
1042 memset(valid_banks, 0, sizeof(valid_banks)); 1048 memset(valid_banks, 0, sizeof(valid_banks));
1043 no_way_out = mce_no_way_out(&m, &msg, valid_banks); 1049 no_way_out = mce_no_way_out(&m, &msg, valid_banks, regs);
1044 1050
1045 barrier(); 1051 barrier();
1046 1052
@@ -1451,6 +1457,34 @@ static void __mcheck_cpu_init_generic(void)
1451 } 1457 }
1452} 1458}
1453 1459
1460/*
1461 * During IFU recovery Sandy Bridge -EP4S processors set the RIPV and
1462 * EIPV bits in MCG_STATUS to zero on the affected logical processor (SDM
1463 * Vol 3B Table 15-20). But this confuses both the code that determines
1464 * whether the machine check occurred in kernel or user mode, and also
1465 * the severity assessment code. Pretend that EIPV was set, and take the
1466 * ip/cs values from the pt_regs that mce_gather_info() ignored earlier.
1467 */
1468static void quirk_sandybridge_ifu(int bank, struct mce *m, struct pt_regs *regs)
1469{
1470 if (bank != 0)
1471 return;
1472 if ((m->mcgstatus & (MCG_STATUS_EIPV|MCG_STATUS_RIPV)) != 0)
1473 return;
1474 if ((m->status & (MCI_STATUS_OVER|MCI_STATUS_UC|
1475 MCI_STATUS_EN|MCI_STATUS_MISCV|MCI_STATUS_ADDRV|
1476 MCI_STATUS_PCC|MCI_STATUS_S|MCI_STATUS_AR|
1477 MCACOD)) !=
1478 (MCI_STATUS_UC|MCI_STATUS_EN|
1479 MCI_STATUS_MISCV|MCI_STATUS_ADDRV|MCI_STATUS_S|
1480 MCI_STATUS_AR|MCACOD_INSTR))
1481 return;
1482
1483 m->mcgstatus |= MCG_STATUS_EIPV;
1484 m->ip = regs->ip;
1485 m->cs = regs->cs;
1486}
1487
1454/* Add per CPU specific workarounds here */ 1488/* Add per CPU specific workarounds here */
1455static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) 1489static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
1456{ 1490{
@@ -1548,6 +1582,9 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
1548 */ 1582 */
1549 if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) 1583 if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0)
1550 mce_bootlog = 0; 1584 mce_bootlog = 0;
1585
1586 if (c->x86 == 6 && c->x86_model == 45)
1587 quirk_no_way_out = quirk_sandybridge_ifu;
1551 } 1588 }
1552 if (monarch_timeout < 0) 1589 if (monarch_timeout < 0)
1553 monarch_timeout = 0; 1590 monarch_timeout = 0;