ARM: ftrace: use ADD not POP to counter PUSH at entry
authorArd Biesheuvel <ardb@kernel.org>
Wed, 8 Dec 2021 07:42:03 +0000 (08:42 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Wed, 9 Feb 2022 08:12:32 +0000 (09:12 +0100)
The compiler emitted hook used for ftrace consists of a PUSH {LR} to
preserve the link register, followed by a branch-and-link (BL) to
__gnu_mount_nc. Dynamic ftrace patches away the latter to turn the
combined sequence into a NOP, using a POP {LR} instruction.

This is not necessary, since the link register does not get clobbered in
this case, and simply adding #4 to the stack pointer is sufficient, and
avoids a memory access that may take a few cycles to resolve depending
on the micro-architecture.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
arch/arm/kernel/entry-ftrace.S
arch/arm/kernel/ftrace.c

index f4886fb..dca12a0 100644 (file)
@@ -27,7 +27,7 @@
  * allows it to be clobbered in subroutines and doesn't use it to hold
  * parameters.)
  *
- * When using dynamic ftrace, we patch out the mcount call by a "pop {lr}"
+ * When using dynamic ftrace, we patch out the mcount call by a "add sp, #4"
  * instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
  */
 
index a006585..811cadf 100644 (file)
 #include <asm/set_memory.h>
 #include <asm/patch.h>
 
+/*
+ * The compiler emitted profiling hook consists of
+ *
+ *   PUSH    {LR}
+ *   BL             __gnu_mcount_nc
+ *
+ * To turn this combined sequence into a NOP, we need to restore the value of
+ * SP before the PUSH. Let's use an ADD rather than a POP into LR, as LR is not
+ * modified anyway, and reloading LR from memory is highly likely to be less
+ * efficient.
+ */
 #ifdef CONFIG_THUMB2_KERNEL
-#define        NOP             0xf85deb04      /* pop.w {lr} */
+#define        NOP             0xf10d0d04      /* add.w sp, sp, #4 */
 #else
-#define        NOP             0xe8bd4000      /* pop {lr} */
+#define        NOP             0xe28dd004      /* add   sp, sp, #4 */
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE