summaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
authorDon Zickus2006-09-26 10:52:26 +0200
committerAndi Kleen2006-09-26 10:52:26 +0200
commit3adbbcce9a49b900d4cc118cdccfdefa78bf1afb (patch)
tree3163758ed23d973a54b396593957c63470f39a0d /arch/i386/kernel/traps.c
parent[PATCH] i386: Add SMP support on i386 to reservation framework (diff)
downloadkernel-qcow2-linux-3adbbcce9a49b900d4cc118cdccfdefa78bf1afb.tar.gz
kernel-qcow2-linux-3adbbcce9a49b900d4cc118cdccfdefa78bf1afb.tar.xz
kernel-qcow2-linux-3adbbcce9a49b900d4cc118cdccfdefa78bf1afb.zip
[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)
do_exit(SIGSEGV);
}
+static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
+{
+ return 0;
+}
+
+static nmi_callback_t nmi_callback = dummy_nmi_callback;
+
static void default_do_nmi(struct pt_regs * regs)
{
unsigned char reason = 0;
@@ -723,12 +730,11 @@ static void default_do_nmi(struct pt_regs * regs)
* Ok, so this is none of the documented NMI sources,
* so it must be the NMI watchdog.
*/
- if (nmi_watchdog) {
- nmi_watchdog_tick(regs, reason);
+ if (nmi_watchdog_tick(regs, reason))
return;
- }
#endif
- unknown_nmi_error(reason, regs);
+ if (!rcu_dereference(nmi_callback)(regs, smp_processor_id()))
+ unknown_nmi_error(reason, regs);
return;
}
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)
reassert_nmi();
}
-static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
-{
- return 0;
-}
-
-static nmi_callback_t nmi_callback = dummy_nmi_callback;
-
fastcall void do_nmi(struct pt_regs * regs, long error_code)
{
int cpu;
@@ -761,8 +760,7 @@ fastcall void do_nmi(struct pt_regs * regs, long error_code)
++nmi_count(cpu);
- if (!rcu_dereference(nmi_callback)(regs, cpu))
- default_do_nmi(regs);
+ default_do_nmi(regs);
nmi_exit();
}