aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/mach_traps.h12
-rw-r--r--arch/x86/kernel/traps.c51
2 files changed, 37 insertions, 26 deletions
diff --git a/arch/x86/include/asm/mach_traps.h b/arch/x86/include/asm/mach_traps.h
index f7920601e47..72a8b52e7df 100644
--- a/arch/x86/include/asm/mach_traps.h
+++ b/arch/x86/include/asm/mach_traps.h
@@ -7,9 +7,19 @@
7 7
8#include <asm/mc146818rtc.h> 8#include <asm/mc146818rtc.h>
9 9
10#define NMI_REASON_PORT 0x61
11
12#define NMI_REASON_SERR 0x80
13#define NMI_REASON_IOCHK 0x40
14#define NMI_REASON_MASK (NMI_REASON_SERR | NMI_REASON_IOCHK)
15
16#define NMI_REASON_CLEAR_SERR 0x04
17#define NMI_REASON_CLEAR_IOCHK 0x08
18#define NMI_REASON_CLEAR_MASK 0x0f
19
10static inline unsigned char get_nmi_reason(void) 20static inline unsigned char get_nmi_reason(void)
11{ 21{
12 return inb(0x61); 22 return inb(NMI_REASON_PORT);
13} 23}
14 24
15static inline void reassert_nmi(void) 25static inline void reassert_nmi(void)
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index c76aaca5694..c7fd1cea037 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -310,15 +310,15 @@ static int __init setup_unknown_nmi_panic(char *str)
310__setup("unknown_nmi_panic", setup_unknown_nmi_panic); 310__setup("unknown_nmi_panic", setup_unknown_nmi_panic);
311 311
312static notrace __kprobes void 312static notrace __kprobes void
313mem_parity_error(unsigned char reason, struct pt_regs *regs) 313pci_serr_error(unsigned char reason, struct pt_regs *regs)
314{ 314{
315 printk(KERN_EMERG 315 pr_emerg("NMI: PCI system error (SERR) for reason %02x on CPU %d.\n",
316 "Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", 316 reason, smp_processor_id());
317 reason, smp_processor_id());
318
319 printk(KERN_EMERG
320 "You have some hardware problem, likely on the PCI bus.\n");
321 317
318 /*
319 * On some machines, PCI SERR line is used to report memory
320 * errors. EDAC makes use of it.
321 */
322#if defined(CONFIG_EDAC) 322#if defined(CONFIG_EDAC)
323 if (edac_handler_set()) { 323 if (edac_handler_set()) {
324 edac_atomic_assert_error(); 324 edac_atomic_assert_error();
@@ -329,11 +329,11 @@ mem_parity_error(unsigned char reason, struct pt_regs *regs)
329 if (panic_on_unrecovered_nmi) 329 if (panic_on_unrecovered_nmi)
330 panic("NMI: Not continuing"); 330 panic("NMI: Not continuing");
331 331
332 printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); 332 pr_emerg("Dazed and confused, but trying to continue\n");
333 333
334 /* Clear and disable the memory parity error line. */ 334 /* Clear and disable the PCI SERR error line. */
335 reason = (reason & 0xf) | 4; 335 reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_SERR;
336 outb(reason, 0x61); 336 outb(reason, NMI_REASON_PORT);
337} 337}
338 338
339static notrace __kprobes void 339static notrace __kprobes void
@@ -341,15 +341,17 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
341{ 341{
342 unsigned long i; 342 unsigned long i;
343 343
344 printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); 344 pr_emerg(
345 "NMI: IOCK error (debug interrupt?) for reason %02x on CPU %d.\n",
346 reason, smp_processor_id());
345 show_registers(regs); 347 show_registers(regs);
346 348
347 if (panic_on_io_nmi) 349 if (panic_on_io_nmi)
348 panic("NMI IOCK error: Not continuing"); 350 panic("NMI IOCK error: Not continuing");
349 351
350 /* Re-enable the IOCK line, wait for a few seconds */ 352 /* Re-enable the IOCK line, wait for a few seconds */
351 reason = (reason & 0xf) | 8; 353 reason = (reason & NMI_REASON_CLEAR_MASK) | NMI_REASON_CLEAR_IOCHK;
352 outb(reason, 0x61); 354 outb(reason, NMI_REASON_PORT);
353 355
354 i = 20000; 356 i = 20000;
355 while (--i) { 357 while (--i) {
@@ -357,8 +359,8 @@ io_check_error(unsigned char reason, struct pt_regs *regs)
357 udelay(100); 359 udelay(100);
358 } 360 }
359 361
360 reason &= ~8; 362 reason &= ~NMI_REASON_CLEAR_IOCHK;
361 outb(reason, 0x61); 363 outb(reason, NMI_REASON_PORT);
362} 364}
363 365
364static notrace __kprobes void 366static notrace __kprobes void
@@ -377,15 +379,14 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs)
377 return; 379 return;
378 } 380 }
379#endif 381#endif
380 printk(KERN_EMERG 382 pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n",
381 "Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", 383 reason, smp_processor_id());
382 reason, smp_processor_id());
383 384
384 printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); 385 pr_emerg("Do you have a strange power saving mode enabled?\n");
385 if (unknown_nmi_panic || panic_on_unrecovered_nmi) 386 if (unknown_nmi_panic || panic_on_unrecovered_nmi)
386 panic("NMI: Not continuing"); 387 panic("NMI: Not continuing");
387 388
388 printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); 389 pr_emerg("Dazed and confused, but trying to continue\n");
389} 390}
390 391
391static notrace __kprobes void default_do_nmi(struct pt_regs *regs) 392static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
@@ -399,7 +400,7 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
399 if (!cpu) 400 if (!cpu)
400 reason = get_nmi_reason(); 401 reason = get_nmi_reason();
401 402
402 if (!(reason & 0xc0)) { 403 if (!(reason & NMI_REASON_MASK)) {
403 if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) 404 if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT)
404 == NOTIFY_STOP) 405 == NOTIFY_STOP)
405 return; 406 return;
@@ -417,9 +418,9 @@ static notrace __kprobes void default_do_nmi(struct pt_regs *regs)
417 return; 418 return;
418 419
419 /* AK: following checks seem to be broken on modern chipsets. FIXME */ 420 /* AK: following checks seem to be broken on modern chipsets. FIXME */
420 if (reason & 0x80) 421 if (reason & NMI_REASON_SERR)
421 mem_parity_error(reason, regs); 422 pci_serr_error(reason, regs);
422 if (reason & 0x40) 423 if (reason & NMI_REASON_IOCHK)
423 io_check_error(reason, regs); 424 io_check_error(reason, regs);
424#ifdef CONFIG_X86_32 425#ifdef CONFIG_X86_32
425 /* 426 /*