diff options
author | Ingo Molnar <mingo@kernel.org> | 2012-09-19 11:01:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2012-09-19 11:01:25 -0400 |
commit | f1f652447694f92beff8a534d94b36ea441c939a (patch) | |
tree | 177f029e418d517e39dfa2495a9a67a45381b833 /arch/x86/kernel/cpu/mcheck | |
parent | 55babd8f41f122f5f4c7cebf520c766c983282c6 (diff) | |
parent | 5698bd757d55b1bb87edd1a9744ab09c142abfc2 (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.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mcheck/mce.c | 43 |
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 | ||
104 | static DEFINE_PER_CPU(struct work_struct, mce_work); | 104 | static DEFINE_PER_CPU(struct work_struct, mce_work); |
105 | 105 | ||
106 | static 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 | */ |
653 | static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp) | 655 | static 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 | */ | ||
1468 | static 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 */ |
1455 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | 1489 | static 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; |