From: Ard Biesheuvel <ardb@kernel.org>
To: linux@armlinux.org.uk
Cc: linux-arm-kernel@lists.infradead.org,
Ard Biesheuvel <ardb@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
Sudeep Holla <sudeep.holla@arm.com>,
Cristian Marussi <cristian.marussi@arm.com>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Arnd Bergmann <arnd@arndb.de>,
Linus Walleij <linus.walleij@linaro.org>,
Masami Hiramatsu <mhiramat@kernel.org>
Subject: [PATCH v2 07/12] ARM: unwind: track location of LR value in stack frame
Date: Mon, 31 Jan 2022 18:03:42 +0100 [thread overview]
Message-ID: <20220131170347.381551-8-ardb@kernel.org> (raw)
In-Reply-To: <20220131170347.381551-1-ardb@kernel.org>
The ftrace graph tracer needs to override the return address of an
instrumented function, in order to install a hook that gets invoked when
the function returns again.
Currently, we only support this when building for ARM using GCC with
frame pointers, as in this case, it is guaranteed that the function will
reload LR from [FP, #-4] in all cases, and we can simply pass that
address to the ftrace code.
In order to support this for configurations that rely on the EABI
unwinder, such as Thumb2 builds, make the unwinder keep track of the
address from which LR was unwound, permitting ftrace to make use of this
in a subsequent patch.
Drop the call to is_kernel_text_address(), which is problematic in terms
of ftrace recursion, given that it may be instrumented itself. The call
is redundant anyway, as no unwind directives will be found unless the PC
points to memory that is known to contain executable code.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/arm/include/asm/stacktrace.h | 3 +++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/unwind.c | 7 ++++---
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index d87d60532b86..e56503fd9447 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -14,6 +14,9 @@ struct stackframe {
unsigned long sp;
unsigned long lr;
unsigned long pc;
+
+ /* address of the LR value on the stack */
+ unsigned long *lr_addr;
#ifdef CONFIG_KRETPROBES
struct llist_node *kr_cur;
struct task_struct *tsk;
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ae295a3bcfef..56511856ff9d 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,6 +10,7 @@ ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_insn.o = -pg
CFLAGS_REMOVE_patch.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
endif
CFLAGS_REMOVE_return_address.o = -pg
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index c5ea328c428d..b4e468a7674b 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -55,6 +55,7 @@ struct unwind_ctrl_block {
const unsigned long *insn; /* pointer to the current instructions word */
unsigned long sp_low; /* lowest value of sp allowed */
unsigned long sp_high; /* highest value of sp allowed */
+ unsigned long *lr_addr; /* address of LR value on the stack */
/*
* 1 : check for stack overflow for each register pop.
* 0 : save overhead if there is plenty of stack remaining.
@@ -239,6 +240,8 @@ static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
* from being tracked by KASAN.
*/
ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp));
+ if (reg == 14)
+ ctrl->lr_addr = *vsp;
(*vsp)++;
return URC_OK;
}
@@ -395,9 +398,6 @@ int unwind_frame(struct stackframe *frame)
pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
frame->pc, frame->lr, frame->sp);
- if (!kernel_text_address(frame->pc))
- return -URC_FAILURE;
-
idx = unwind_find_idx(frame->pc);
if (!idx) {
pr_warn("unwind: Index not found %08lx\n", frame->pc);
@@ -476,6 +476,7 @@ int unwind_frame(struct stackframe *frame)
frame->lr = ctrl.vrs[LR];
frame->pc = ctrl.vrs[PC];
frame->sp_low = ctrl.sp_low;
+ frame->lr_addr = ctrl.lr_addr;
return URC_OK;
}
--
2.30.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2022-01-31 17:23 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-31 17:03 [PATCH v2 00/12] ARM: ftrace fixes and cleanups Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 01/12] ARM: ftrace: ensure that ADR take Thumb bit into account Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 02/12] ARM: ftrace: use ADD not POP to counter PUSH at entry Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 03/12] ARM: ftrace: use trampolines to keep .init.text in branching range Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 04/12] ARM: ftrace: avoid redundant loads or clobbering IP Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 05/12] ARM: ftrace: avoid unnecessary literal loads Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 06/12] ARM: ftrace: enable HAVE_FUNCTION_GRAPH_FP_TEST Ard Biesheuvel
2022-01-31 17:03 ` Ard Biesheuvel [this message]
2022-01-31 17:03 ` [PATCH v2 08/12] ARM: ftrace: enable the graph tracer with the EABI unwinder Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 09/12] ARM: kprobes: treat R7 as the frame pointer register in Thumb2 builds Ard Biesheuvel
2022-01-31 18:31 ` Nick Desaulniers
2022-02-01 7:42 ` Ard Biesheuvel
2022-02-01 13:18 ` Masami Hiramatsu
2022-02-01 14:05 ` Ard Biesheuvel
2022-02-02 6:10 ` Masami Hiramatsu
2022-02-02 8:00 ` Ard Biesheuvel
2022-01-31 17:03 ` [PATCH v2 10/12] drivers/firmware/scmi: disable ftrace for Clang " Ard Biesheuvel
2022-01-31 18:37 ` Nick Desaulniers
2022-02-01 8:12 ` Ard Biesheuvel
2022-01-31 22:04 ` Sudeep Holla
2022-01-31 17:03 ` [PATCH v2 11/12] ARM: cacheflush: avoid clobbering the frame pointer in Thumb2 mode Ard Biesheuvel
2022-01-31 18:40 ` Nick Desaulniers
2022-01-31 17:03 ` [PATCH v2 12/12] Revert "ARM: 9144/1: forbid ftrace with clang and thumb2_kernel" Ard Biesheuvel
2022-01-31 18:42 ` Nick Desaulniers
2022-01-31 17:21 ` [PATCH v2 00/12] ARM: ftrace fixes and cleanups Steven Rostedt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220131170347.381551-8-ardb@kernel.org \
--to=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=cristian.marussi@arm.com \
--cc=linus.walleij@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=mhiramat@kernel.org \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=rostedt@goodmis.org \
--cc=sudeep.holla@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).