]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'please-pull-mce' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Jun 2012 22:15:04 +0000 (15:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Jun 2012 22:15:04 +0000 (15:15 -0700)
Pull MCE regression fix from Tony Luck:
 "Typo/thinko in a cleanup caused a semantic change. Fix it."

* tag 'please-pull-mce' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
  x86/mce: Fix the MCE poll timer logic

1  2 
arch/x86/kernel/cpu/mcheck/mce.c

index 0a687fd185e6c97b496578d1dc6acb4001c2833d,d6b18a4d0b95559c8cc66c008bfa47b548dad374..a97f3c4a3946b7e7d3b8be67129a33166ab2b61c
@@@ -591,7 -591,7 +591,7 @@@ void machine_check_poll(enum mcp_flags 
        struct mce m;
        int i;
  
 -      percpu_inc(mce_poll_count);
 +      this_cpu_inc(mce_poll_count);
  
        mce_gather_info(&m, NULL);
  
@@@ -955,10 -955,9 +955,10 @@@ struct mce_info 
        atomic_t                inuse;
        struct task_struct      *t;
        __u64                   paddr;
 +      int                     restartable;
  } mce_info[MCE_INFO_MAX];
  
 -static void mce_save_info(__u64 addr)
 +static void mce_save_info(__u64 addr, int c)
  {
        struct mce_info *mi;
  
                if (atomic_cmpxchg(&mi->inuse, 0, 1) == 0) {
                        mi->t = current;
                        mi->paddr = addr;
 +                      mi->restartable = c;
                        return;
                }
        }
@@@ -1028,7 -1026,7 +1028,7 @@@ void do_machine_check(struct pt_regs *r
  
        atomic_inc(&mce_entry);
  
 -      percpu_inc(mce_exception_count);
 +      this_cpu_inc(mce_exception_count);
  
        if (!banks)
                goto out;
                        mce_panic("Fatal machine check on current CPU", &m, msg);
                if (worst == MCE_AR_SEVERITY) {
                        /* schedule action before return to userland */
 -                      mce_save_info(m.addr);
 +                      mce_save_info(m.addr, m.mcgstatus & MCG_STATUS_RIPV);
                        set_thread_flag(TIF_MCE_NOTIFY);
                } else if (kill_it) {
                        force_sig(SIGBUS, current);
@@@ -1195,13 -1193,7 +1195,13 @@@ void mce_notify_process(void
  
        pr_err("Uncorrected hardware memory error in user-access at %llx",
                 mi->paddr);
 -      if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) {
 +      /*
 +       * We must call memory_failure() here even if the current process is
 +       * doomed. We still need to mark the page as poisoned and alert any
 +       * other users of the page.
 +       */
 +      if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0 ||
 +                         mi->restartable == 0) {
                pr_err("Memory error not recovered");
                force_sig(SIGBUS, current);
        }
@@@ -1274,7 -1266,7 +1274,7 @@@ static void mce_timer_fn(unsigned long 
         */
        iv = __this_cpu_read(mce_next_interval);
        if (mce_notify_irq())
-               iv = max(iv, (unsigned long) HZ/100);
+               iv = max(iv / 2, (unsigned long) HZ/100);
        else
                iv = min(iv * 2, round_jiffies_relative(check_interval * HZ));
        __this_cpu_write(mce_next_interval, iv);
@@@ -1446,43 -1438,6 +1446,43 @@@ static int __cpuinit __mcheck_cpu_apply
                 */
                 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) {