Messages in this thread Patch in this message | | | Date | Tue, 25 Feb 2020 23:33:29 +0100 | From | Thomas Gleixner <> | Subject | [patch 08/16] x86/entry: Implement user mode C entry points for #DB and #MCE |
| |
The MCE entry point uses the same mechanism as the IST entry point for now. For #DB split the inner workings and just keep the ist_enter/exit magic in the IST variant. Fixup the ASM code to emit the proper noist_##cfunc call.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- arch/x86/entry/entry_64.S | 2 +- arch/x86/kernel/cpu/mce/core.c | 11 +++++++++++ arch/x86/kernel/traps.c | 30 ++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 9 deletions(-)
--- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -646,7 +646,7 @@ SYM_CODE_START(\asmsym) /* Switch to the regular task stack and use the noist entry point */ .Lfrom_usermode_switch_stack_\@: - idtentry_body vector \cfunc, has_error_code=0 + idtentry_body vector noist_\cfunc, has_error_code=0 _ASM_NOKPROBE(\asmsym) SYM_CODE_END(\asmsym) --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -1898,11 +1898,22 @@ static void unexpected_machine_check(str /* Call the installed machine check handler for this CPU setup. */ void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check; +/* MCE hit kernel mode */ DEFINE_IDTENTRY_MCE(exc_machine_check) { machine_check_vector(regs); } +#ifdef CONFIG_X86_64 +/* + * The user mode variant (same content for now). + */ +DEFINE_IDTENTRY_MCE_USER(exc_machine_check) +{ + machine_check_vector(regs); +} +#endif + /* * Called for each booted CPU to set up machine checks. * Must be called with preempt off: --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -739,15 +739,13 @@ static bool is_sysenter_singlestep(struc * * May run on IST stack. */ -DEFINE_IDTENTRY_DEBUG(exc_debug) +static void notrace handle_debug(struct pt_regs *regs) { struct task_struct *tsk = current; int user_icebp = 0; unsigned long dr6; int si_code; - ist_enter(regs); - get_debugreg(dr6, 6); /* * The Intel SDM says: @@ -776,7 +774,7 @@ DEFINE_IDTENTRY_DEBUG(exc_debug) is_sysenter_singlestep(regs))) { dr6 &= ~DR_STEP; if (!dr6) - goto exit; + return; /* * else we might have gotten a single-step trap and hit a * watchpoint at the same time, in which case we should fall @@ -797,12 +795,12 @@ DEFINE_IDTENTRY_DEBUG(exc_debug) #ifdef CONFIG_KPROBES if (kprobe_debug_handler(regs)) - goto exit; + return; #endif if (notify_die(DIE_DEBUG, "debug", regs, (long)&dr6, 0, SIGTRAP) == NOTIFY_STOP) - goto exit; + return; /* * Let others (NMI) know that the debug stack is in use @@ -818,7 +816,7 @@ DEFINE_IDTENTRY_DEBUG(exc_debug) X86_TRAP_DB); cond_local_irq_disable(regs); debug_stack_usage_dec(); - goto exit; + return; } if (WARN_ON_ONCE((dr6 & DR_STEP) && !user_mode(regs))) { @@ -837,11 +835,27 @@ DEFINE_IDTENTRY_DEBUG(exc_debug) send_sigtrap(regs, 0, si_code); cond_local_irq_disable(regs); debug_stack_usage_dec(); +} +NOKPROBE_SYMBOL(handle_debug); -exit: +/* + * IST stack entry. + */ +DEFINE_IDTENTRY_DEBUG(exc_debug) +{ + ist_enter(regs); + handle_debug(regs); ist_exit(regs); } +#ifdef CONFIG_X86_64 +/* User entry, runs on regular task stack */ +DEFINE_IDTENTRY_DEBUG_USER(exc_debug) +{ + handle_debug(regs); +} +#endif + /* * Note that we play around with the 'TS' bit in an attempt to get * the correct behaviour even in the presence of the asynchronous
| |