]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
arm64: Simplify do_notify_resume() DAIF masking
authorMark Rutland <mark.rutland@arm.com>
Tue, 6 Feb 2024 12:38:46 +0000 (12:38 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Tue, 20 Feb 2024 18:12:13 +0000 (18:12 +0000)
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: Mark 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: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20240206123848.1696480-2-mark.rutland@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Itaru Kitayama <itaru.kitayama@linux.dev>
arch/arm64/kernel/signal.c

index 0e8beb3349ea2a1aae6340f879f78dd568e04f51..50e108741599d2caef3bd7f492e8275778490bd6 100644 (file)
@@ -1281,32 +1281,28 @@ static void do_signal(struct pt_regs *regs)
 void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
 {
        do {
-               if (thread_flags & _TIF_NEED_RESCHED) {
-                       /* Unmask Debug and SError for the next task */
-                       local_daif_restore(DAIF_PROCCTX_NOIRQ);
+               local_daif_restore(DAIF_PROCCTX);
 
+               if (thread_flags & _TIF_NEED_RESCHED)
                        schedule();
-               } else {
-                       local_daif_restore(DAIF_PROCCTX);
 
-                       if (thread_flags & _TIF_UPROBE)
-                               uprobe_notify_resume(regs);
+               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_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_SIGPENDING | _TIF_NOTIFY_SIGNAL))
+                       do_signal(regs);
 
-                       if (thread_flags & _TIF_NOTIFY_RESUME)
-                               resume_user_mode_work(regs);
+               if (thread_flags & _TIF_NOTIFY_RESUME)
+                       resume_user_mode_work(regs);
 
-                       if (thread_flags & _TIF_FOREIGN_FPSTATE)
-                               fpsimd_restore_current_state();
-               }
+               if (thread_flags & _TIF_FOREIGN_FPSTATE)
+                       fpsimd_restore_current_state();
 
                local_daif_mask();
                thread_flags = read_thread_flags();