]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
x86/mrst: Avoid reporting wrong nmi status
authorJacob Pan <jacob.jun.pan@linux.intel.com>
Thu, 10 Nov 2011 13:43:05 +0000 (13:43 +0000)
committerIngo Molnar <mingo@elte.hu>
Thu, 10 Nov 2011 15:21:01 +0000 (16:21 +0100)
Moorestown/Medfield platform does not have port 0x61 to report
NMI status, nor does it have external NMI sources. The only NMI
sources are from lapic, as results of perf counter overflow or
IPI, e.g. NMI watchdog or spin lock debug.

Reading port 0x61 on Moorestown will return 0xff which misled
NMI handlers to false critical errors such memory parity error.
The subsequent ioport access for NMI handling can also cause
undefined behavior on Moorestown.

This patch allows kernel process NMI due to watchdog or backrace
dump without unnecessary hangs.

Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
[hand applied]
Signed-off-by: Alan Cox <alan@linux.intel.com>
arch/x86/include/asm/mach_traps.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/nmi.c
arch/x86/kernel/x86_init.c
arch/x86/platform/mrst/mrst.c

index 72a8b52e7dfd0de3fa4271284fdd4a76da7fb31b..a01e7ec7d2377aaede271b6ad4ddd546ef5238a5 100644 (file)
@@ -17,7 +17,7 @@
 #define NMI_REASON_CLEAR_IOCHK 0x08
 #define NMI_REASON_CLEAR_MASK  0x0f
 
-static inline unsigned char get_nmi_reason(void)
+static inline unsigned char default_get_nmi_reason(void)
 {
        return inb(NMI_REASON_PORT);
 }
index f864fbe474c6b31e0f081bc0d8c945e39c00fe84..1971e652d24be5fc0674633c1edb3717645306e7 100644 (file)
@@ -167,6 +167,7 @@ struct x86_platform_ops {
        void (*iommu_shutdown)(void);
        bool (*is_untracked_pat_range)(u64 start, u64 end);
        void (*nmi_init)(void);
+       unsigned char (*get_nmi_reason)(void);
        int (*i8042_detect)(void);
 };
 
index b9c8628974af3ae4eeb7cc73891140618df589b2..27d1e7cbdb6c06832891677c62f0e4e92a6d428b 100644 (file)
@@ -348,7 +348,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
 
        /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
        raw_spin_lock(&nmi_reason_lock);
-       reason = get_nmi_reason();
+       reason = x86_platform.get_nmi_reason();
 
        if (reason & NMI_REASON_MASK) {
                if (reason & NMI_REASON_SERR)
index 701c7be442f1ca6dc5712605fecfcea6a837c92e..c1d6cd549397ad54dbcb32526c9170e1f590a759 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/pat.h>
 #include <asm/tsc.h>
 #include <asm/iommu.h>
+#include <asm/mach_traps.h>
 
 void __cpuinit x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
@@ -104,6 +105,7 @@ struct x86_platform_ops x86_platform = {
        .iommu_shutdown                 = iommu_shutdown_noop,
        .is_untracked_pat_range         = is_ISA_range,
        .nmi_init                       = default_nmi_init,
+       .get_nmi_reason                 = default_get_nmi_reason,
        .i8042_detect                   = default_i8042_detect
 };
 
index b7f14e5b2c661ecfbfe356a5c2529444f3139532..9b9ee292c107f0b206dd97eb5a9aa2843ebbb171 100644 (file)
@@ -276,6 +276,17 @@ static void mrst_reboot(void)
        intel_scu_ipc_simple_command(0xf1, 0);
 }
 
+/*
+ * Moorestown does not have external NMI source nor port 0x61 to report
+ * NMI status. The possible NMI sources are from pmu as a result of NMI
+ * watchdog or lock debug. Reading io port 0x61 results in 0xff which
+ * misled NMI handler.
+ */
+static unsigned char mrst_get_nmi_reason(void)
+{
+       return 0;
+}
+
 /*
  * Moorestown specific x86_init function overrides and early setup
  * calls.
@@ -297,6 +308,8 @@ void __init x86_mrst_early_setup(void)
        x86_platform.calibrate_tsc = mrst_calibrate_tsc;
        x86_platform.i8042_detect = mrst_i8042_detect;
        x86_init.timers.wallclock_init = mrst_rtc_init;
+       x86_platform.get_nmi_reason = mrst_get_nmi_reason;
+
        x86_init.pci.init = pci_mrst_init;
        x86_init.pci.fixup_irqs = x86_init_noop;