summaryrefslogtreecommitdiff
path: root/arch/i386/kernel/traps.c
diff options
context:
space:
mode:
authorFernando Luis Vzquez Cao <fernando@oss.ntt.co.jp>2006-09-26 10:52:36 +0200
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 10:52:36 +0200
commit06039754d775d3e48e4a292e4f353321205eff53 (patch)
treea6abdd9ca0efb34006792e7275c4a2c954b229be /arch/i386/kernel/traps.c
parent6f6b1e0477ccb2f25a9b045e38440347d2ce21c8 (diff)
downloadlwn-06039754d775d3e48e4a292e4f353321205eff53.tar.gz
lwn-06039754d775d3e48e4a292e4f353321205eff53.zip
[PATCH] i386: Disallow kprobes on NMI handlers
A kprobe executes IRET early and that could cause NMI recursion and stack corruption. Note: This problem was originally spotted and solved by Andi Kleen in the x86_64 architecture. This patch is an adaption of his patch for i386. AK: Merged with current code which was a bit different. AK: Removed printk in nmi handler that shouldn't be there in the first time AK: Added missing include. AK: added KPROBES_END Signed-off-by: Fernando Vazquez <fernando@intellilink.co.jp> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r--arch/i386/kernel/traps.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 00d643f3de41..5c0f4960c67d 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -689,7 +689,8 @@ gp_in_kernel:
}
}
-static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+mem_parity_error(unsigned char reason, struct pt_regs * regs)
{
printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on "
"CPU %d.\n", reason, smp_processor_id());
@@ -704,7 +705,8 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
clear_mem_error(reason);
}
-static void io_check_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+io_check_error(unsigned char reason, struct pt_regs * regs)
{
unsigned long i;
@@ -720,7 +722,8 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs)
outb(reason, 0x61);
}
-static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
+static __kprobes void
+unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
{
#ifdef CONFIG_MCA
/* Might actually be able to figure out what the guilty party
@@ -741,7 +744,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
static DEFINE_SPINLOCK(nmi_print_lock);
-void die_nmi (struct pt_regs *regs, const char *msg)
+void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
{
if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) ==
NOTIFY_STOP)
@@ -773,7 +776,7 @@ void die_nmi (struct pt_regs *regs, const char *msg)
do_exit(SIGSEGV);
}
-static void default_do_nmi(struct pt_regs * regs)
+static __kprobes void default_do_nmi(struct pt_regs * regs)
{
unsigned char reason = 0;
@@ -811,7 +814,7 @@ static void default_do_nmi(struct pt_regs * regs)
reassert_nmi();
}
-fastcall void do_nmi(struct pt_regs * regs, long error_code)
+fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code)
{
int cpu;