diff options
-rw-r--r-- | arch/x86/include/asm/mach_traps.h | 12 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 51 |
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 | |||
10 | static inline unsigned char get_nmi_reason(void) | 20 | static inline unsigned char get_nmi_reason(void) |
11 | { | 21 | { |
12 | return inb(0x61); | 22 | return inb(NMI_REASON_PORT); |
13 | } | 23 | } |
14 | 24 | ||
15 | static inline void reassert_nmi(void) | 25 | static 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 | ||
312 | static notrace __kprobes void | 312 | static notrace __kprobes void |
313 | mem_parity_error(unsigned char reason, struct pt_regs *regs) | 313 | pci_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 | ||
339 | static notrace __kprobes void | 339 | static 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 | ||
364 | static notrace __kprobes void | 366 | static 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 | ||
391 | static notrace __kprobes void default_do_nmi(struct pt_regs *regs) | 392 | static 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 | /* |