The following commit has been merged into the x86/entry branch of tip:

Commit-ID:     f4f6b66fd8011eb5f24dec936faaa4cab2ca7ebc
Gitweb:        
https://git.kernel.org/tip/f4f6b66fd8011eb5f24dec936faaa4cab2ca7ebc
Author:        Peter Zijlstra <pet...@infradead.org>
AuthorDate:    Thu, 05 Mar 2020 16:09:52 +01:00
Committer:     Thomas Gleixner <t...@linutronix.de>
CommitterDate: Tue, 19 May 2020 16:04:07 +02:00

x86/traps: Split int3 handler up

For code simplicity split up the int3 handler into a kernel and user part
which makes the code flow simpler to understand.

Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Reviewed-by: Alexandre Chartre <alexandre.char...@oracle.com>
Link: https://lkml.kernel.org/r/20200505135314.045220...@linutronix.de


---
 arch/x86/kernel/traps.c | 68 +++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 0ad12df..21c8cfc 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -568,6 +568,35 @@ exit:
        cond_local_irq_disable(regs);
 }
 
+static bool do_int3(struct pt_regs *regs)
+{
+       int res;
+
+#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
+       if (kgdb_ll_trap(DIE_INT3, "int3", regs, 0, X86_TRAP_BP,
+                        SIGTRAP) == NOTIFY_STOP)
+               return true;
+#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
+
+#ifdef CONFIG_KPROBES
+       if (kprobe_int3_handler(regs))
+               return true;
+#endif
+       res = notify_die(DIE_INT3, "int3", regs, 0, X86_TRAP_BP, SIGTRAP);
+
+       return res == NOTIFY_STOP;
+}
+
+static void do_int3_user(struct pt_regs *regs)
+{
+       if (do_int3(regs))
+               return;
+
+       cond_local_irq_enable(regs);
+       do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, 0, 0, NULL);
+       cond_local_irq_disable(regs);
+}
+
 DEFINE_IDTENTRY_RAW(exc_int3)
 {
        /*
@@ -585,37 +614,20 @@ DEFINE_IDTENTRY_RAW(exc_int3)
         * because the INT3 could have been hit in any context including
         * NMI.
         */
-       if (user_mode(regs))
+       if (user_mode(regs)) {
                idtentry_enter(regs);
-       else
-               nmi_enter();
-
-       instrumentation_begin();
-#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
-       if (kgdb_ll_trap(DIE_INT3, "int3", regs, 0, X86_TRAP_BP,
-                               SIGTRAP) == NOTIFY_STOP)
-               goto exit;
-#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
-
-#ifdef CONFIG_KPROBES
-       if (kprobe_int3_handler(regs))
-               goto exit;
-#endif
-
-       if (notify_die(DIE_INT3, "int3", regs, 0, X86_TRAP_BP,
-                       SIGTRAP) == NOTIFY_STOP)
-               goto exit;
-
-       cond_local_irq_enable(regs);
-       do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, 0, 0, NULL);
-       cond_local_irq_disable(regs);
-
-exit:
-       instrumentation_end();
-       if (user_mode(regs))
+               instrumentation_begin();
+               do_int3_user(regs);
+               instrumentation_end();
                idtentry_exit(regs);
-       else
+       } else {
+               nmi_enter();
+               instrumentation_begin();
+               if (!do_int3(regs))
+                       die("int3", regs, 0);
+               instrumentation_end();
                nmi_exit();
+       }
 }
 
 #ifdef CONFIG_X86_64

Reply via email to