|
@@ -269,6 +269,7 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags)
|
|
/* Called with IRQs disabled. */
|
|
/* Called with IRQs disabled. */
|
|
__visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
|
|
__visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
|
|
{
|
|
{
|
|
|
|
+ struct thread_info *ti = pt_regs_to_thread_info(regs);
|
|
u32 cached_flags;
|
|
u32 cached_flags;
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled()))
|
|
if (IS_ENABLED(CONFIG_PROVE_LOCKING) && WARN_ON(!irqs_disabled()))
|
|
@@ -276,12 +277,22 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs)
|
|
|
|
|
|
lockdep_sys_exit();
|
|
lockdep_sys_exit();
|
|
|
|
|
|
- cached_flags =
|
|
|
|
- READ_ONCE(pt_regs_to_thread_info(regs)->flags);
|
|
|
|
|
|
+ cached_flags = READ_ONCE(ti->flags);
|
|
|
|
|
|
if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS))
|
|
if (unlikely(cached_flags & EXIT_TO_USERMODE_LOOP_FLAGS))
|
|
exit_to_usermode_loop(regs, cached_flags);
|
|
exit_to_usermode_loop(regs, cached_flags);
|
|
|
|
|
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
|
+ /*
|
|
|
|
+ * Compat syscalls set TS_COMPAT. Make sure we clear it before
|
|
|
|
+ * returning to user mode. We need to clear it *after* signal
|
|
|
|
+ * handling, because syscall restart has a fixup for compat
|
|
|
|
+ * syscalls. The fixup is exercised by the ptrace_syscall_32
|
|
|
|
+ * selftest.
|
|
|
|
+ */
|
|
|
|
+ ti->status &= ~TS_COMPAT;
|
|
|
|
+#endif
|
|
|
|
+
|
|
user_enter();
|
|
user_enter();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -333,14 +344,6 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs)
|
|
if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS))
|
|
if (unlikely(cached_flags & SYSCALL_EXIT_WORK_FLAGS))
|
|
syscall_slow_exit_work(regs, cached_flags);
|
|
syscall_slow_exit_work(regs, cached_flags);
|
|
|
|
|
|
-#ifdef CONFIG_COMPAT
|
|
|
|
- /*
|
|
|
|
- * Compat syscalls set TS_COMPAT. Make sure we clear it before
|
|
|
|
- * returning to user mode.
|
|
|
|
- */
|
|
|
|
- ti->status &= ~TS_COMPAT;
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
local_irq_disable();
|
|
local_irq_disable();
|
|
prepare_exit_to_usermode(regs);
|
|
prepare_exit_to_usermode(regs);
|
|
}
|
|
}
|