--- arch/x86/kernel/traps.c | 49 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index f58679e487f6..bb511836b929 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -809,8 +809,17 @@ static void handle_debug(struct pt_regs *regs, unsigned long dr6, bool user) * If DR6 is zero, no point in trying to handle it. The kernel is * not using INT1. */ - if (!user && !dr6) - return; + if (!user) { + /* + * Catch SYSENTER with TF set and clear DR_STEP. If this hit a + * watchpoint at the same time then that will still be handled. + */ + if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs)) + dr6 &= ~DR_STEP; + + if (!dr6) + return; + } /* * If dr6 has no reason to give us about the origin of this trap, @@ -862,6 +871,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long dr6, bool user) cond_local_irq_disable(regs); } +#ifdef CONFIG_X86_64 static __always_inline void exc_debug_kernel(struct pt_regs *regs, unsigned long dr6) { @@ -869,13 +879,6 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, instrumentation_begin(); trace_hardirqs_off_finish(); - /* - * Catch SYSENTER with TF set and clear DR_STEP. If this hit a - * watchpoint at the same time then that will still be handled. - */ - if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs)) - dr6 &= ~DR_STEP; - handle_debug(regs, dr6, false); if (regs->flags & X86_EFLAGS_IF) @@ -884,6 +887,16 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs, nmi_exit(); } +/* IST stack entry */ +DEFINE_IDTENTRY_DEBUG(exc_debug) +{ + unsigned long dr6, dr7; + + debug_enter(&dr6, &dr7); + exc_debug_kernel(regs, dr6); + debug_exit(dr7); +} + static __always_inline void exc_debug_user(struct pt_regs *regs, unsigned long dr6) { @@ -895,17 +908,6 @@ static __always_inline void exc_debug_user(struct pt_regs *regs, idtentry_exit_user(regs); } -#ifdef CONFIG_X86_64 -/* IST stack entry */ -DEFINE_IDTENTRY_DEBUG(exc_debug) -{ - unsigned long dr6, dr7; - - debug_enter(&dr6, &dr7); - exc_debug_kernel(regs, dr6); - debug_exit(dr7); -} - /* User entry, runs on regular task stack */ DEFINE_IDTENTRY_DEBUG_USER(exc_debug) { @@ -922,12 +924,7 @@ DEFINE_IDTENTRY_DEBUG(exc_debug) unsigned long dr6, dr7; debug_enter(&dr6, &dr7); - - if (user_mode(regs)) - exc_debug_user(regs, dr6); - else - exc_debug_kernel(regs, dr6); - + handle_debug(regs, dr6, user_mode(regs)); debug_exit(dr7); } #endif -- 2.27.0