kgdb,i386: Fix corner case access to ss with NMI watch dog exception
authorJason Wessel <jason.wessel@windriver.com>
Fri, 11 Dec 2009 14:43:16 +0000 (08:43 -0600)
committerJason Wessel <jason.wessel@windriver.com>
Fri, 11 Dec 2009 14:43:16 +0000 (08:43 -0600)
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>
arch/x86/kernel/kgdb.c

index f93d015753ce8a08ebab6982d17746ad060cd701..aefae46aa6464ddc6e89c3f691aa8359771bb49f 100644 (file)
@@ -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
 }
 
 /**