summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel/signal.c
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2024-02-06 12:38:46 +0000
committerCatalin Marinas <catalin.marinas@arm.com>2024-02-20 18:12:13 +0000
commit270de609ae2af441d15289406340ff209e5dc864 (patch)
tree8bc18acec0a6e3257f00cc017b04d217276aefb3 /arch/arm64/kernel/signal.c
parent54be6c6c5ae8e0d93a6c4641cb7528eb0b6ba478 (diff)
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: 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>
Diffstat (limited to 'arch/arm64/kernel/signal.c')
-rw-r--r--arch/arm64/kernel/signal.c34
1 files changed, 15 insertions, 19 deletions
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 0e8beb3349ea..50e108741599 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -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();