summaryrefslogtreecommitdiff
path: root/arch/x86/kernel/cpu
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2020-02-26 01:33:29 +0300
committerThomas Gleixner <tglx@linutronix.de>2020-06-11 16:15:00 +0300
commit4c0dcd8350a03cb65f645a039f2772be880ee74a (patch)
treec4d232c3383abba5950c28850b905980ab6bdc28 /arch/x86/kernel/cpu
parentf08e32ec3cfcf9e6d3640007de590c225ab2e201 (diff)
downloadlinux-4c0dcd8350a03cb65f645a039f2772be880ee74a.tar.xz
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 nmi_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> 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/20200505135315.177564104@linutronix.de
Diffstat (limited to 'arch/x86/kernel/cpu')
-rw-r--r--arch/x86/kernel/cpu/mce/core.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 317765245190..a72c0135a5ec 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -1904,24 +1904,50 @@ static void unexpected_machine_check(struct pt_regs *regs)
/* Call the installed machine check handler for this CPU setup. */
void (*machine_check_vector)(struct pt_regs *) = unexpected_machine_check;
-DEFINE_IDTENTRY_MCE(exc_machine_check)
+static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
{
+ /*
+ * Only required when from kernel mode. See
+ * mce_check_crashing_cpu() for details.
+ */
if (machine_check_vector == do_machine_check &&
mce_check_crashing_cpu())
return;
- if (user_mode(regs))
- idtentry_enter(regs);
- else
- nmi_enter();
+ nmi_enter();
+ machine_check_vector(regs);
+ nmi_exit();
+}
+static __always_inline void exc_machine_check_user(struct pt_regs *regs)
+{
+ idtentry_enter(regs);
machine_check_vector(regs);
+ idtentry_exit(regs);
+}
+#ifdef CONFIG_X86_64
+/* MCE hit kernel mode */
+DEFINE_IDTENTRY_MCE(exc_machine_check)
+{
+ exc_machine_check_kernel(regs);
+}
+
+/* The user mode variant. */
+DEFINE_IDTENTRY_MCE_USER(exc_machine_check)
+{
+ exc_machine_check_user(regs);
+}
+#else
+/* 32bit unified entry point */
+DEFINE_IDTENTRY_MCE(exc_machine_check)
+{
if (user_mode(regs))
- idtentry_exit(regs);
+ exc_machine_check_user(regs);
else
- nmi_exit();
+ exc_machine_check_kernel(regs);
}
+#endif
/*
* Called for each booted CPU to set up machine checks.