aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/entry/common.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2020-03-04 12:51:59 +0100
committerThomas Gleixner <tglx@linutronix.de>2020-06-11 15:14:39 +0200
commit4983e5d74c821780d518232eea4acdc4a8f0b44d (patch)
treec0a8c6b928d0ebecb0727f9edb2dabedd88de3bc /arch/x86/entry/common.c
parentdd8e2d9ae64fa4348530df3e45e9f874d807a1c2 (diff)
downloadlinux-4983e5d74c821780d518232eea4acdc4a8f0b44d.tar.gz
x86/entry: Move irq flags tracing to prepare_exit_to_usermode()
This is another step towards more C-code and less convoluted ASM. Similar to the entry path, invoke the tracer before context tracking which might turn off RCU and invoke lockdep as the last step before going back to user space. Annotate the code sections in exit_to_user_mode() accordingly so objtool won't complain about the tracer invocation. 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/20200505134340.703783926@linutronix.de
Diffstat (limited to 'arch/x86/entry/common.c')
-rw-r--r--arch/x86/entry/common.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 7473c1297a84..e4f9f5f2c21b 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -72,10 +72,27 @@ static __always_inline void enter_from_user_mode(void)
}
#endif
-static noinstr void exit_to_user_mode(void)
+/**
+ * exit_to_user_mode - Fixup state when exiting to user mode
+ *
+ * Syscall exit enables interrupts, but the kernel state is interrupts
+ * disabled when this is invoked. Also tell RCU about it.
+ *
+ * 1) Trace interrupts on state
+ * 2) Invoke context tracking if enabled to adjust RCU state
+ * 3) Clear CPU buffers if CPU is affected by MDS and the migitation is on.
+ * 4) Tell lockdep that interrupts are enabled
+ */
+static __always_inline void exit_to_user_mode(void)
{
+ instrumentation_begin();
+ trace_hardirqs_on_prepare();
+ lockdep_hardirqs_on_prepare(CALLER_ADDR0);
+ instrumentation_end();
+
user_enter_irqoff();
mds_user_clear_cpu_buffers();
+ lockdep_hardirqs_on(CALLER_ADDR0);
}
static void do_audit_syscall_entry(struct pt_regs *regs, u32 arch)