From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CC525C433F5 for ; Tue, 25 Jan 2022 15:55:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=N6bhA3Mh319sAh/RkbFe3vzhKmpIwDSf14fsC+fYh4w=; b=PZxqtBmkWeYSYW VrBvN94KANmnb+BliEcDouYXEKiFAPYyRFAtCFbN+A56MipQxOEi3512XnRhr29SyeV7hq9hhRfY0 nSFXdoMH6B59Knrz5iJfjJMnxL1KcukNzAxnmScbSiU5njbdV2b0ERVotU/oGX0znrUzlaT128c4J u5ldq27DXhc+61lnBPwwHUCT71qGJzEkyx5pfHFEP1u0nX9G/v4tzrZrjZYrT0F2kwy4otR3sl6Fe 2Jcd99QY6IcNtUSDIZ3IsodMDGWUBzCI8FFSwrZr/mUucR7bt/+5gqt1IfAFNTJ8S2KxbHUQBigrs i+M9PblaZUeMfykFydOw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCO8C-008UVp-QY; Tue, 25 Jan 2022 15:53:17 +0000 Received: from ams.source.kernel.org ([2604:1380:4601:e00::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nCNsw-008QAC-S3 for linux-arm-kernel@lists.infradead.org; Tue, 25 Jan 2022 15:37:33 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 34F38B818B5; Tue, 25 Jan 2022 15:37:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A9F9C340E8; Tue, 25 Jan 2022 15:37:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1643125047; bh=cGICg1sptqUZnit/XOBDDWq7Hq/0ytpp+oJf6nE0lIM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Dijr/e529OzQAAbpZr9mA5snp3tbZTfbY7ooSy0Ei2ufAm4c79bMBjtiLZEtXj6cr XciN/X3Y46LkzfxxrN27xOgRKET4aiXUQv3NhuRU8/9I10zfwMMv7OvAoaycCN7FmT 2FtEQXUY5517rt7R+CErBYhIaIQElFPkkmFhfr9BxwYHIRcPToQlmIYVlnfvzP+KYu tkUV6bexmjMRvyLVoYu0zDuUq2UA58EdDSdnULGsNcJG7T2peg+BHYsrK6JiKoZsMm WbNmAQd6CTug28tK9IOIeJDJ64TYFjmPdjpSCcUeY/S2djIvRPNi9pIBX2t1tBjQQ4 iN5m2YyYZJskg== From: Ard Biesheuvel To: linux@armlinux.org.uk, linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , Arnd Bergmann , Linus Walleij , Nick Desaulniers Subject: [PATCH 8/8] ARM: ftrace: enable the graph tracer with the EABI unwinder Date: Tue, 25 Jan 2022 16:36:56 +0100 Message-Id: <20220125153656.1802079-9-ardb@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org> References: <20220125153656.1802079-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7691; h=from:subject; bh=cGICg1sptqUZnit/XOBDDWq7Hq/0ytpp+oJf6nE0lIM=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBh8BkXqcMKfLV3ZaCszWWHcNR1Hy3glY4sZXEDAU65 SkilTHKJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYfAZFwAKCRDDTyI5ktmPJEjsC/ 4nTh7LuATFaNjvlciv26B3gAJjTLvO+HhvtU1VkR9iQAIKVY0osNsL+NXWr4dke9NngJR9Lso1Z3X9 jZ6t57q3nN5PYS8zitVRrOlxInTi/J206OxnJW55/wK/o797/HfVEUv2MDU6StgD8yYoJLkEKfCJoU /s6l+rAKU4g/5I2X2/1tcj6kfEQrY0Q8Zo+RWPgdieGZ8bIJVOJUfplWhddnMjub6weyJdb+XHz/yg PM38J7jv5qa9flaPEpJwaYwbOAmVr03PDyyakXvxA/LB5tu3NJmUSF16l+zys+Rx3Alp52hA9w6wHn XXhErkmgZ4dXmhYEDqU01Mj2wrIfmsFAAOPEmdUMD2vIW2pD3TTWgjZRGhnU0MQosm58VNIDEiu/0I 1KMm+Ot9ZSQuSe9uKHz57lGMl4UNjT576DQlMuTRUmMzLDY1cSkJEZ8/yHoGvArfLSmsu9LudfFPLe I0Ebp8Vs1KBOO2zwfmwzKZ5fvFbtwaYMbDKmmIXp0oZhE= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220125_073731_254202_5FE47023 X-CRM114-Status: GOOD ( 24.25 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Enable the function graph tracer in combination with the EABI unwinder, so that Thumb2 builds or Clang ARM builds can make use of it. This involves using the unwinder to locate the return address of an instrumented function on the stack, so that it can be overridden and made to refer to the ftrace handling routines that need to be called at function return. Given that for these builds, it is not guaranteed that the value of the link register is stored on the stack, fall back to the stack slot that will be used by the ftrace exit code to restore LR in the instrumented function's execution context. Signed-off-by: Ard Biesheuvel --- arch/arm/Kconfig | 2 +- arch/arm/Kconfig.debug | 2 +- arch/arm/include/asm/ftrace.h | 18 ------------- arch/arm/kernel/Makefile | 5 +--- arch/arm/kernel/entry-ftrace.S | 28 ++++++++++++++------ arch/arm/kernel/ftrace.c | 19 +++++++++++-- 6 files changed, 40 insertions(+), 34 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cbbe38f55088..e3c1a76d0a42 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -92,7 +92,7 @@ config ARM select HAVE_EXIT_THREAD select HAVE_FAST_GUP if ARM_LPAE select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL - select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG + select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG) select HAVE_GCC_PLUGINS select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 976315dea958..0c9497d549e3 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -65,7 +65,7 @@ config UNWINDER_FRAME_POINTER config UNWINDER_ARM bool "ARM EABI stack unwinder" - depends on AEABI && !FUNCTION_GRAPH_TRACER + depends on AEABI select ARM_UNWIND help This option enables stack unwinding support in the kernel diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h index b4f5fab6b04e..5358aad67831 100644 --- a/arch/arm/include/asm/ftrace.h +++ b/arch/arm/include/asm/ftrace.h @@ -35,26 +35,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) #ifndef __ASSEMBLY__ -#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) -/* - * return_address uses walk_stackframe to do it's work. If both - * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind - * information. For this to work in the function tracer many functions would - * have to be marked with __notrace. So for now just depend on - * !CONFIG_ARM_UNWIND. - */ - void *return_address(unsigned int); -#else - -static inline void *return_address(unsigned int level) -{ - return NULL; -} - -#endif - #define ftrace_return_address(n) return_address(n) #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 56511856ff9d..5cebb8d5a1d6 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -25,10 +25,7 @@ obj-y := elf.o entry-common.o irq.o opcodes.o \ KASAN_SANITIZE_stacktrace.o := n KASAN_SANITIZE_traps.o := n -ifneq ($(CONFIG_ARM_UNWIND),y) -obj-$(CONFIG_FRAME_POINTER) += return_address.o -endif - +obj-y += return_address.o obj-$(CONFIG_ATAGS) += atags_parse.o obj-$(CONFIG_ATAGS_PROC) += atags_proc.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S index bbfa0954c385..3e7bcaca5e07 100644 --- a/arch/arm/kernel/entry-ftrace.S +++ b/arch/arm/kernel/entry-ftrace.S @@ -100,7 +100,8 @@ ftrace_regs_call: #ifdef CONFIG_FUNCTION_GRAPH_TRACER .globl ftrace_graph_regs_call ftrace_graph_regs_call: - mov r0, r0 +ARM( mov r0, r0 ) +THUMB( nop.w ) #endif @ pop saved regs @@ -112,13 +113,18 @@ ftrace_graph_regs_call: #ifdef CONFIG_FUNCTION_GRAPH_TRACER .macro __ftrace_graph_regs_caller - sub r0, fp, #4 @ lr of instrumented routine (parent) +#ifdef CONFIG_UNWINDER_FRAME_POINTER + sub r0, fp, #4 @ lr of instrumented routine (parent) +#else + add r0, sp, #S_LR +#endif @ called from __ftrace_regs_caller - ldr r1, [sp, #S_PC] @ instrumented routine (func) + ldr r1, [sp, #S_PC] @ instrumented routine (func) mcount_adjust_addr r1, r1 - mov r2, fp @ frame pointer + mov r2, fpreg @ frame pointer + add r3, sp, #PT_REGS_SIZE bl prepare_ftrace_return @ pop registers saved in ftrace_regs_caller @@ -149,14 +155,19 @@ ftrace_call\suffix: #ifdef CONFIG_FUNCTION_GRAPH_TRACER .globl ftrace_graph_call\suffix ftrace_graph_call\suffix: - mov r0, r0 +ARM( mov r0, r0 ) +THUMB( nop.w ) #endif mcount_exit .endm .macro __ftrace_graph_caller +#ifdef CONFIG_UNWINDER_FRAME_POINTER sub r0, fp, #4 @ &lr of instrumented routine (&parent) +#else + add r0, sp, #20 +#endif #ifdef CONFIG_DYNAMIC_FTRACE @ called from __ftrace_caller, saved in mcount_enter ldr r1, [sp, #16] @ instrumented routine (func) @@ -165,7 +176,8 @@ ftrace_graph_call\suffix: @ called from __mcount, untouched in lr mcount_adjust_addr r1, lr @ instrumented routine (func) #endif - mov r2, fp @ frame pointer + mov r2, fpreg @ frame pointer + add r3, sp, #24 bl prepare_ftrace_return mcount_exit .endm @@ -244,14 +256,14 @@ ENDPROC(ftrace_graph_regs_caller) .purgem mcount_exit #ifdef CONFIG_FUNCTION_GRAPH_TRACER - .globl return_to_handler -return_to_handler: +ENTRY(return_to_handler) stmdb sp!, {r0-r3} add r0, sp, #16 @ sp at exit of instrumented routine bl ftrace_return_to_handler mov lr, r0 @ r0 has real ret addr ldmia sp!, {r0-r3} ret lr +ENDPROC(return_to_handler) #endif ENTRY(ftrace_stub) diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 988525b274e3..65aa9e1eface 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #ifdef CONFIG_THUMB2_KERNEL @@ -211,8 +212,10 @@ int ftrace_make_nop(struct module *mod, #endif /* CONFIG_DYNAMIC_FTRACE */ #ifdef CONFIG_FUNCTION_GRAPH_TRACER +asmlinkage void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, - unsigned long frame_pointer) + unsigned long frame_pointer, + unsigned long stack_pointer) { unsigned long return_hooker = (unsigned long) &return_to_handler; unsigned long old; @@ -223,6 +226,18 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) { /* FP points one word below parent's top of stack */ frame_pointer += 4; + } else { + struct stackframe frame = { + .fp = frame_pointer, + .sp = stack_pointer, + .lr = self_addr, + .pc = self_addr, + }; + if (unwind_frame(&frame) < 0) + return; + if (frame.lr != self_addr) + parent = frame.lr_addr; + frame_pointer = frame.sp; } old = *parent; @@ -245,7 +260,7 @@ static int __ftrace_modify_caller(unsigned long *callsite, unsigned long caller_fn = (unsigned long) func; unsigned long pc = (unsigned long) callsite; unsigned long branch = arm_gen_branch(pc, caller_fn); - unsigned long nop = 0xe1a00000; /* mov r0, r0 */ + unsigned long nop = arm_gen_nop(); unsigned long old = enable ? nop : branch; unsigned long new = enable ? branch : nop; -- 2.30.2 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel