Skip to content

Commit

Permalink
x86/mrst: Avoid reporting wrong nmi status
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jacob Pan authored and Ingo Molnar committed Nov 10, 2011
1 parent 0a91532 commit 064a59b
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 2 deletions.
2 changes: 1 addition & 1 deletion arch/x86/include/asm/mach_traps.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/x86_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/kernel/x86_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) { }
Expand Down Expand Up @@ -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
};

Expand Down
13 changes: 13 additions & 0 deletions arch/x86/platform/mrst/mrst.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;

Expand Down

0 comments on commit 064a59b

Please sign in to comment.