Commit ad1c2f39 authored by Ard Biesheuvel's avatar Ard Biesheuvel
Browse files

ARM: ftrace: use ADD not POP to counter PUSH at entry



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: default avatarArd Biesheuvel <ardb@kernel.org>
Reviewed-by: default avatarNick Desaulniers <ndesaulniers@google.com>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
parent dd88b03f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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).
 */

+13 −2
Original line number Diff line number Diff line
@@ -24,10 +24,21 @@
#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