diff options
| author | Jason Wessel <jason.wessel@windriver.com> | 2009-12-11 09:43:16 -0500 |
|---|---|---|
| committer | Jason Wessel <jason.wessel@windriver.com> | 2009-12-11 09:43:16 -0500 |
| commit | cf6f196d112a6f6757b1ca3cce0b576f7abee479 (patch) | |
| tree | 977a9e18167112af168ce49f95b5d26fe1bec46d | |
| parent | 59d309f9c8ef0bd01bf93cc0e758f1d810417bdb (diff) | |
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>
| -rw-r--r-- | arch/x86/kernel/kgdb.c | 10 |
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) | |||
| 86 | gdb_regs[GDB_DS] = regs->ds; | 86 | gdb_regs[GDB_DS] = regs->ds; |
| 87 | gdb_regs[GDB_ES] = regs->es; | 87 | gdb_regs[GDB_ES] = regs->es; |
| 88 | gdb_regs[GDB_CS] = regs->cs; | 88 | gdb_regs[GDB_CS] = regs->cs; |
| 89 | gdb_regs[GDB_SS] = __KERNEL_DS; | ||
| 90 | gdb_regs[GDB_FS] = 0xFFFF; | 89 | gdb_regs[GDB_FS] = 0xFFFF; |
| 91 | gdb_regs[GDB_GS] = 0xFFFF; | 90 | gdb_regs[GDB_GS] = 0xFFFF; |
| 91 | if (user_mode_vm(regs)) { | ||
| 92 | gdb_regs[GDB_SS] = regs->ss; | ||
| 93 | gdb_regs[GDB_SP] = regs->sp; | ||
| 94 | } else { | ||
| 95 | gdb_regs[GDB_SS] = __KERNEL_DS; | ||
| 96 | gdb_regs[GDB_SP] = kernel_stack_pointer(regs); | ||
| 97 | } | ||
| 92 | #else | 98 | #else |
| 93 | gdb_regs[GDB_R8] = regs->r8; | 99 | gdb_regs[GDB_R8] = regs->r8; |
| 94 | gdb_regs[GDB_R9] = regs->r9; | 100 | gdb_regs[GDB_R9] = regs->r9; |
| @@ -101,8 +107,8 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) | |||
| 101 | gdb_regs32[GDB_PS] = regs->flags; | 107 | gdb_regs32[GDB_PS] = regs->flags; |
| 102 | gdb_regs32[GDB_CS] = regs->cs; | 108 | gdb_regs32[GDB_CS] = regs->cs; |
| 103 | gdb_regs32[GDB_SS] = regs->ss; | 109 | gdb_regs32[GDB_SS] = regs->ss; |
| 104 | #endif | ||
| 105 | gdb_regs[GDB_SP] = kernel_stack_pointer(regs); | 110 | gdb_regs[GDB_SP] = kernel_stack_pointer(regs); |
| 111 | #endif | ||
| 106 | } | 112 | } |
| 107 | 113 | ||
| 108 | /** | 114 | /** |
