Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: entry: remove redundant IRQ flag tracing

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>

authored by

Mark Rutland and committed by
Catalin Marinas
df068247 d78050ee

+1 -15
-7
arch/arm64/kernel/signal.c
··· 914 914 asmlinkage void do_notify_resume(struct pt_regs *regs, 915 915 unsigned long thread_flags) 916 916 { 917 - /* 918 - * The assembly code enters us with IRQs off, but it hasn't 919 - * informed the tracing code of that for efficiency reasons. 920 - * Update the trace code with the current status. 921 - */ 922 - trace_hardirqs_off(); 923 - 924 917 do { 925 918 if (thread_flags & _TIF_NEED_RESCHED) { 926 919 /* Unmask Debug and SError for the next task */
+1 -8
arch/arm64/kernel/syscall.c
··· 165 165 if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { 166 166 local_daif_mask(); 167 167 flags = current_thread_info()->flags; 168 - if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { 169 - /* 170 - * We're off to userspace, where interrupts are 171 - * always enabled after we restore the flags from 172 - * the SPSR. 173 - */ 174 - trace_hardirqs_on(); 168 + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) 175 169 return; 176 - } 177 170 local_daif_restore(DAIF_PROCCTX); 178 171 } 179 172