aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2011-01-06 16:18:47 -0500
committerIngo Molnar <mingo@elte.hu>2011-01-07 09:08:51 -0500
commit1c7b74d46fed530cca22a9a54140cdac2815c797 (patch)
tree647c236abdeb4bd57d170ed8a54e64d58f18a5ec
parent4158755d3136f4cb05c1a8a260e9c06f93baeb48 (diff)
x86, NMI: Add NMI symbol constants and rename memory parity to PCI SERR
Replace the NMI related magic numbers with symbol constants. Memory parity error is only valid for IBM PC-AT, newer machine use bit 7 (0x80) of 0x61 port for PCI SERR. While memory error is usually reported via MCE. So corresponding function name and kernel log string is changed. But on some machines, PCI SERR line is still used to report memory errors. This is used by EDAC, so corresponding EDAC call is reserved. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <1294348732-15030-2-git-send-email-dzickus@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-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 f7920601e472..72a8b52e7dfd 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 c76aaca5694d..c7fd1cea0374 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 /*