summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/kgdb.c
diff options
context:
space:
mode:
authorJason Wessel <jason.wessel@windriver.com>2008-09-26 10:36:41 -0500
committerJason Wessel <jason.wessel@windriver.com>2008-09-26 10:36:41 -0500
commitd7161a65341556bacb5e6654e133803f46f51063 (patch)
treeb2933dc2ce1435956c193c37fd53a3d5530fe9d7 /arch/x86/kernel/kgdb.c
parent18d6522b86d21a04c8ac1ea79747e2e434a956d9 (diff)
kgdb, x86, arm, mips, powerpc: ignore user space single stepping
On the x86 arch, user space single step exceptions should be ignored if they occur in the kernel space, such as ptrace stepping through a system call. First check if it is kgdb that is executing a single step, then ensure it is not an accidental traversal into the user space, while in kgdb, any other time the TIF_SINGLESTEP is set, kgdb should ignore the exception. On x86, arm, mips and powerpc, the kgdb_contthread usage was inconsistent with the way single stepping is implemented in the kgdb core. The arch specific stub should always set the kgdb_cpu_doing_single_step correctly if it is single stepping. This allows kgdb to correctly process an instruction steps if ptrace happens to be requesting an instruction step over a system call. Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'arch/x86/kernel/kgdb.c')
-rw-r--r--arch/x86/kernel/kgdb.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index f47f0eb886b8..00f7896c9a19 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -378,10 +378,8 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
if (remcomInBuffer[0] == 's') {
linux_regs->flags |= X86_EFLAGS_TF;
kgdb_single_step = 1;
- if (kgdb_contthread) {
- atomic_set(&kgdb_cpu_doing_single_step,
- raw_smp_processor_id());
- }
+ atomic_set(&kgdb_cpu_doing_single_step,
+ raw_smp_processor_id());
}
get_debugreg(dr6, 6);
@@ -466,9 +464,15 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
case DIE_DEBUG:
if (atomic_read(&kgdb_cpu_doing_single_step) ==
- raw_smp_processor_id() &&
- user_mode(regs))
- return single_step_cont(regs, args);
+ raw_smp_processor_id()) {
+ if (user_mode(regs))
+ return single_step_cont(regs, args);
+ break;
+ } else if (test_thread_flag(TIF_SINGLESTEP))
+ /* This means a user thread is single stepping
+ * a system call which should be ignored
+ */
+ return NOTIFY_DONE;
/* fall through */
default:
if (user_mode(regs))