aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorJacob Pan <jacob.jun.pan@linux.intel.com>2011-11-10 08:43:05 -0500
committerIngo Molnar <mingo@elte.hu>2011-11-10 10:21:01 -0500
commit064a59b6dd1f341cc478c212bb436e3da9cb8d04 (patch)
tree44a5075e6b913493391911a57ebbe3cc6a25c26e /arch/x86
parent0a9153261d54c432bc0bdc88607f24c835ac729c (diff)
x86/mrst: Avoid reporting wrong nmi status
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>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/mach_traps.h2
-rw-r--r--arch/x86/include/asm/x86_init.h1
-rw-r--r--arch/x86/kernel/nmi.c2
-rw-r--r--arch/x86/kernel/x86_init.c2
-rw-r--r--arch/x86/platform/mrst/mrst.c13
5 files changed, 18 insertions, 2 deletions
diff --git a/arch/x86/include/asm/mach_traps.h b/arch/x86/include/asm/mach_traps.h
index 72a8b52e7dfd..a01e7ec7d237 100644
--- a/arch/x86/include/asm/mach_traps.h
+++ b/arch/x86/include/asm/mach_traps.h
@@ -17,7 +17,7 @@
17#define NMI_REASON_CLEAR_IOCHK 0x08 17#define NMI_REASON_CLEAR_IOCHK 0x08
18#define NMI_REASON_CLEAR_MASK 0x0f 18#define NMI_REASON_CLEAR_MASK 0x0f
19 19
20static inline unsigned char get_nmi_reason(void) 20static inline unsigned char default_get_nmi_reason(void)
21{ 21{
22 return inb(NMI_REASON_PORT); 22 return inb(NMI_REASON_PORT);
23} 23}
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f864fbe474c6..1971e652d24b 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -167,6 +167,7 @@ struct x86_platform_ops {
167 void (*iommu_shutdown)(void); 167 void (*iommu_shutdown)(void);
168 bool (*is_untracked_pat_range)(u64 start, u64 end); 168 bool (*is_untracked_pat_range)(u64 start, u64 end);
169 void (*nmi_init)(void); 169 void (*nmi_init)(void);
170 unsigned char (*get_nmi_reason)(void);
170 int (*i8042_detect)(void); 171 int (*i8042_detect)(void);
171}; 172};
172 173
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index b9c8628974af..27d1e7cbdb6c 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -348,7 +348,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
348 348
349 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */ 349 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */
350 raw_spin_lock(&nmi_reason_lock); 350 raw_spin_lock(&nmi_reason_lock);
351 reason = get_nmi_reason(); 351 reason = x86_platform.get_nmi_reason();
352 352
353 if (reason & NMI_REASON_MASK) { 353 if (reason & NMI_REASON_MASK) {
354 if (reason & NMI_REASON_SERR) 354 if (reason & NMI_REASON_SERR)
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 701c7be442f1..c1d6cd549397 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -21,6 +21,7 @@
21#include <asm/pat.h> 21#include <asm/pat.h>
22#include <asm/tsc.h> 22#include <asm/tsc.h>
23#include <asm/iommu.h> 23#include <asm/iommu.h>
24#include <asm/mach_traps.h>
24 25
25void __cpuinit x86_init_noop(void) { } 26void __cpuinit x86_init_noop(void) { }
26void __init x86_init_uint_noop(unsigned int unused) { } 27void __init x86_init_uint_noop(unsigned int unused) { }
@@ -104,6 +105,7 @@ struct x86_platform_ops x86_platform = {
104 .iommu_shutdown = iommu_shutdown_noop, 105 .iommu_shutdown = iommu_shutdown_noop,
105 .is_untracked_pat_range = is_ISA_range, 106 .is_untracked_pat_range = is_ISA_range,
106 .nmi_init = default_nmi_init, 107 .nmi_init = default_nmi_init,
108 .get_nmi_reason = default_get_nmi_reason,
107 .i8042_detect = default_i8042_detect 109 .i8042_detect = default_i8042_detect
108}; 110};
109 111
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
index b7f14e5b2c66..9b9ee292c107 100644
--- a/arch/x86/platform/mrst/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
@@ -277,6 +277,17 @@ static void mrst_reboot(void)
277} 277}
278 278
279/* 279/*
280 * Moorestown does not have external NMI source nor port 0x61 to report
281 * NMI status. The possible NMI sources are from pmu as a result of NMI
282 * watchdog or lock debug. Reading io port 0x61 results in 0xff which
283 * misled NMI handler.
284 */
285static unsigned char mrst_get_nmi_reason(void)
286{
287 return 0;
288}
289
290/*
280 * Moorestown specific x86_init function overrides and early setup 291 * Moorestown specific x86_init function overrides and early setup
281 * calls. 292 * calls.
282 */ 293 */
@@ -297,6 +308,8 @@ void __init x86_mrst_early_setup(void)
297 x86_platform.calibrate_tsc = mrst_calibrate_tsc; 308 x86_platform.calibrate_tsc = mrst_calibrate_tsc;
298 x86_platform.i8042_detect = mrst_i8042_detect; 309 x86_platform.i8042_detect = mrst_i8042_detect;
299 x86_init.timers.wallclock_init = mrst_rtc_init; 310 x86_init.timers.wallclock_init = mrst_rtc_init;
311 x86_platform.get_nmi_reason = mrst_get_nmi_reason;
312
300 x86_init.pci.init = pci_mrst_init; 313 x86_init.pci.init = pci_mrst_init;
301 x86_init.pci.fixup_irqs = x86_init_noop; 314 x86_init.pci.fixup_irqs = x86_init_noop;
302 315