aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
authorDon Zickus <dzickus@redhat.com>2006-09-26 04:52:26 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:26 -0400
commit3adbbcce9a49b900d4cc118cdccfdefa78bf1afb (patch)
tree3163758ed23d973a54b396593957c63470f39a0d /arch/i386/kernel/traps.c
parentb7471c6da94d30d3deadc55986cc38d1ff57f9ca (diff)
[PATCH] x86: Cleanup NMI interrupt path
This patch cleans up the NMI interrupt path. Instead of being gated by if the 'nmi callback' is set, the interrupt handler now calls everyone who is registered on the die_chain and additionally checks the nmi watchdog, reseting it if enabled. This allows more subsystems to hook into the NMI if they need to (without being block by set_nmi_callback). Signed-off-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r--arch/i386/kernel/traps.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 3a07b2677e2a..282f0bd40dfd 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -706,6 +706,13 @@ void die_nmi (struct pt_regs *regs, const char *msg)
706 do_exit(SIGSEGV); 706 do_exit(SIGSEGV);
707} 707}
708 708
709static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
710{
711 return 0;
712}
713
714static nmi_callback_t nmi_callback = dummy_nmi_callback;
715
709static void default_do_nmi(struct pt_regs * regs) 716static void default_do_nmi(struct pt_regs * regs)
710{ 717{
711 unsigned char reason = 0; 718 unsigned char reason = 0;
@@ -723,12 +730,11 @@ static void default_do_nmi(struct pt_regs * regs)
723 * Ok, so this is none of the documented NMI sources, 730 * Ok, so this is none of the documented NMI sources,
724 * so it must be the NMI watchdog. 731 * so it must be the NMI watchdog.
725 */ 732 */
726 if (nmi_watchdog) { 733 if (nmi_watchdog_tick(regs, reason))
727 nmi_watchdog_tick(regs, reason);
728 return; 734 return;
729 }
730#endif 735#endif
731 unknown_nmi_error(reason, regs); 736 if (!rcu_dereference(nmi_callback)(regs, smp_processor_id()))
737 unknown_nmi_error(reason, regs);
732 return; 738 return;
733 } 739 }
734 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) 740 if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP)
@@ -744,13 +750,6 @@ static void default_do_nmi(struct pt_regs * regs)
744 reassert_nmi(); 750 reassert_nmi();
745} 751}
746 752
747static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
748{
749 return 0;
750}
751
752static nmi_callback_t nmi_callback = dummy_nmi_callback;
753
754fastcall void do_nmi(struct pt_regs * regs, long error_code) 753fastcall void do_nmi(struct pt_regs * regs, long error_code)
755{ 754{
756 int cpu; 755 int cpu;
@@ -761,8 +760,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
761 760
762 ++nmi_count(cpu); 761 ++nmi_count(cpu);
763 762
764 if (!rcu_dereference(nmi_callback)(regs, cpu)) 763 default_do_nmi(regs);
765 default_do_nmi(regs);
766 764
767 nmi_exit(); 765 nmi_exit();
768} 766}