mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-05-24 10:39:52 +00: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) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com> Link: https://lkml.kernel.org/r/20200505135314.045220765@linutronix.de
This commit is contained in:
parent
8edd7e37ae
commit
21e28290b3
1 changed files with 40 additions and 28 deletions
|
@ -568,6 +568,35 @@ exit:
|
||||||
cond_local_irq_disable(regs);
|
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)
|
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
|
* because the INT3 could have been hit in any context including
|
||||||
* NMI.
|
* NMI.
|
||||||
*/
|
*/
|
||||||
if (user_mode(regs))
|
if (user_mode(regs)) {
|
||||||
idtentry_enter(regs);
|
idtentry_enter(regs);
|
||||||
else
|
instrumentation_begin();
|
||||||
nmi_enter();
|
do_int3_user(regs);
|
||||||
|
instrumentation_end();
|
||||||
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))
|
|
||||||
idtentry_exit(regs);
|
idtentry_exit(regs);
|
||||||
else
|
} else {
|
||||||
|
nmi_enter();
|
||||||
|
instrumentation_begin();
|
||||||
|
if (!do_int3(regs))
|
||||||
|
die("int3", regs, 0);
|
||||||
|
instrumentation_end();
|
||||||
nmi_exit();
|
nmi_exit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_64
|
#ifdef CONFIG_X86_64
|
||||||
|
|
Loading…
Add table
Reference in a new issue