x86/entry: Move irq tracing on syscall entry to C-code
authorThomas Gleixner <tglx@linutronix.de>
Tue, 25 Feb 2020 22:08:05 +0000 (23:08 +0100)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 11 Jun 2020 13:14:39 +0000 (15:14 +0200)
Now that the C entry points are safe, move the irq flags tracing code into
the entry helper:

    - Invoke lockdep before calling into context tracking

    - Use the safe trace_hardirqs_on_prepare() trace function after context
      tracking established state and RCU is watching.

enter_from_user_mode() is also still invoked from the exception/interrupt
entry code which still contains the ASM irq flags tracing. So this is just
a redundant and harmless invocation of tracing / lockdep until these are
removed as well.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200505134340.611961721@linutronix.de
arch/x86/entry/common.c
arch/x86/entry/entry_32.S
arch/x86/entry/entry_64.S
arch/x86/entry/entry_64_compat.S

index 9892fb7..7473c12 100644 (file)
 #include <trace/events/syscalls.h>
 
 #ifdef CONFIG_CONTEXT_TRACKING
-/* Called on entry from user mode with IRQs off. */
+/**
+ * enter_from_user_mode - Establish state when coming from user mode
+ *
+ * Syscall entry disables interrupts, but user mode is traced as interrupts
+ * enabled. Also with NO_HZ_FULL RCU might be idle.
+ *
+ * 1) Tell lockdep that interrupts are disabled
+ * 2) Invoke context tracking if enabled to reactivate RCU
+ * 3) Trace interrupts off state
+ */
 __visible noinstr void enter_from_user_mode(void)
 {
        enum ctx_state state = ct_state();
 
+       lockdep_hardirqs_off(CALLER_ADDR0);
        user_exit_irqoff();
 
        instrumentation_begin();
        CT_WARN_ON(state != CONTEXT_USER);
+       trace_hardirqs_off_prepare();
        instrumentation_end();
 }
 #else
-static inline void enter_from_user_mode(void) {}
+static __always_inline void enter_from_user_mode(void)
+{
+       lockdep_hardirqs_off(CALLER_ADDR0);
+       instrumentation_begin();
+       trace_hardirqs_off_prepare();
+       instrumentation_end();
+}
 #endif
 
 static noinstr void exit_to_user_mode(void)
index bf0082b..65704e0 100644 (file)
@@ -967,12 +967,6 @@ SYM_FUNC_START(entry_SYSENTER_32)
        jnz     .Lsysenter_fix_flags
 .Lsysenter_flags_fixed:
 
-       /*
-        * User mode is traced as though IRQs are on, and SYSENTER
-        * turned them off.
-        */
-       TRACE_IRQS_OFF
-
        movl    %esp, %eax
        call    do_fast_syscall_32
        /* XEN PV guests always use IRET path */
@@ -1082,12 +1076,6 @@ SYM_FUNC_START(entry_INT80_32)
 
        SAVE_ALL pt_regs_ax=$-ENOSYS switch_stacks=1    /* save rest */
 
-       /*
-        * User mode is traced as though IRQs are on, and the interrupt gate
-        * turned them off.
-        */
-       TRACE_IRQS_OFF
-
        movl    %esp, %eax
        call    do_int80_syscall_32
 .Lsyscall_32_done:
index b199f43..9e34fe8 100644 (file)
@@ -167,8 +167,6 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL)
 
        PUSH_AND_CLEAR_REGS rax=$-ENOSYS
 
-       TRACE_IRQS_OFF
-
        /* IRQs are off. */
        movq    %rax, %rdi
        movq    %rsp, %rsi
index f1d3cca..e2e8bd7 100644 (file)
@@ -129,12 +129,6 @@ SYM_FUNC_START(entry_SYSENTER_compat)
        jnz     .Lsysenter_fix_flags
 .Lsysenter_flags_fixed:
 
-       /*
-        * User mode is traced as though IRQs are on, and SYSENTER
-        * turned them off.
-        */
-       TRACE_IRQS_OFF
-
        movq    %rsp, %rdi
        call    do_fast_syscall_32
        /* XEN PV guests always use IRET path */
@@ -247,12 +241,6 @@ SYM_INNER_LABEL(entry_SYSCALL_compat_after_hwframe, SYM_L_GLOBAL)
        pushq   $0                      /* pt_regs->r15 = 0 */
        xorl    %r15d, %r15d            /* nospec   r15 */
 
-       /*
-        * User mode is traced as though IRQs are on, and SYSENTER
-        * turned them off.
-        */
-       TRACE_IRQS_OFF
-
        movq    %rsp, %rdi
        call    do_fast_syscall_32
        /* XEN PV guests always use IRET path */
@@ -403,12 +391,6 @@ SYM_CODE_START(entry_INT80_compat)
        xorl    %r15d, %r15d            /* nospec   r15 */
        cld
 
-       /*
-        * User mode is traced as though IRQs are on, and the interrupt
-        * gate turned them off.
-        */
-       TRACE_IRQS_OFF
-
        movq    %rsp, %rdi
        call    do_int80_syscall_32
 .Lsyscall_32_done: