Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jacob Pan and committed by
Ingo Molnar
064a59b6 0a915326

+18 -2
+1 -1
arch/x86/include/asm/mach_traps.h
··· 17 17 #define NMI_REASON_CLEAR_IOCHK 0x08 18 18 #define NMI_REASON_CLEAR_MASK 0x0f 19 19 20 - static inline unsigned char get_nmi_reason(void) 20 + static inline unsigned char default_get_nmi_reason(void) 21 21 { 22 22 return inb(NMI_REASON_PORT); 23 23 }
+1
arch/x86/include/asm/x86_init.h
··· 167 167 void (*iommu_shutdown)(void); 168 168 bool (*is_untracked_pat_range)(u64 start, u64 end); 169 169 void (*nmi_init)(void); 170 + unsigned char (*get_nmi_reason)(void); 170 171 int (*i8042_detect)(void); 171 172 }; 172 173
+1 -1
arch/x86/kernel/nmi.c
··· 348 348 349 349 /* Non-CPU-specific NMI: NMI sources can be processed on any CPU */ 350 350 raw_spin_lock(&nmi_reason_lock); 351 - reason = get_nmi_reason(); 351 + reason = x86_platform.get_nmi_reason(); 352 352 353 353 if (reason & NMI_REASON_MASK) { 354 354 if (reason & NMI_REASON_SERR)
+2
arch/x86/kernel/x86_init.c
··· 21 21 #include <asm/pat.h> 22 22 #include <asm/tsc.h> 23 23 #include <asm/iommu.h> 24 + #include <asm/mach_traps.h> 24 25 25 26 void __cpuinit x86_init_noop(void) { } 26 27 void __init x86_init_uint_noop(unsigned int unused) { } ··· 105 104 .iommu_shutdown = iommu_shutdown_noop, 106 105 .is_untracked_pat_range = is_ISA_range, 107 106 .nmi_init = default_nmi_init, 107 + .get_nmi_reason = default_get_nmi_reason, 108 108 .i8042_detect = default_i8042_detect 109 109 }; 110 110
+13
arch/x86/platform/mrst/mrst.c
··· 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 + */ 285 + static unsigned char mrst_get_nmi_reason(void) 286 + { 287 + return 0; 288 + } 289 + 290 + /* 280 291 * Moorestown specific x86_init function overrides and early setup 281 292 * calls. 282 293 */ ··· 308 297 x86_platform.calibrate_tsc = mrst_calibrate_tsc; 309 298 x86_platform.i8042_detect = mrst_i8042_detect; 310 299 x86_init.timers.wallclock_init = mrst_rtc_init; 300 + x86_platform.get_nmi_reason = mrst_get_nmi_reason; 301 + 311 302 x86_init.pci.init = pci_mrst_init; 312 303 x86_init.pci.fixup_irqs = x86_init_noop; 313 304