Commit 997d79eb authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas

arm64: Move do_notify_resume() to entry-common.c

Currently do_notify_resume() lives in arch/arm64/kernel/signal.c, but it would
make more sense for it to live in entry-common.c as it handles more than
signals, and is coupled with the rest of the return-to-userspace sequence (e.g.
with unusual DAIF masking that matches the exception return requirements).

Move do_notify_resume() to entry-common.c.

There should be no functional change as a result of this patch.
Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20240206123848.1696480-3-mark.rutland@arm.comSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Tested-by: default avatarItaru Kitayama <itaru.kitayama@linux.dev>
parent 270de609
...@@ -74,7 +74,7 @@ void do_el0_fpac(struct pt_regs *regs, unsigned long esr); ...@@ -74,7 +74,7 @@ void do_el0_fpac(struct pt_regs *regs, unsigned long esr);
void do_el1_fpac(struct pt_regs *regs, unsigned long esr); void do_el1_fpac(struct pt_regs *regs, unsigned long esr);
void do_el0_mops(struct pt_regs *regs, unsigned long esr); void do_el0_mops(struct pt_regs *regs, unsigned long esr);
void do_serror(struct pt_regs *regs, unsigned long esr); void do_serror(struct pt_regs *regs, unsigned long esr);
void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags); void do_signal(struct pt_regs *regs);
void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far); void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigned long far);
#endif /* __ASM_EXCEPTION_H */ #endif /* __ASM_EXCEPTION_H */
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/lockdep.h> #include <linux/lockdep.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/resume_user_mode.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/debug.h> #include <linux/sched/debug.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
...@@ -126,6 +127,37 @@ static __always_inline void __exit_to_user_mode(void) ...@@ -126,6 +127,37 @@ static __always_inline void __exit_to_user_mode(void)
lockdep_hardirqs_on(CALLER_ADDR0); lockdep_hardirqs_on(CALLER_ADDR0);
} }
static void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
{
do {
local_daif_restore(DAIF_PROCCTX);
if (thread_flags & _TIF_NEED_RESCHED)
schedule();
if (thread_flags & _TIF_UPROBE)
uprobe_notify_resume(regs);
if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
clear_thread_flag(TIF_MTE_ASYNC_FAULT);
send_sig_fault(SIGSEGV, SEGV_MTEAERR,
(void __user *)NULL, current);
}
if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME)
resume_user_mode_work(regs);
if (thread_flags & _TIF_FOREIGN_FPSTATE)
fpsimd_restore_current_state();
local_daif_mask();
thread_flags = read_thread_flags();
} while (thread_flags & _TIF_WORK_MASK);
}
static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs) static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs)
{ {
unsigned long flags; unsigned long flags;
......
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/sizes.h> #include <linux/sizes.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/resume_user_mode.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/rseq.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <asm/daifflags.h> #include <asm/daifflags.h>
...@@ -1207,7 +1207,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) ...@@ -1207,7 +1207,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
* the kernel can handle, and then we build all the user-level signal handling * the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that. * stack-frames in one go after that.
*/ */
static void do_signal(struct pt_regs *regs) void do_signal(struct pt_regs *regs)
{ {
unsigned long continue_addr = 0, restart_addr = 0; unsigned long continue_addr = 0, restart_addr = 0;
int retval = 0; int retval = 0;
...@@ -1278,37 +1278,6 @@ static void do_signal(struct pt_regs *regs) ...@@ -1278,37 +1278,6 @@ static void do_signal(struct pt_regs *regs)
restore_saved_sigmask(); restore_saved_sigmask();
} }
void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
{
do {
local_daif_restore(DAIF_PROCCTX);
if (thread_flags & _TIF_NEED_RESCHED)
schedule();
if (thread_flags & _TIF_UPROBE)
uprobe_notify_resume(regs);
if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
clear_thread_flag(TIF_MTE_ASYNC_FAULT);
send_sig_fault(SIGSEGV, SEGV_MTEAERR,
(void __user *)NULL, current);
}
if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME)
resume_user_mode_work(regs);
if (thread_flags & _TIF_FOREIGN_FPSTATE)
fpsimd_restore_current_state();
local_daif_mask();
thread_flags = read_thread_flags();
} while (thread_flags & _TIF_WORK_MASK);
}
unsigned long __ro_after_init signal_minsigstksz; unsigned long __ro_after_init signal_minsigstksz;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment