summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/kgdb.c
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2009-12-11 15:43:16 +0100
committerJason Wessel <jason.wessel@windriver.com>2009-12-11 15:43:16 +0100
commitcf6f196d112a6f6757b1ca3cce0b576f7abee479 (patch)
tree977a9e18167112af168ce49f95b5d26fe1bec46d /arch/x86/kernel/kgdb.c
parentkgdb: Replace strstr() by strchr() for single-character needles (diff)
downloadlinux-cf6f196d112a6f6757b1ca3cce0b576f7abee479.tar.xz
linux-cf6f196d112a6f6757b1ca3cce0b576f7abee479.zip
kgdb,i386: Fix corner case access to ss with NMI watch dog exception
It is possible for the user_mode_vm(regs) check to return true on the i368 arch for a non master kgdb cpu or when the master kgdb cpu handles the NMI watch dog exception. The solution is simply to select the correct gdb_ss location based on the check to user_mode_vm(regs). CC: Ingo Molnar <mingo@elte.hu> Acked-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'arch/x86/kernel/kgdb.c')
-rw-r--r--arch/x86/kernel/kgdb.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index f93d015753ce..aefae46aa646 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -86,9 +86,15 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs[GDB_DS] = regs->ds;
gdb_regs[GDB_ES] = regs->es;
gdb_regs[GDB_CS] = regs->cs;
- gdb_regs[GDB_SS] = __KERNEL_DS;
gdb_regs[GDB_FS] = 0xFFFF;
gdb_regs[GDB_GS] = 0xFFFF;
+ if (user_mode_vm(regs)) {
+ gdb_regs[GDB_SS] = regs->ss;
+ gdb_regs[GDB_SP] = regs->sp;
+ } else {
+ gdb_regs[GDB_SS] = __KERNEL_DS;
+ gdb_regs[GDB_SP] = kernel_stack_pointer(regs);
+ }
#else
gdb_regs[GDB_R8] = regs->r8;
gdb_regs[GDB_R9] = regs->r9;
@@ -101,8 +107,8 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
gdb_regs32[GDB_PS] = regs->flags;
gdb_regs32[GDB_CS] = regs->cs;
gdb_regs32[GDB_SS] = regs->ss;
-#endif
gdb_regs[GDB_SP] = kernel_stack_pointer(regs);
+#endif
}
/**