Commit dd8e2d9a authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/entry: Move irq tracing on syscall entry to C-code



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: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarAlexandre Chartre <alexandre.chartre@oracle.com>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200505134340.611961721@linutronix.de


parent 8f159f1d
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -40,19 +40,36 @@
#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)
+0 −12
Original line number Diff line number Diff line
@@ -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:
+0 −2
Original line number Diff line number Diff line
@@ -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
+0 −18
Original line number Diff line number Diff line
@@ -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: