diff options
author | Alexander van Heukelum <heukelum@fastmail.fm> | 2008-09-30 12:41:37 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-13 04:33:21 -0400 |
commit | 3d2a71a596bd9c761c8487a2178e95f8a61da083 (patch) | |
tree | eb02df788007f136e20ec557009242992396c845 /arch/x86/kernel/traps_64.c | |
parent | e407d62088b7f61f38e1086062650c75a4f2757a (diff) |
x86, traps: converge do_debug handlers
Make the x86_64-version and the i386-version of do_debug
more similar.
- introduce preempt_conditional_sti/cli to i386. The preempt-count
is now elevated during the trap handler, like on x86_64. It
does not run on a separate stack, however.
- replace an open-coded "send_sigtrap"
- copy some comments
Signed-off-by: Alexander van Heukelum <heukelum@fastmail.fm>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/traps_64.c')
-rw-r--r-- | arch/x86/kernel/traps_64.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index be73323ca952..a851eca6d04c 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -380,7 +380,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
380 | { | 380 | { |
381 | struct task_struct *tsk = current; | 381 | struct task_struct *tsk = current; |
382 | unsigned long condition; | 382 | unsigned long condition; |
383 | siginfo_t info; | 383 | int si_code; |
384 | 384 | ||
385 | get_debugreg(condition, 6); | 385 | get_debugreg(condition, 6); |
386 | 386 | ||
@@ -394,6 +394,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
394 | SIGTRAP) == NOTIFY_STOP) | 394 | SIGTRAP) == NOTIFY_STOP) |
395 | return; | 395 | return; |
396 | 396 | ||
397 | /* It's safe to allow irq's after DR6 has been saved */ | ||
397 | preempt_conditional_sti(regs); | 398 | preempt_conditional_sti(regs); |
398 | 399 | ||
399 | /* Mask out spurious debug traps due to lazy DR7 setting */ | 400 | /* Mask out spurious debug traps due to lazy DR7 setting */ |
@@ -402,6 +403,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
402 | goto clear_dr7; | 403 | goto clear_dr7; |
403 | } | 404 | } |
404 | 405 | ||
406 | /* Save debug status register where ptrace can see it */ | ||
405 | tsk->thread.debugreg6 = condition; | 407 | tsk->thread.debugreg6 = condition; |
406 | 408 | ||
407 | /* | 409 | /* |
@@ -413,15 +415,14 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
413 | goto clear_TF_reenable; | 415 | goto clear_TF_reenable; |
414 | } | 416 | } |
415 | 417 | ||
418 | si_code = get_si_code(condition); | ||
416 | /* Ok, finally something we can handle */ | 419 | /* Ok, finally something we can handle */ |
417 | tsk->thread.trap_no = 1; | 420 | send_sigtrap(tsk, regs, error_code, si_code); |
418 | tsk->thread.error_code = error_code; | ||
419 | info.si_signo = SIGTRAP; | ||
420 | info.si_errno = 0; | ||
421 | info.si_code = get_si_code(condition); | ||
422 | info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL; | ||
423 | force_sig_info(SIGTRAP, &info, tsk); | ||
424 | 421 | ||
422 | /* | ||
423 | * Disable additional traps. They'll be re-enabled when | ||
424 | * the signal is delivered. | ||
425 | */ | ||
425 | clear_dr7: | 426 | clear_dr7: |
426 | set_debugreg(0, 7); | 427 | set_debugreg(0, 7); |
427 | preempt_conditional_cli(regs); | 428 | preempt_conditional_cli(regs); |