Merge branch 'x86/mce' into x86/urgent
[platform/upstream/kernel-adaptation-pc.git] / arch / x86 / kernel / cpu / mcheck / mce.c
index 11c9166..aaa056f 100644 (file)
@@ -583,7 +583,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
        struct mce m;
        int i;
 
-       percpu_inc(mce_poll_count);
+       this_cpu_inc(mce_poll_count);
 
        mce_gather_info(&m, NULL);
 
@@ -1017,7 +1017,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 
        atomic_inc(&mce_entry);
 
-       percpu_inc(mce_exception_count);
+       this_cpu_inc(mce_exception_count);
 
        if (!banks)
                goto out;
@@ -1431,6 +1431,43 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c)
                 */
                 if (c->x86 == 6 && banks > 0)
                        mce_banks[0].ctl = 0;
+
+                /*
+                 * Turn off MC4_MISC thresholding banks on those models since
+                 * they're not supported there.
+                 */
+                if (c->x86 == 0x15 &&
+                    (c->x86_model >= 0x10 && c->x86_model <= 0x1f)) {
+                        int i;
+                        u64 val, hwcr;
+                        bool need_toggle;
+                        u32 msrs[] = {
+                               0x00000413, /* MC4_MISC0 */
+                               0xc0000408, /* MC4_MISC1 */
+                        };
+
+                        rdmsrl(MSR_K7_HWCR, hwcr);
+
+                        /* McStatusWrEn has to be set */
+                        need_toggle = !(hwcr & BIT(18));
+
+                        if (need_toggle)
+                                wrmsrl(MSR_K7_HWCR, hwcr | BIT(18));
+
+                        for (i = 0; i < ARRAY_SIZE(msrs); i++) {
+                                rdmsrl(msrs[i], val);
+
+                                /* CntP bit set? */
+                                if (val & BIT_64(62)) {
+                                       val &= ~BIT_64(62);
+                                       wrmsrl(msrs[i], val);
+                                }
+                        }
+
+                        /* restore old settings */
+                        if (need_toggle)
+                                wrmsrl(MSR_K7_HWCR, hwcr);
+                }
        }
 
        if (c->x86_vendor == X86_VENDOR_INTEL) {