lkml.org 
[lkml]   [2020]   [Feb]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
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
\
 
 \ /
  Last update: 2020-02-26 00:27    [W:0.168 / U:0.364 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site