arm64: entry: unmask IRQ+FIQ after EL0 handling
authorMark Rutland <mark.rutland@arm.com>
Mon, 7 Jun 2021 09:46:06 +0000 (10:46 +0100)
committerWill Deacon <will@kernel.org>
Mon, 7 Jun 2021 10:35:54 +0000 (11:35 +0100)
For non-fatal exceptions taken from EL0, we expect that at some point
during exception handling it is possible to return to a regular process
context with all exceptions unmasked (e.g. as we do in
do_notify_resume()), and we generally aim to unmask exceptions wherever
possible.

While handling SError and debug exceptions from EL0, we need to leave
some exceptions masked during handling. Handling SError requires us to
mask SError (which also requires masking IRQ+FIQ), and handing debug
exceptions requires us to mask debug (which also requires masking
SError+IRQ+FIQ).

Once do_serror() or do_debug_exception() has returned, we no longer need
to mask exceptions, and can unmask them all, which is what we did prior
to commit:

  9034f6251572a474 ("arm64: Do not enable IRQs for ct_user_exit")

... where we had to mask IRQs as for context_tracking_user_exit()
expected IRQs to be masked.

Since then, we realised that our context tracking wasn't entirely
correct, and reworked the entry code to fix this. As of commit:

  23529049c6842382 ("arm64: entry: fix non-NMI user<->kernel transitions")

... we replaced the call to context_tracking_user_exit() with a call to
user_exit_irqoff() as part of enter_from_user_mode(), which occurs
earlier, before we run the body of the handler and unmask exceptions in
DAIF.

When we return to userspace, we go via ret_to_user(), which masks
exceptions in DAIF prior to calling user_enter_irqoff() as part of
exit_to_user_mode().

Thus, there's no longer a reason to leave IRQs or FIQs masked at the end
of the EL0 debug or error handlers, as neither the user exit context
tracking nor the user entry context tracking requires this. Let's bring
these into line with other EL0 exception handlers and ensure that IRQ
and FIQ are unmasked in DAIF at some point during the handler.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20210607094624.34689-3-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/kernel/entry-common.c
arch/arm64/kernel/entry.S

index 340d04e136179450ddada9a0b1de727eb29df9d0..02be1517e08f5ca2bcc73a7c39b15012f7de4077 100644 (file)
@@ -398,7 +398,7 @@ static void noinstr el0_dbg(struct pt_regs *regs, unsigned long esr)
 
        enter_from_user_mode();
        do_debug_exception(far, esr, regs);
-       local_daif_restore(DAIF_PROCCTX_NOIRQ);
+       local_daif_restore(DAIF_PROCCTX);
 }
 
 static void noinstr el0_svc(struct pt_regs *regs)
index 3513984a88bd1b149c9fa0113bcd4ae7e4003625..6b2f6f5c5bb8cd5ffa057fd585da27c43c2473c0 100644 (file)
@@ -794,7 +794,7 @@ el0_error_naked:
        mov     x0, sp
        mov     x1, x25
        bl      do_serror
-       enable_da
+       enable_daif
        b       ret_to_user
 SYM_CODE_END(el0_error)