x86/entry: Convert INT3 exception to IDTENTRY_RAW
Convert #BP to IDTENTRY_RAW: - Implement the C entry point with DEFINE_IDTENTRY_RAW - Invoke idtentry_enter/exit() from the function body - Emit the ASM stub with DECLARE_IDTENTRY_RAW - Remove the ASM idtentry in 64bit - Remove the open coded ASM entry code in 32bit - Fixup the XEN/PV code - Remove the old prototypes No functional change. This could be a plain IDTENTRY, but as Peter pointed out INT3 is broken vs. the static key in the context tracking code as this static key might be in the state of being patched and has an int3 which would recurse forever. IDTENTRY_RAW is therefore chosen to allow addressing this issue without lots of code churn. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Acked-by: Andy Lutomirski <luto@kernel.org> Link: https://lkml.kernel.org/r/20200505135313.938474960@linutronix.de
This commit is contained in:
@@ -60,7 +60,7 @@ static bool idt_setup_done __initdata;
|
||||
*/
|
||||
static const __initconst struct idt_data early_idts[] = {
|
||||
INTG(X86_TRAP_DB, debug),
|
||||
SYSG(X86_TRAP_BP, int3),
|
||||
SYSG(X86_TRAP_BP, asm_exc_int3),
|
||||
#ifdef CONFIG_X86_32
|
||||
INTG(X86_TRAP_PF, page_fault),
|
||||
#endif
|
||||
|
@@ -568,7 +568,7 @@ exit:
|
||||
cond_local_irq_disable(regs);
|
||||
}
|
||||
|
||||
dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
|
||||
DEFINE_IDTENTRY_RAW(exc_int3)
|
||||
{
|
||||
/*
|
||||
* poke_int3_handler() is completely self contained code; it does (and
|
||||
@@ -579,16 +579,20 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Unlike any other non-IST entry, we can be called from pretty much
|
||||
* any location in the kernel through kprobes -- text_poke() will most
|
||||
* likely be handled by poke_int3_handler() above. This means this
|
||||
* handler is effectively NMI-like.
|
||||
* idtentry_enter() uses static_branch_{,un}likely() and therefore
|
||||
* can trigger INT3, hence poke_int3_handler() must be done
|
||||
* before. If the entry came from kernel mode, then use nmi_enter()
|
||||
* 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, error_code, X86_TRAP_BP,
|
||||
if (kgdb_ll_trap(DIE_INT3, "int3", regs, 0, X86_TRAP_BP,
|
||||
SIGTRAP) == NOTIFY_STOP)
|
||||
goto exit;
|
||||
#endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
|
||||
@@ -598,19 +602,21 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
|
||||
goto exit;
|
||||
#endif
|
||||
|
||||
if (notify_die(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
|
||||
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, error_code, 0, NULL);
|
||||
do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, 0, 0, NULL);
|
||||
cond_local_irq_disable(regs);
|
||||
|
||||
exit:
|
||||
if (!user_mode(regs))
|
||||
instrumentation_end();
|
||||
if (user_mode(regs))
|
||||
idtentry_exit(regs);
|
||||
else
|
||||
nmi_exit();
|
||||
}
|
||||
NOKPROBE_SYMBOL(do_int3);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
|
Reference in New Issue
Block a user