diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2008-09-26 11:36:41 -0400 |
---|---|---|
committer | Jason Wessel <jason.wessel@windriver.com> | 2008-09-26 11:36:41 -0400 |
commit | d7161a65341556bacb5e6654e133803f46f51063 (patch) | |
tree | b2933dc2ce1435956c193c37fd53a3d5530fe9d7 /arch/x86/kernel/kgdb.c | |
parent | 18d6522b86d21a04c8ac1ea79747e2e434a956d9 (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.c | 18 |
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, | |||
378 | if (remcomInBuffer[0] == 's') { | 378 | if (remcomInBuffer[0] == 's') { |
379 | linux_regs->flags |= X86_EFLAGS_TF; | 379 | linux_regs->flags |= X86_EFLAGS_TF; |
380 | kgdb_single_step = 1; | 380 | kgdb_single_step = 1; |
381 | if (kgdb_contthread) { | 381 | atomic_set(&kgdb_cpu_doing_single_step, |
382 | atomic_set(&kgdb_cpu_doing_single_step, | 382 | raw_smp_processor_id()); |
383 | raw_smp_processor_id()); | ||
384 | } | ||
385 | } | 383 | } |
386 | 384 | ||
387 | get_debugreg(dr6, 6); | 385 | get_debugreg(dr6, 6); |
@@ -466,9 +464,15 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd) | |||
466 | 464 | ||
467 | case DIE_DEBUG: | 465 | case DIE_DEBUG: |
468 | if (atomic_read(&kgdb_cpu_doing_single_step) == | 466 | if (atomic_read(&kgdb_cpu_doing_single_step) == |
469 | raw_smp_processor_id() && | 467 | raw_smp_processor_id()) { |
470 | user_mode(regs)) | 468 | if (user_mode(regs)) |
471 | return single_step_cont(regs, args); | 469 | return single_step_cont(regs, args); |
470 | break; | ||
471 | } else if (test_thread_flag(TIF_SINGLESTEP)) | ||
472 | /* This means a user thread is single stepping | ||
473 | * a system call which should be ignored | ||
474 | */ | ||
475 | return NOTIFY_DONE; | ||
472 | /* fall through */ | 476 | /* fall through */ |
473 | default: | 477 | default: |
474 | if (user_mode(regs)) | 478 | if (user_mode(regs)) |