7
7
#include <linux/syscalls.h>
8
8
#include <linux/seccomp.h>
9
9
#include <linux/sched.h>
10
+ #include <linux/context_tracking.h>
11
+ #include <linux/livepatch.h>
12
+ #include <linux/resume_user_mode.h>
13
+ #include <linux/tick.h>
14
+ #include <linux/kmsan.h>
10
15
11
16
#include <asm/entry-common.h>
12
17
@@ -98,7 +103,19 @@ static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs) {}
98
103
* done between establishing state and enabling interrupts. The caller must
99
104
* enable interrupts before invoking syscall_enter_from_user_mode_work().
100
105
*/
101
- void enter_from_user_mode (struct pt_regs * regs );
106
+ static __always_inline void enter_from_user_mode (struct pt_regs * regs )
107
+ {
108
+ arch_enter_from_user_mode (regs );
109
+ lockdep_hardirqs_off (CALLER_ADDR0 );
110
+
111
+ CT_WARN_ON (__ct_state () != CONTEXT_USER );
112
+ user_exit_irqoff ();
113
+
114
+ instrumentation_begin ();
115
+ kmsan_unpoison_entry_regs (regs );
116
+ trace_hardirqs_off_finish ();
117
+ instrumentation_end ();
118
+ }
102
119
103
120
/**
104
121
* syscall_enter_from_user_mode_prepare - Establish state and enable interrupts
@@ -117,6 +134,9 @@ void enter_from_user_mode(struct pt_regs *regs);
117
134
*/
118
135
void syscall_enter_from_user_mode_prepare (struct pt_regs * regs );
119
136
137
+ long syscall_trace_enter (struct pt_regs * regs , long syscall ,
138
+ unsigned long work );
139
+
120
140
/**
121
141
* syscall_enter_from_user_mode_work - Check and handle work before invoking
122
142
* a syscall
@@ -140,7 +160,15 @@ void syscall_enter_from_user_mode_prepare(struct pt_regs *regs);
140
160
* ptrace_report_syscall_entry(), __secure_computing(), trace_sys_enter()
141
161
* 2) Invocation of audit_syscall_entry()
142
162
*/
143
- long syscall_enter_from_user_mode_work (struct pt_regs * regs , long syscall );
163
+ static __always_inline long syscall_enter_from_user_mode_work (struct pt_regs * regs , long syscall )
164
+ {
165
+ unsigned long work = READ_ONCE (current_thread_info ()-> syscall_work );
166
+
167
+ if (work & SYSCALL_WORK_ENTER )
168
+ syscall = syscall_trace_enter (regs , syscall , work );
169
+
170
+ return syscall ;
171
+ }
144
172
145
173
/**
146
174
* syscall_enter_from_user_mode - Establish state and check and handle work
@@ -159,7 +187,19 @@ long syscall_enter_from_user_mode_work(struct pt_regs *regs, long syscall);
159
187
* Returns: The original or a modified syscall number. See
160
188
* syscall_enter_from_user_mode_work() for further explanation.
161
189
*/
162
- long syscall_enter_from_user_mode (struct pt_regs * regs , long syscall );
190
+ static __always_inline long syscall_enter_from_user_mode (struct pt_regs * regs , long syscall )
191
+ {
192
+ long ret ;
193
+
194
+ enter_from_user_mode (regs );
195
+
196
+ instrumentation_begin ();
197
+ local_irq_enable ();
198
+ ret = syscall_enter_from_user_mode_work (regs , syscall );
199
+ instrumentation_end ();
200
+
201
+ return ret ;
202
+ }
163
203
164
204
/**
165
205
* local_irq_enable_exit_to_user - Exit to user variant of local_irq_enable()
@@ -258,6 +298,43 @@ static __always_inline void arch_exit_to_user_mode(void) { }
258
298
*/
259
299
void arch_do_signal_or_restart (struct pt_regs * regs );
260
300
301
+ /**
302
+ * exit_to_user_mode_loop - do any pending work before leaving to user space
303
+ */
304
+ unsigned long exit_to_user_mode_loop (struct pt_regs * regs ,
305
+ unsigned long ti_work );
306
+
307
+ /**
308
+ * exit_to_user_mode_prepare - call exit_to_user_mode_loop() if required
309
+ * @regs: Pointer to pt_regs on entry stack
310
+ *
311
+ * 1) check that interrupts are disabled
312
+ * 2) call tick_nohz_user_enter_prepare()
313
+ * 3) call exit_to_user_mode_loop() if any flags from
314
+ * EXIT_TO_USER_MODE_WORK are set
315
+ * 4) check that interrupts are still disabled
316
+ */
317
+ static __always_inline void exit_to_user_mode_prepare (struct pt_regs * regs )
318
+ {
319
+ unsigned long ti_work ;
320
+
321
+ lockdep_assert_irqs_disabled ();
322
+
323
+ /* Flush pending rcuog wakeup before the last need_resched() check */
324
+ tick_nohz_user_enter_prepare ();
325
+
326
+ ti_work = read_thread_flags ();
327
+ if (unlikely (ti_work & EXIT_TO_USER_MODE_WORK ))
328
+ ti_work = exit_to_user_mode_loop (regs , ti_work );
329
+
330
+ arch_exit_to_user_mode_prepare (regs , ti_work );
331
+
332
+ /* Ensure that kernel state is sane for a return to userspace */
333
+ kmap_assert_nomap ();
334
+ lockdep_assert_irqs_disabled ();
335
+ lockdep_sys_exit ();
336
+ }
337
+
261
338
/**
262
339
* exit_to_user_mode - Fixup state when exiting to user mode
263
340
*
@@ -276,7 +353,17 @@ void arch_do_signal_or_restart(struct pt_regs *regs);
276
353
* non-instrumentable.
277
354
* The caller has to invoke syscall_exit_to_user_mode_work() before this.
278
355
*/
279
- void exit_to_user_mode (void );
356
+ static __always_inline void exit_to_user_mode (void )
357
+ {
358
+ instrumentation_begin ();
359
+ trace_hardirqs_on_prepare ();
360
+ lockdep_hardirqs_on_prepare ();
361
+ instrumentation_end ();
362
+
363
+ user_enter_irqoff ();
364
+ arch_exit_to_user_mode ();
365
+ lockdep_hardirqs_on (CALLER_ADDR0 );
366
+ }
280
367
281
368
/**
282
369
* syscall_exit_to_user_mode_work - Handle work before returning to user mode
0 commit comments