arm64: entry: remove redundant IRQ flag tracing
authorMark Rutland <mark.rutland@arm.com>
Thu, 7 Jan 2021 14:53:10 +0000 (14:53 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Jan 2021 10:55:07 +0000 (11:55 +0100)
[ Upstream commit df06824767cc9a32fbdb0e3d3b7e169292a5b5fe ]

All EL0 returns go via ret_to_user(), which masks IRQs and notifies
lockdep and tracing before calling into do_notify_resume(). Therefore,
there's no need for do_notify_resume() to call trace_hardirqs_off(), and
the comment is stale. The call is simply redundant.

In ret_to_user() we call exit_to_user_mode(), which notifies lockdep and
tracing the IRQs will be enabled in userspace, so there's no need for
el0_svc_common() to call trace_hardirqs_on() before returning. Further,
at the start of ret_to_user() we call trace_hardirqs_off(), so not only
is this redundant, but it is immediately undone.

In addition to being redundant, the trace_hardirqs_on() in
el0_svc_common() leaves lockdep inconsistent with the hardware state,
and is liable to cause issues for any C code or instrumentation
between this and the call to trace_hardirqs_off() which undoes it in
ret_to_user().

This patch removes the redundant tracing calls and associated stale
comments.

Fixes: 23529049c684 ("arm64: entry: fix non-NMI user<->kernel transitions")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Will Deacon <will@kernel.org>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20210107145310.44616-1-mark.rutland@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm64/kernel/signal.c
arch/arm64/kernel/syscall.c

index a8184ca..5085299 100644 (file)
@@ -914,13 +914,6 @@ static void do_signal(struct pt_regs *regs)
 asmlinkage void do_notify_resume(struct pt_regs *regs,
                                 unsigned long thread_flags)
 {
-       /*
-        * The assembly code enters us with IRQs off, but it hasn't
-        * informed the tracing code of that for efficiency reasons.
-        * Update the trace code with the current status.
-        */
-       trace_hardirqs_off();
-
        do {
                /* Check valid user FS if needed */
                addr_limit_user_check();
index f8f758e..6fa8cfb 100644 (file)
@@ -165,15 +165,8 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
        if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) {
                local_daif_mask();
                flags = current_thread_info()->flags;
-               if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) {
-                       /*
-                        * We're off to userspace, where interrupts are
-                        * always enabled after we restore the flags from
-                        * the SPSR.
-                        */
-                       trace_hardirqs_on();
+               if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP))
                        return;
-               }
                local_daif_restore(DAIF_PROCCTX);
        }