1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/context_tracking.h>
4 #include <linux/entry-common.h>
6 #define CREATE_TRACE_POINTS
7 #include <trace/events/syscalls.h>
10 * enter_from_user_mode - Establish state when coming from user mode
12 * Syscall/interrupt entry disables interrupts, but user mode is traced as
13 * interrupts enabled. Also with NO_HZ_FULL RCU might be idle.
15 * 1) Tell lockdep that interrupts are disabled
16 * 2) Invoke context tracking if enabled to reactivate RCU
17 * 3) Trace interrupts off state
19 static __always_inline void enter_from_user_mode(struct pt_regs *regs)
21 arch_check_user_regs(regs);
22 lockdep_hardirqs_off(CALLER_ADDR0);
24 CT_WARN_ON(ct_state() != CONTEXT_USER);
27 instrumentation_begin();
28 trace_hardirqs_off_finish();
29 instrumentation_end();
32 static inline void syscall_enter_audit(struct pt_regs *regs, long syscall)
34 if (unlikely(audit_context())) {
35 unsigned long args[6];
37 syscall_get_arguments(current, regs, args);
38 audit_syscall_entry(syscall, args[0], args[1], args[2], args[3]);
42 static long syscall_trace_enter(struct pt_regs *regs, long syscall,
43 unsigned long ti_work)
48 if (ti_work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) {
49 ret = arch_syscall_enter_tracehook(regs);
50 if (ret || (ti_work & _TIF_SYSCALL_EMU))
54 /* Do seccomp after ptrace, to catch any tracer changes. */
55 if (ti_work & _TIF_SECCOMP) {
56 ret = __secure_computing(NULL);
61 if (unlikely(ti_work & _TIF_SYSCALL_TRACEPOINT))
62 trace_sys_enter(regs, syscall);
64 syscall_enter_audit(regs, syscall);
66 return ret ? : syscall;
69 noinstr long syscall_enter_from_user_mode(struct pt_regs *regs, long syscall)
71 unsigned long ti_work;
73 enter_from_user_mode(regs);
74 instrumentation_begin();
77 ti_work = READ_ONCE(current_thread_info()->flags);
78 if (ti_work & SYSCALL_ENTER_WORK)
79 syscall = syscall_trace_enter(regs, syscall, ti_work);
80 instrumentation_end();
85 noinstr void irqentry_enter_from_user_mode(struct pt_regs *regs)
87 enter_from_user_mode(regs);