diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2020-03-04 12:51:59 +0100 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-06-11 15:14:39 +0200 |
commit | 4983e5d74c821780d518232eea4acdc4a8f0b44d (patch) | |
tree | c0a8c6b928d0ebecb0727f9edb2dabedd88de3bc /arch/x86/entry/common.c | |
parent | dd8e2d9ae64fa4348530df3e45e9f874d807a1c2 (diff) | |
download | linux-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.c | 19 |
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) |