Commit 270de609 authored by Mark Rutland's avatar Mark Rutland Committed by Catalin Marinas

arm64: Simplify do_notify_resume() DAIF masking

In do_notify_resume, we handle _TIF_NEED_RESCHED differently from all
other flags, leaving IRQ+FIQ masked when calling into schedule(). This
masking is a historical artifact, and it is not currently necessary
to mask IRQ+FIQ when calling into schedule (as evidenced by the generic
exit_to_user_mode_loop(), which unmasks IRQs before checking
_TIF_NEED_RESCHED and calling schedule()).

This patch removes the special case for _TIF_NEED_RESCHED, moving this
check into the main loop such that schedule() will be called from a
regular process context with IRQ+FIQ unmasked. This is a minor
simplification to do_notify_resume() and brings it into line with the
generic exit_to_user_mode_loop() logic. This will also aid subsequent
rework of DAIF management.
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-2-mark.rutland@arm.comSigned-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Tested-by: default avatarItaru Kitayama <itaru.kitayama@linux.dev>
parent 54be6c6c
...@@ -1281,32 +1281,28 @@ static void do_signal(struct pt_regs *regs) ...@@ -1281,32 +1281,28 @@ static void do_signal(struct pt_regs *regs)
void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
{ {
do { do {
if (thread_flags & _TIF_NEED_RESCHED) { local_daif_restore(DAIF_PROCCTX);
/* Unmask Debug and SError for the next task */
local_daif_restore(DAIF_PROCCTX_NOIRQ);
if (thread_flags & _TIF_NEED_RESCHED)
schedule(); schedule();
} else {
local_daif_restore(DAIF_PROCCTX);
if (thread_flags & _TIF_UPROBE) if (thread_flags & _TIF_UPROBE)
uprobe_notify_resume(regs); uprobe_notify_resume(regs);
if (thread_flags & _TIF_MTE_ASYNC_FAULT) { if (thread_flags & _TIF_MTE_ASYNC_FAULT) {
clear_thread_flag(TIF_MTE_ASYNC_FAULT); clear_thread_flag(TIF_MTE_ASYNC_FAULT);
send_sig_fault(SIGSEGV, SEGV_MTEAERR, send_sig_fault(SIGSEGV, SEGV_MTEAERR,
(void __user *)NULL, current); (void __user *)NULL, current);
} }
if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) if (thread_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs); do_signal(regs);
if (thread_flags & _TIF_NOTIFY_RESUME) if (thread_flags & _TIF_NOTIFY_RESUME)
resume_user_mode_work(regs); resume_user_mode_work(regs);
if (thread_flags & _TIF_FOREIGN_FPSTATE) if (thread_flags & _TIF_FOREIGN_FPSTATE)
fpsimd_restore_current_state(); fpsimd_restore_current_state();
}
local_daif_mask(); local_daif_mask();
thread_flags = read_thread_flags(); thread_flags = read_thread_flags();
......
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