aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/traps_64.c
diff options
context:
space:
mode:
authorAlexander van Heukelum <heukelum@fastmail.fm>2008-09-30 12:41:37 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-13 04:33:21 -0400
commit3d2a71a596bd9c761c8487a2178e95f8a61da083 (patch)
treeeb02df788007f136e20ec557009242992396c845 /arch/x86/kernel/traps_64.c
parente407d62088b7f61f38e1086062650c75a4f2757a (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.c17
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 */
425clear_dr7: 426clear_dr7:
426 set_debugreg(0, 7); 427 set_debugreg(0, 7);
427 preempt_conditional_cli(regs); 428 preempt_conditional_cli(regs);