From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 055C6C4167B for ; Fri, 8 Dec 2023 16:36:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1573889AbjLHQgf (ORCPT ); Fri, 8 Dec 2023 11:36:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574539AbjLHQfm (ORCPT ); Fri, 8 Dec 2023 11:35:42 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC5FA1BD9 for ; Fri, 8 Dec 2023 08:35:46 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E9608C433C8; Fri, 8 Dec 2023 16:35:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053346; bh=Ho/kybth4D2azYyy3+MrZcuV5/UtWLUUn5wsZ3KGBaY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Jh+JoUBhx/n+uubL7szxJytPSQ53Zm47OjhmnBAd9ZX/l9qyt04gNFfuYtjHYCHwr pZUNCoaeFX9sJLhGo43RBkkne2uQhz9S/6kr6T9MrVqBOoCuMFkBC7UmlyLtyDwLzL WOFgLyrJtV5039Mohiw8mt+5WoReashV3Kmzs4eK4POOkTSyAQS4ISVh4vNanu7ZCj bRclPa490aWqumbrEIEdUjScW+5bw30KF2iCQxtDW+O3S68I0/hvGM5539BT0BwATO UpdF5GT6VWOrQkGh+heMG1R9FL+7ui9lsazW+Vwcjis4OxopQ3P2LonVxMxCgwOy3x 5dQVm+RiHAoyA== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 1/9] powerpc/ftrace: Fix indentation in ftrace.h Date: Fri, 8 Dec 2023 22:00:40 +0530 Message-ID: <9f058227bd9243f0842786ef7228d87ab10d29f6.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Replace seven spaces with a tab character to fix an indentation issue reported by the kernel test robot. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202311221731.alUwTDIm-lkp@int= el.com/ Signed-off-by: Naveen N Rao --- arch/powerpc/include/asm/ftrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/f= trace.h index 9e5a39b6a311..1ebd2ca97f12 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -25,7 +25,7 @@ static inline unsigned long ftrace_call_adjust(unsigned l= ong addr) if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) addr +=3D MCOUNT_INSN_SIZE; =20 - return addr; + return addr; } =20 unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip, --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BA4A2C4167B for ; Fri, 8 Dec 2023 16:35:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574316AbjLHQfM (ORCPT ); Fri, 8 Dec 2023 11:35:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574057AbjLHQfD (ORCPT ); Fri, 8 Dec 2023 11:35:03 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73A1C19AA for ; Fri, 8 Dec 2023 08:35:08 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2CBEEC433C8; Fri, 8 Dec 2023 16:35:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053308; bh=SUBvtEn9z9UrSU17r7Cw0HAstRv+zJkI6nOLOYxgtBI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dgZj87RJDMQntv41jgP4YNzanNPs+Fpah5vLvv/Fi7x0xv29OoS4clgN/qIAyR3jV hNHJeCEa/bbQa3tIPnXKAXv1XPy755Z5yFhAqz/ZNGNCeHC60vxB53+qo4cZ5ZDMGt 1bKvP6XKSFo//muVUOZZnkbmDgADqtIdir6Z1wlBqONgp6SxBcA0Fpg4TBCaa7JPoH DyIwjCw1N0hyzBtUCNEkS+BkeEJHcvJ2vMCyeg2HJIFUbmpLMN74veO6ZY9RsKKn+X WnLEVHuFTlAKZL/rOOjuiuX5Vaa7uEQymnLPerK8Spbtr8wV1Ef8GfvngNKvimkVO8 EumXuDYVXZszg== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 2/9] powerpc/ftrace: Unify 32-bit and 64-bit ftrace entry code Date: Fri, 8 Dec 2023 22:00:41 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" On 32-bit powerpc, gcc generates a three instruction sequence for function profiling: mflr r0 stw r0, 4(r1) bl _mcount On kernel boot, the call to _mcount() is nop-ed out, to be patched back in when ftrace is actually enabled. The 'stw' instruction therefore is not necessary unless ftrace is enabled. Nop it out during ftrace init. When ftrace is enabled, we want the 'stw' so that stack unwinding works properly. Perform the same within the ftrace handler, similar to 64-bit powerpc. For 64-bit powerpc, early versions of gcc used to emit a three instruction sequence for function profiling (with -mprofile-kernel) with a 'std' instruction to mimic the 'stw' above. Address that scenario also by nop-ing out the 'std' instruction during ftrace init. Signed-off-by: Naveen N Rao --- arch/powerpc/kernel/trace/ftrace.c | 6 ++++-- arch/powerpc/kernel/trace/ftrace_entry.S | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace= /ftrace.c index 82010629cf88..2956196c98ff 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -229,13 +229,15 @@ int ftrace_init_nop(struct module *mod, struct dyn_ft= race *rec) /* Expected sequence: 'mflr r0', 'stw r0,4(r1)', 'bl _mcount' */ ret =3D ftrace_validate_inst(ip - 8, ppc_inst(PPC_RAW_MFLR(_R0))); if (!ret) - ret =3D ftrace_validate_inst(ip - 4, ppc_inst(PPC_RAW_STW(_R0, _R1, 4))= ); + ret =3D ftrace_modify_code(ip - 4, ppc_inst(PPC_RAW_STW(_R0, _R1, 4)), + ppc_inst(PPC_RAW_NOP())); } else if (IS_ENABLED(CONFIG_MPROFILE_KERNEL)) { /* Expected sequence: 'mflr r0', ['std r0,16(r1)'], 'bl _mcount' */ ret =3D ftrace_read_inst(ip - 4, &old); if (!ret && !ppc_inst_equal(old, ppc_inst(PPC_RAW_MFLR(_R0)))) { ret =3D ftrace_validate_inst(ip - 8, ppc_inst(PPC_RAW_MFLR(_R0))); - ret |=3D ftrace_validate_inst(ip - 4, ppc_inst(PPC_RAW_STD(_R0, _R1, 16= ))); + ret |=3D ftrace_modify_code(ip - 4, ppc_inst(PPC_RAW_STD(_R0, _R1, 16)), + ppc_inst(PPC_RAW_NOP())); } } else { return -EINVAL; diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel= /trace/ftrace_entry.S index 40677416d7b2..17d1ed3d0b40 100644 --- a/arch/powerpc/kernel/trace/ftrace_entry.S +++ b/arch/powerpc/kernel/trace/ftrace_entry.S @@ -33,6 +33,8 @@ * and then arrange for the ftrace function to be called. */ .macro ftrace_regs_entry allregs + /* Save the original return address in A's stack frame */ + PPC_STL r0, LRSAVE(r1) /* Create a minimal stack frame for representing B */ PPC_STLU r1, -STACK_FRAME_MIN_SIZE(r1) =20 @@ -44,8 +46,6 @@ SAVE_GPRS(3, 10, r1) =20 #ifdef CONFIG_PPC64 - /* Save the original return address in A's stack frame */ - std r0, LRSAVE+SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE(r1) /* Ok to continue? */ lbz r3, PACA_FTRACE_ENABLED(r13) cmpdi r3, 0 --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15FF5C4167B for ; Fri, 8 Dec 2023 16:35:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574400AbjLHQfS (ORCPT ); Fri, 8 Dec 2023 11:35:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574219AbjLHQfG (ORCPT ); Fri, 8 Dec 2023 11:35:06 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5B599198E for ; Fri, 8 Dec 2023 08:35:13 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34BC3C433C7; Fri, 8 Dec 2023 16:35:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053313; bh=v2mYSDmjqdbapRfO1Kx9bcMiig2SVy+s9w1cLpmU0IY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ME9PtPfym6Ef0DDZb+Yjsva6Tx8a2WFMT7p9z045HUvh9QMf6RYkYWO9RVuxKCFgU HJcwtvyeTDA4KEjFRvwrIbXOu7CmVeFAVv63UTCBUWBRfBvmLPohHZUqUw8UlH+OjM 7XtiUv082yDmJAx1zPZCY03aeXILFNzg8yK+5FTCffZ4PiV0xSKCaQekcRzWHGLWdx tgDLBLsAWL7w1QN3PX4zxsuozv5RHP5xxw1+h7Ke6HDg5/vbmy6mu2P7Z7JC4Keetj GCv1sqJ1XsfaiO78KJ9MM0sDVB1FFKqvhgYXhoCOLIfq7BNf3nUgtbk23tcxonJOAV W9PhRJauc5uaQ== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 3/9] powerpc/ftrace: Remove nops after the call to ftrace_stub Date: Fri, 8 Dec 2023 22:00:42 +0530 Message-ID: <8ee5ec520e37d5523654bb2cd65a17512fb774e2.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" ftrace_stub is within the same CU, so there is no need for a subsequent nop instruction. Signed-off-by: Naveen N Rao --- arch/powerpc/kernel/trace/ftrace_entry.S | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel= /trace/ftrace_entry.S index 17d1ed3d0b40..244a1c7bb1e8 100644 --- a/arch/powerpc/kernel/trace/ftrace_entry.S +++ b/arch/powerpc/kernel/trace/ftrace_entry.S @@ -162,7 +162,6 @@ _GLOBAL(ftrace_regs_caller) .globl ftrace_regs_call ftrace_regs_call: bl ftrace_stub - nop ftrace_regs_exit 1 =20 _GLOBAL(ftrace_caller) @@ -171,7 +170,6 @@ _GLOBAL(ftrace_caller) .globl ftrace_call ftrace_call: bl ftrace_stub - nop ftrace_regs_exit 0 =20 _GLOBAL(ftrace_stub) --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D62E4C46CA3 for ; Fri, 8 Dec 2023 16:35:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574457AbjLHQf2 (ORCPT ); Fri, 8 Dec 2023 11:35:28 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41484 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574298AbjLHQfL (ORCPT ); Fri, 8 Dec 2023 11:35:11 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F169519A9 for ; Fri, 8 Dec 2023 08:35:17 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 144D9C433B6; Fri, 8 Dec 2023 16:35:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053317; bh=l/ccn9TohWmVu0gidxLaFZAXe873u+W72QG48wg65qk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KmthFkp9R6S/S5QKzNeYjmgaMpiidbj1m4cc2zhTtKl9OKSy2IzILLGw4PS0qs3VM Hh1heFlMbk9aE/p7RBhwLjnswCE20sB/esq/CO5GoY2rktts5wrkXxi6aHYiCfBRq7 XgjhbwiQXDa+9B2X5cePCKwa6R+ED0TZv6+eghgsMEYO2vhqjU8OtofeTWVZmo0N/u RcF5U3Rm/tOZYbODaFJNlgpCv5VWA8Afh+n+MhcgtQiy7TsGZGRJV1CrT1EDsTBqcx 1yibxRHME3rt9nAgj5bWwwmxecDUzmirP2JGnoaWXn4gfsho0Ws6VszDbfdaPo5/6D x8AlUT9JYDW2Q== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 4/9] powerpc/Kconfig: Select FUNCTION_ALIGNMENT_4B Date: Fri, 8 Dec 2023 22:00:43 +0530 Message-ID: <21892186ec44abe24df0daf64f577dac0e78783f.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Sathvika Vasireddy Commit d49a0626216b95 ("arch: Introduce CONFIG_FUNCTION_ALIGNMENT") introduced a generic function-alignment infrastructure. Move to using FUNCTION_ALIGNMENT_4B on powerpc, to use the same alignment as that of the existing _GLOBAL macro. Signed-off-by: Sathvika Vasireddy --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/linkage.h | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 6f105ee4f3cf..318e5c1b7454 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -189,6 +189,7 @@ config PPC select EDAC_ATOMIC_SCRUB select EDAC_SUPPORT select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if ARCH_USING_PATCHABLE= _FUNCTION_ENTRY + select FUNCTION_ALIGNMENT_4B select GENERIC_ATOMIC64 if PPC32 select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_CMOS_UPDATE diff --git a/arch/powerpc/include/asm/linkage.h b/arch/powerpc/include/asm/= linkage.h index b88d1d2cf304..b71b9582e754 100644 --- a/arch/powerpc/include/asm/linkage.h +++ b/arch/powerpc/include/asm/linkage.h @@ -4,9 +4,6 @@ =20 #include =20 -#define __ALIGN .align 2 -#define __ALIGN_STR ".align 2" - #ifdef CONFIG_PPC64_ELF_ABI_V1 #define cond_syscall(x) \ asm ("\t.weak " #x "\n\t.set " #x ", sys_ni_syscall\n" \ --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0D76FC10F05 for ; Fri, 8 Dec 2023 16:35:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574217AbjLHQfe (ORCPT ); Fri, 8 Dec 2023 11:35:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235959AbjLHQfY (ORCPT ); Fri, 8 Dec 2023 11:35:24 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 969311995 for ; Fri, 8 Dec 2023 08:35:22 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A3D15C433CA; Fri, 8 Dec 2023 16:35:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053322; bh=Z4H+/v658tdpIUS/M5eM4mkmmspGMz1KhbqU6pOZF5M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qErDFEmodD4DDHqqZIhdZcw0R/xgNXnvkXsREwRbPKKokGq2qG2xZUkfREtkgqGnA 4g84nEMw28/wbN9hRCzkZPhe6Y5ZKK3qerh7amZTHf9IZt+IiARhqVLNQC5j6Z8LoG F1Smct9Ycj0BSKp8chdrfrR9LExLy9vL0FIz1AvGHUJb4Dw9KnAlIkDzfl+sELiG3+ B43QVHxSh3P4pn4Epgg+Cvx/CPHy4DBXdlZkgSFdGN3u8Q+2DjbVyjdupIX7QmqBdV Z8klsrgLmfc8dE0QjCKTTOeln31fMuYCkbfVP3mZDbMPdKhvUQ89P81GHQAuV2t2HA Vx0ZkALRS12pA== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 5/9] powerpc/kprobes: Use ftrace to determine if a probe is at function entry Date: Fri, 8 Dec 2023 22:00:44 +0530 Message-ID: <15f0b3a2e72326423cfb4ce4e89afff540042245.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Rather than hard-coding the offset into a function to be used to determine if a kprobe is at function entry, use ftrace_location() to determine the ftrace location within the function and categorize all instructions till that offset to be function entry. For functions that cannot be traced, we fall back to using a fixed offset of 8 (two instructions) to categorize a probe as being at function entry for 64-bit elfv2. Signed-off-by: Naveen N Rao Acked-by: Masami Hiramatsu (Google) --- arch/powerpc/kernel/kprobes.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index b20ee72e873a..42665dfab59e 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -105,24 +105,22 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name,= unsigned int offset) return addr; } =20 -static bool arch_kprobe_on_func_entry(unsigned long offset) +static bool arch_kprobe_on_func_entry(unsigned long addr, unsigned long of= fset) { -#ifdef CONFIG_PPC64_ELF_ABI_V2 -#ifdef CONFIG_KPROBES_ON_FTRACE - return offset <=3D 16; -#else - return offset <=3D 8; -#endif -#else + unsigned long ip =3D ftrace_location(addr); + + if (ip) + return offset <=3D (ip - addr); + if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2)) + return offset <=3D 8; return !offset; -#endif } =20 /* XXX try and fold the magic of kprobe_lookup_name() in this */ kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long= offset, bool *on_func_entry) { - *on_func_entry =3D arch_kprobe_on_func_entry(offset); + *on_func_entry =3D arch_kprobe_on_func_entry(addr, offset); return (kprobe_opcode_t *)(addr + offset); } =20 --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63EACC4167B for ; Fri, 8 Dec 2023 16:36:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574168AbjLHQgI (ORCPT ); Fri, 8 Dec 2023 11:36:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574437AbjLHQf1 (ORCPT ); Fri, 8 Dec 2023 11:35:27 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94DEA1BF9 for ; Fri, 8 Dec 2023 08:35:28 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 09800C433C8; Fri, 8 Dec 2023 16:35:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053327; bh=NrFJSrx/3KR19QzR5TYpYUFTEJbo+oQ4qyOEwL/i7oY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tNc8PeKxSqfDlHuiQBneADfgcw9l8lFQKQFHNKGLDEayi4SBRjtLo5pSh7n9IkhM/ addO+WlSlvXzV6wJ+ajcWwMC+DlK7gX2W/KkBuOwvicad2MgqE8hjE29GLHCCthSyX Z30585QGQp6wo0eykt2xGLeAlUdKhLwd9rytH+HS1+X/vdk31Owgi5CDeEO9QNGQD7 F35eZAUdOwp2yUSWmtZX6CjSVidZ6T8ngt8cTXdyb31Iw4S+S+zHqiLUua4EAscvWG CeH7CSOYauI9OcJcC+bNyGwAxriZpbitzWD/fhmh/DjZnhHA+wSUHfw33w6FviTaSu fB3Cj5nk9s2TA== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 6/9] powerpc/ftrace: Update and move function profile instructions out-of-line Date: Fri, 8 Dec 2023 22:00:45 +0530 Message-ID: <39363eb6b1857f26f9fa51808ad48b0121899b84.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Function profile sequence on powerpc includes two instructions at the beginning of each function: mflr r0 bl ftrace_caller The call to ftrace_caller() gets nop'ed out during kernel boot and is patched in when ftrace is enabled. There are two issues with this: 1. The 'mflr r0' instruction at the beginning of each function remains even though ftrace is not being used. 2. When ftrace is activated, we return from ftrace_caller() with a bctr instruction to preserve r0 and LR, resulting in the link stack becoming unbalanced. To address (1), we have tried to nop'out the 'mflr r0' instruction when nop'ing out the call to ftrace_caller() and restoring it when enabling ftrace. But, that required additional synchronization slowing down ftrace activation. It also left an additional nop instruction at the beginning of each function and that wasn't desirable on 32-bit powerpc. Instead of that, move the function profile sequence out-of-line leaving a single nop at function entry. On ftrace activation, the nop is changed to an unconditional branch to the out-of-line sequence that in turn calls ftrace_caller(). This removes the need for complex synchronization during ftrace activation and simplifies the code. More importantly, this improves performance of the kernel when ftrace is not in use. To address (2), change the ftrace trampoline to return with a 'blr' instruction with the original return address in r0 intact. Then, an additional 'mtlr r0' instruction in the function profile sequence can move the correct return address back to LR. With the above two changes, the function profile sequence now looks like the following: [func: # GEP -- 64-bit powerpc, optional addis r2,r12,imm1 addi r2,r2,imm2] tramp: mflr r0 bl ftrace_caller mtlr r0 b func nop [nop] # 64-bit powerpc only func: # LEP nop On 32-bit powerpc, the ftrace mcount trampoline is now completely outside the function. This is also the case on 64-bit powerpc for functions that do not need a GEP. However, for functions that need a GEP, the additional instructions are inserted between the GEP and the LEP. Since we can only have a fixed number of instructions between GEP and LEP, we choose to emit 6 instructions. Four of those instructions are used for the function profile sequence and two instruction slots are reserved for implementing support for DYNAMIC_FTRACE_WITH_CALL_OPS. On 32-bit powerpc, we emit one additional nop for this purpose resulting in a total of 5 nops before function entry. To enable ftrace, the nop at function entry is changed to an unconditional branch to 'tramp'. The call to ftrace_caller() may be updated to ftrace_regs_caller() depending on the registered ftrace ops. On 64-bit powerpc, we additionally change the instruction at 'tramp' to 'mflr r0' from an unconditional branch back to func+4. This is so that functions entered through the GEP can skip the function profile sequence unless ftrace is enabled. With the context_switch microbenchmark on a P9 machine, there is a performance improvement of ~6% with this patch applied, going from 650k context switches to 690k context switches without ftrace enabled. With ftrace enabled, the performance was similar at 86k context switches. The downside of this approach is the increase in vmlinux size, especially on 32-bit powerpc. We now emit 3 additional instructions for each function (excluding the one or two instructions for supporting DYNAMIC_FTRACE_WITH_CALL_OPS). On 64-bit powerpc with the current implementation of -fpatchable-function-entry though, this is not avoidable since we are forced to emit 6 instructions between the GEP and the LEP even if we are to only support DYNAMIC_FTRACE_WITH_CALL_OPS. Signed-off-by: Naveen N Rao --- arch/powerpc/Makefile | 6 +- arch/powerpc/include/asm/code-patching.h | 15 ++- arch/powerpc/include/asm/ftrace.h | 18 ++- arch/powerpc/kernel/kprobes.c | 51 +++++++- arch/powerpc/kernel/trace/ftrace.c | 149 ++++++++++++++++++----- arch/powerpc/kernel/trace/ftrace_entry.S | 54 ++++++-- 6 files changed, 246 insertions(+), 47 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index f19dbaa1d541..91ef34be8eb9 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -145,7 +145,11 @@ CFLAGS-$(CONFIG_PPC32) +=3D $(call cc-option,-mno-read= only-in-sdata) ifdef CONFIG_FUNCTION_TRACER ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY KBUILD_CPPFLAGS +=3D -DCC_USING_PATCHABLE_FUNCTION_ENTRY -CC_FLAGS_FTRACE :=3D -fpatchable-function-entry=3D2 +ifdef CONFIG_PPC32 +CC_FLAGS_FTRACE :=3D -fpatchable-function-entry=3D6,5 +else +CC_FLAGS_FTRACE :=3D -fpatchable-function-entry=3D7,6 +endif else CC_FLAGS_FTRACE :=3D -pg ifdef CONFIG_MPROFILE_KERNEL diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/includ= e/asm/code-patching.h index 84f6ccd7de7a..9a54bb9e0dde 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -185,10 +185,21 @@ static inline unsigned long ppc_function_entry(void *= func) */ if ((((*insn & OP_RT_RA_MASK) =3D=3D ADDIS_R2_R12) || ((*insn & OP_RT_RA_MASK) =3D=3D LIS_R2)) && - ((*(insn+1) & OP_RT_RA_MASK) =3D=3D ADDI_R2_R2)) + ((*(insn+1) & OP_RT_RA_MASK) =3D=3D ADDI_R2_R2)) { +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + /* + * Heuristic: look for the 'mtlr r0' instruction assuming ftrace init is= done. + * If it is not found, look for two consecutive nops after the GEP. + * Longer term, we really should be parsing the symbol table to determin= e LEP. + */ + if ((*(insn+4) =3D=3D PPC_RAW_MTLR(_R0)) || + ((*(insn+2) =3D=3D PPC_RAW_NOP() && *(insn+3) =3D=3D PPC_RAW_NOP()))) + return (unsigned long)(insn + 8); +#endif return (unsigned long)(insn + 2); - else + } else { return (unsigned long)func; + } #elif defined(CONFIG_PPC64_ELF_ABI_V1) /* * On PPC64 ABIv1 the function pointer actually points to the diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/f= trace.h index 1ebd2ca97f12..d9b99781bea3 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -11,10 +11,20 @@ #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR =20 /* Ignore unused weak functions which will have larger offsets */ -#if defined(CONFIG_MPROFILE_KERNEL) || defined(CONFIG_ARCH_USING_PATCHABLE= _FUNCTION_ENTRY) -#define FTRACE_MCOUNT_MAX_OFFSET 16 +#if defined(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY) +#if defined(CONFIG_PPC64) +#define FTRACE_MCOUNT_MAX_OFFSET (MCOUNT_INSN_SIZE * 8) +#define FTRACE_MCOUNT_TRAMP_OFFSET (MCOUNT_INSN_SIZE * 6) +#else +#define FTRACE_MCOUNT_MAX_OFFSET 0 +#define FTRACE_MCOUNT_TRAMP_OFFSET (MCOUNT_INSN_SIZE * 5) +#endif /* CONFIG_PPC64 */ +#elif defined(CONFIG_MPROFILE_KERNEL) +#define FTRACE_MCOUNT_MAX_OFFSET (MCOUNT_INSN_SIZE * 4) +#define FTRACE_MCOUNT_TRAMP_OFFSET 0 #elif defined(CONFIG_PPC32) -#define FTRACE_MCOUNT_MAX_OFFSET 8 +#define FTRACE_MCOUNT_MAX_OFFSET (MCOUNT_INSN_SIZE * 2) +#define FTRACE_MCOUNT_TRAMP_OFFSET 0 #endif =20 #ifndef __ASSEMBLY__ @@ -23,7 +33,7 @@ extern void _mcount(void); static inline unsigned long ftrace_call_adjust(unsigned long addr) { if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) - addr +=3D MCOUNT_INSN_SIZE; + addr +=3D FTRACE_MCOUNT_TRAMP_OFFSET; =20 return addr; } diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 42665dfab59e..21557cf8544d 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -33,12 +33,61 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); =20 struct kretprobe_blackpoint kretprobe_blacklist[] =3D {{NULL, NULL}}; =20 +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY +/* + * Reject probes on the ftrace mcount trampoline instruction sequence. Th= ere + * are two scenarios to handle: + * 1. Functions that can be traced and have a GEP. + * 2. Functions without a GEP, wherein the ftrace mcount trampoline ends up + * being part of the previous function + */ +static inline bool addr_within_ftrace_mcount_trampoline(unsigned long addr) +{ + unsigned long ip, size, offset; + + if (!kallsyms_lookup_size_offset(addr, &size, &offset)) + return false; + + if (IS_ENABLED(CONFIG_PPC64)) { + ip =3D ftrace_location(addr - offset); + + /* If the function is traceable and has GEP... */ + if (ip && ip !=3D (addr - offset)) + /* ... reject probes on 6 instructions after the GEP entry sequence */ + if (offset >=3D 2 * MCOUNT_INSN_SIZE && offset < 8 * MCOUNT_INSN_SIZE) + return true; + + /* If the next function is traceable and does not have GEP... */ + ip =3D addr + offset; + if (ftrace_location(ip) =3D=3D ip) + /* ... reject probes on 6 instructions at the end of the function */ + if (offset >=3D (size - 6 * MCOUNT_INSN_SIZE)) + return true; + } else { + /* If the next function is traceable ... */ + ip =3D addr + offset; + if (ftrace_location(ip) =3D=3D ip) + /* ... reject probes on the last 5 instructions of the function */ + if (offset >=3D (size - 5 * MCOUNT_INSN_SIZE)) + return true; + } + + return false; +} +#else +static inline bool addr_within_ftrace_mcount_trampoline(unsigned long addr) +{ + return false; +} +#endif + bool arch_within_kprobe_blacklist(unsigned long addr) { return (addr >=3D (unsigned long)__kprobes_text_start && addr < (unsigned long)__kprobes_text_end) || (addr >=3D (unsigned long)_stext && - addr < (unsigned long)__head_end); + addr < (unsigned long)__head_end) || + addr_within_ftrace_mcount_trampoline(addr); } =20 kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset) diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace= /ftrace.c index 2956196c98ff..d3b4949142a8 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -70,7 +70,7 @@ static inline int ftrace_modify_code(unsigned long ip, pp= c_inst_t old, ppc_inst_ { int ret =3D ftrace_validate_inst(ip, old); =20 - if (!ret) + if (!ret && !ppc_inst_equal(old, new)) ret =3D patch_instruction((u32 *)ip, new); =20 return ret; @@ -96,7 +96,8 @@ static unsigned long find_ftrace_tramp(unsigned long ip) =20 static int ftrace_get_call_inst(struct dyn_ftrace *rec, unsigned long addr= , ppc_inst_t *call_inst) { - unsigned long ip =3D rec->ip; + unsigned long ip =3D rec->ip - (FTRACE_MCOUNT_TRAMP_OFFSET ? + FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE : 0); unsigned long stub; =20 if (is_offset_in_branch_range(addr - ip)) { @@ -135,18 +136,38 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsign= ed long old_addr, unsigned int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { ppc_inst_t old, new; - int ret; + unsigned long ip; + int ret =3D 0; =20 - /* This can only ever be called during module load */ if (WARN_ON(!IS_ENABLED(CONFIG_MODULES) || core_kernel_text(rec->ip))) return -EINVAL; =20 - old =3D ppc_inst(PPC_RAW_NOP()); - ret =3D ftrace_get_call_inst(rec, addr, &new); + if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) + ret =3D ftrace_get_call_inst(rec, (unsigned long)ftrace_caller, &old); + else + old =3D ppc_inst(PPC_RAW_NOP()); + ret |=3D ftrace_get_call_inst(rec, addr, &new); if (ret) return ret; =20 - return ftrace_modify_code(rec->ip, old, new); + ip =3D rec->ip - (FTRACE_MCOUNT_TRAMP_OFFSET ? + FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE : 0); + + /* This can only ever be called during module load */ + ret =3D ftrace_modify_code(ip, old, new); + + if (ret || !IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) + return ret; + + ip =3D rec->ip; + ret =3D ftrace_modify_code(ip, ppc_inst(PPC_RAW_NOP()), + ppc_inst(PPC_RAW_BRANCH(-FTRACE_MCOUNT_TRAMP_OFFSET))); + if (IS_ENABLED(CONFIG_PPC64) && !ret) + ret =3D ftrace_modify_code(ip - FTRACE_MCOUNT_TRAMP_OFFSET, + ppc_inst(PPC_RAW_BRANCH(FTRACE_MCOUNT_TRAMP_OFFSET + MCOUNT_INSN_SIZE= )), + ppc_inst(PPC_RAW_MFLR(_R0))); + + return ret; } =20 int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned l= ong addr) @@ -170,7 +191,8 @@ void ftrace_replace_code(int enable) =20 for_ftrace_rec_iter(iter) { rec =3D ftrace_rec_iter_record(iter); - ip =3D rec->ip; + ip =3D rec->ip - (FTRACE_MCOUNT_TRAMP_OFFSET ? + FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE : 0); =20 if (rec->flags & FTRACE_FL_DISABLED && !(rec->flags & FTRACE_FL_ENABLED)) continue; @@ -179,6 +201,12 @@ void ftrace_replace_code(int enable) new_addr =3D ftrace_get_addr_new(rec); update =3D ftrace_update_record(rec, enable); =20 + if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) { + ret =3D ftrace_get_call_inst(rec, (unsigned long)ftrace_caller, &nop_in= st); + if (ret) + goto out; + } + switch (update) { case FTRACE_UPDATE_IGNORE: default: @@ -205,6 +233,35 @@ void ftrace_replace_code(int enable) ret =3D ftrace_modify_code(ip, old, new); if (ret) goto out; + + if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY) && + (update =3D=3D FTRACE_UPDATE_MAKE_NOP || update =3D=3D FTRACE_UPDATE= _MAKE_CALL)) { + /* Update the actual ftrace location */ + call_inst =3D ppc_inst(PPC_RAW_BRANCH(-FTRACE_MCOUNT_TRAMP_OFFSET)); + nop_inst =3D ppc_inst(PPC_RAW_NOP()); + ip =3D rec->ip; + + if (update =3D=3D FTRACE_UPDATE_MAKE_NOP) + ret =3D ftrace_modify_code(ip, call_inst, nop_inst); + else + ret =3D ftrace_modify_code(ip, nop_inst, call_inst); + + /* Switch unconditional branch after GEP to/from 'mflr r0' */ + if (IS_ENABLED(CONFIG_PPC64) && !ret) { + call_inst =3D ppc_inst(PPC_RAW_BRANCH(FTRACE_MCOUNT_TRAMP_OFFSET + MCO= UNT_INSN_SIZE)); + old =3D ppc_inst(PPC_RAW_MFLR(_R0)); + + if (update =3D=3D FTRACE_UPDATE_MAKE_NOP) + ret =3D ftrace_modify_code(ip - FTRACE_MCOUNT_TRAMP_OFFSET, + old, call_inst); + else + ret =3D ftrace_modify_code(ip - FTRACE_MCOUNT_TRAMP_OFFSET, + call_inst, old); + } + + if (ret) + goto out; + } } =20 out: @@ -217,15 +274,62 @@ int ftrace_init_nop(struct module *mod, struct dyn_ft= race *rec) { unsigned long addr, ip =3D rec->ip; ppc_inst_t old, new; - int ret =3D 0; + int i, ret =3D 0; + u32 ftrace_mcount_tramp_insns[] =3D { +#ifdef CONFIG_PPC64 + PPC_RAW_BRANCH(FTRACE_MCOUNT_TRAMP_OFFSET + MCOUNT_INSN_SIZE), +#else + PPC_RAW_MFLR(_R0), +#endif + PPC_RAW_BL(0), /* bl ftrace_caller */ + PPC_RAW_MTLR(_R0), /* also see update ppc_function_entry() */ + PPC_RAW_BRANCH(FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE * 2) + }; + + if (!core_kernel_text(ip)) { + if (!mod) { + pr_err("0x%lx: No module provided for non-kernel address\n", ip); + return -EFAULT; + } + rec->arch.mod =3D mod; + } + + if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) { + ip -=3D FTRACE_MCOUNT_TRAMP_OFFSET; + + /* First instruction from the sequence */ + old =3D ppc_inst(PPC_RAW_NOP()); + ret =3D ftrace_modify_code(ip, old, ppc_inst(ftrace_mcount_tramp_insns[0= ])); + ip +=3D MCOUNT_INSN_SIZE; + + /* Default the mcount trampoline to go to ftrace_caller */ + ret |=3D ftrace_get_call_inst(rec, (unsigned long)ftrace_caller, &new); + ret |=3D ftrace_modify_code(ip, old, new); + ip +=3D MCOUNT_INSN_SIZE; + + /* Rest of the instructions from the sequence */ + for (i =3D 2; i < 4; i++, ip +=3D MCOUNT_INSN_SIZE) + ret |=3D ftrace_modify_code(ip, old, ppc_inst(ftrace_mcount_tramp_insns= [i])); + + if (IS_ENABLED(CONFIG_PPC64)) { + /* two more nops */ + ret |=3D ftrace_validate_inst(ip, old); + ip +=3D MCOUNT_INSN_SIZE; + ret |=3D ftrace_validate_inst(ip, old); + ip +=3D MCOUNT_INSN_SIZE; + } else { + ret |=3D ftrace_validate_inst(ip, old); + ip +=3D MCOUNT_INSN_SIZE; + } + + /* nop at ftrace location */ + ret |=3D ftrace_validate_inst(ip, old); + + return ret; + } =20 /* Verify instructions surrounding the ftrace location */ - if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) { - /* Expect nops */ - ret =3D ftrace_validate_inst(ip - 4, ppc_inst(PPC_RAW_NOP())); - if (!ret) - ret =3D ftrace_validate_inst(ip, ppc_inst(PPC_RAW_NOP())); - } else if (IS_ENABLED(CONFIG_PPC32)) { + if (IS_ENABLED(CONFIG_PPC32)) { /* Expected sequence: 'mflr r0', 'stw r0,4(r1)', 'bl _mcount' */ ret =3D ftrace_validate_inst(ip - 8, ppc_inst(PPC_RAW_MFLR(_R0))); if (!ret) @@ -246,23 +350,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ft= race *rec) if (ret) return ret; =20 - if (!core_kernel_text(ip)) { - if (!mod) { - pr_err("0x%lx: No module provided for non-kernel address\n", ip); - return -EFAULT; - } - rec->arch.mod =3D mod; - } - /* Nop-out the ftrace location */ new =3D ppc_inst(PPC_RAW_NOP()); addr =3D MCOUNT_ADDR; - if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) { - /* we instead patch-in the 'mflr r0' */ - old =3D ppc_inst(PPC_RAW_NOP()); - new =3D ppc_inst(PPC_RAW_MFLR(_R0)); - ret =3D ftrace_modify_code(ip - 4, old, new); - } else if (is_offset_in_branch_range(addr - ip)) { + if (is_offset_in_branch_range(addr - ip)) { /* Within range */ old =3D ftrace_create_branch_inst(ip, addr, 1); ret =3D ftrace_modify_code(ip, old, new); diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel= /trace/ftrace_entry.S index 244a1c7bb1e8..537c14b12904 100644 --- a/arch/powerpc/kernel/trace/ftrace_entry.S +++ b/arch/powerpc/kernel/trace/ftrace_entry.S @@ -78,6 +78,14 @@ =20 /* Get the _mcount() call site out of LR */ mflr r7 +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + /* + * This points after the bl at 'mtlr r0', but this sequence could be + * outside the function. Move this to point just after the ftrace + * location inside the function for proper unwind. + */ + addi r7, r7, FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE +#endif /* Save it as pt_regs->nip */ PPC_STL r7, _NIP(r1) /* Also save it in B's stackframe header for proper unwind */ @@ -121,12 +129,18 @@ .macro ftrace_regs_exit allregs /* Load ctr with the possibly modified NIP */ PPC_LL r3, _NIP(r1) - mtctr r3 =20 #ifdef CONFIG_LIVEPATCH_64 cmpd r14, r3 /* has NIP been altered? */ #endif =20 +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + subi r3, r3, FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE + mtlr r3 +#else + mtctr r3 +#endif + /* Restore gprs */ .if \allregs =3D=3D 1 REST_GPRS(2, 31, r1) @@ -139,7 +153,9 @@ =20 /* Restore possibly modified LR */ PPC_LL r0, _LINK(r1) +#ifndef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY mtlr r0 +#endif =20 #ifdef CONFIG_PPC64 /* Restore callee's TOC */ @@ -153,7 +169,12 @@ /* Based on the cmpd above, if the NIP was altered handle livepatc= h */ bne- livepatch_handler #endif - bctr /* jump after _mcount site */ + /* jump after _mcount site */ +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + blr +#else + bctr +#endif .endm =20 _GLOBAL(ftrace_regs_caller) @@ -177,6 +198,11 @@ _GLOBAL(ftrace_stub) =20 #ifdef CONFIG_PPC64 ftrace_no_trace: +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + REST_GPR(3, r1) + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE + blr +#else mflr r3 mtctr r3 REST_GPR(3, r1) @@ -184,6 +210,7 @@ ftrace_no_trace: mtlr r0 bctr #endif +#endif =20 #ifdef CONFIG_LIVEPATCH_64 /* @@ -196,9 +223,9 @@ ftrace_no_trace: * * On entry: * - we have no stack frame and can not allocate one - * - LR points back to the original caller (in A) - * - CTR holds the new NIP in C - * - r0, r11 & r12 are free + * - LR/r0 points back to the original caller (in A) + * - CTR/LR holds the new NIP in C + * - r11 & r12 are free */ livepatch_handler: ld r12, PACA_THREAD_INFO(r13) @@ -208,19 +235,26 @@ livepatch_handler: addi r11, r11, 24 std r11, TI_livepatch_sp(r12) =20 - /* Save toc & real LR on livepatch stack */ - std r2, -24(r11) - mflr r12 - std r12, -16(r11) - /* Store stack end marker */ lis r12, STACK_END_MAGIC@h ori r12, r12, STACK_END_MAGIC@l std r12, -8(r11) =20 + /* Save toc & real LR on livepatch stack */ + std r2, -24(r11) +#ifndef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + mflr r12 + std r12, -16(r11) /* Put ctr in r12 for global entry and branch there */ mfctr r12 bctrl +#else + std r0, -16(r11) + mflr r12 + addi r12, r12, FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE + mtlr r12 + blrl +#endif =20 /* * Now we are returning from the patched function to the original --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C5E29C4167B for ; Fri, 8 Dec 2023 16:36:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1573840AbjLHQgL (ORCPT ); Fri, 8 Dec 2023 11:36:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574444AbjLHQf2 (ORCPT ); Fri, 8 Dec 2023 11:35:28 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C718C199A for ; Fri, 8 Dec 2023 08:35:32 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DE94C433CB; Fri, 8 Dec 2023 16:35:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053332; bh=mcOc029J1BqyWbOqtSlrwAjg5MaAlcqBJsrSldWAf8E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KUFBhlM7PmCPIHyssSqtMtp0iHkXz0NaajpTrYeU7B9HrrgSt6Sze/LesuoHwp5ZK xSB8ZFbckeD9MVLZrmE6MV1S8wu6nUgACwNuyfLZBEnOwnjhChCHrzwKnjuTuXIiFQ jC2gXriHQP89crMlGaYqaRLQ2+ii82w+BUq5++7TccuBh7QoJNxKe70VJlNj+xhLgz nhxvjs7ihyhHZlzHuMTrxQt2wl0jJnbMl0u8buymkdxplPfVzVqIeXthFgA2izpoVO rp4WP3WV7Y12Wb4a1HmJNeSxGaGEu4qcCR9A5ibNTgsMdd+OPLKQ0umsxYjqySGFQt pEBXTz3LJZP6A== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 7/9] powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_CALL_OPS Date: Fri, 8 Dec 2023 22:00:46 +0530 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Implement support for DYNAMIC_FTRACE_WITH_CALL_OPS similar to the arm64 implementation. This works by patching-in a pointer to an associated ftrace_ops structure before each traceable function. If multiple ftrace_ops are associated with a call site, then a special ftrace_list_ops is used to enable iterating over all the registered ftrace_ops. If no ftrace_ops are associated with a call site, then a special ftrace_nop_ops structure is used to render the ftrace call as a no-op. ftrace trampoline can then read the associated ftrace_ops for a call site by loading from an offset from the LR, and branch directly to the associated function. The primary advantage with this approach is that we don't have to iterate over all the registered ftrace_ops for call sites that have a single ftrace_ops registered. This is the equivalent of implementing support for dynamic ftrace trampolines, which set up a special ftrace trampoline for each registered ftrace_ops and have individual call sites branch into those directly. A secondary advantage is that this gives us a way to add support for direct ftrace callers without having to resort to using stubs. The address of the direct call trampoline can be loaded from the ftrace_ops structure. To support this, we utilize the space between the existing function profile sequence and the function entry. During ftrace activation, we update this location with the associated ftrace_ops pointer. Then, on ftrace entry, we load from this location and call into ftrace_ops->func(). For 64-bit powerpc, we also select FUNCTION_ALIGNMENT_8B so that the ftrace_ops pointer is double word aligned and can be updated atomically. Signed-off-by: Naveen N Rao --- arch/powerpc/Kconfig | 2 + arch/powerpc/kernel/asm-offsets.c | 4 ++ arch/powerpc/kernel/trace/ftrace.c | 58 ++++++++++++++++++++++++ arch/powerpc/kernel/trace/ftrace_entry.S | 39 +++++++++++----- 4 files changed, 91 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 318e5c1b7454..c8ecc9dcc914 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -190,6 +190,7 @@ config PPC select EDAC_SUPPORT select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if ARCH_USING_PATCHABLE= _FUNCTION_ENTRY select FUNCTION_ALIGNMENT_4B + select FUNCTION_ALIGNMENT_8B if PPC64 && DYNAMIC_FTRACE_WITH_CALL_OPS select GENERIC_ATOMIC64 if PPC32 select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_CMOS_UPDATE @@ -233,6 +234,7 @@ config PPC select HAVE_DEBUG_STACKOVERFLOW select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_ARGS if ARCH_USING_PATCHABLE_FUNCTION_ENT= RY || MPROFILE_KERNEL || PPC32 + select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if ARCH_USING_PATCHABLE_FUNCTION= _ENTRY select HAVE_DYNAMIC_FTRACE_WITH_REGS if ARCH_USING_PATCHABLE_FUNCTION_ENT= RY || MPROFILE_KERNEL || PPC32 select HAVE_EBPF_JIT select HAVE_EFFICIENT_UNALIGNED_ACCESS diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-of= fsets.c index 9f14d95b8b32..8b8a39b57a9f 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -676,5 +676,9 @@ int main(void) DEFINE(BPT_SIZE, BPT_SIZE); #endif =20 +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS + OFFSET(FTRACE_OPS_FUNC, ftrace_ops, func); +#endif + return 0; } diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace= /ftrace.c index d3b4949142a8..af84eabf7912 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -124,6 +124,41 @@ static int ftrace_get_call_inst(struct dyn_ftrace *rec= , unsigned long addr, ppc_ return 0; } =20 +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS +static const struct ftrace_ops *powerpc_rec_get_ops(struct dyn_ftrace *rec) +{ + const struct ftrace_ops *ops =3D NULL; + + if (rec->flags & FTRACE_FL_CALL_OPS_EN) { + ops =3D ftrace_find_unique_ops(rec); + WARN_ON_ONCE(!ops); + } + + if (!ops) + ops =3D &ftrace_list_ops; + + return ops; +} + +static int ftrace_rec_set_ops(const struct dyn_ftrace *rec, const struct f= trace_ops *ops) +{ + return patch_ulong((void *)(rec->ip - sizeof(unsigned long)), (unsigned l= ong)ops); +} + +static int ftrace_rec_set_nop_ops(struct dyn_ftrace *rec) +{ + return ftrace_rec_set_ops(rec, &ftrace_nop_ops); +} + +static int ftrace_rec_update_ops(struct dyn_ftrace *rec) +{ + return ftrace_rec_set_ops(rec, powerpc_rec_get_ops(rec)); +} +#else +static int ftrace_rec_set_nop_ops(struct dyn_ftrace *rec) { return 0; } +static int ftrace_rec_update_ops(struct dyn_ftrace *rec) { return 0; } +#endif + #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, uns= igned long addr) { @@ -159,6 +194,10 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned = long addr) if (ret || !IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) return ret; =20 + ret =3D ftrace_rec_update_ops(rec); + if (ret) + return ret; + ip =3D rec->ip; ret =3D ftrace_modify_code(ip, ppc_inst(PPC_RAW_NOP()), ppc_inst(PPC_RAW_BRANCH(-FTRACE_MCOUNT_TRAMP_OFFSET))); @@ -214,16 +253,19 @@ void ftrace_replace_code(int enable) case FTRACE_UPDATE_MODIFY_CALL: ret =3D ftrace_get_call_inst(rec, new_addr, &new_call_inst); ret |=3D ftrace_get_call_inst(rec, addr, &call_inst); + ret |=3D ftrace_rec_update_ops(rec); old =3D call_inst; new =3D new_call_inst; break; case FTRACE_UPDATE_MAKE_NOP: ret =3D ftrace_get_call_inst(rec, addr, &call_inst); + ret |=3D ftrace_rec_set_nop_ops(rec); old =3D call_inst; new =3D nop_inst; break; case FTRACE_UPDATE_MAKE_CALL: ret =3D ftrace_get_call_inst(rec, new_addr, &call_inst); + ret |=3D ftrace_rec_update_ops(rec); old =3D nop_inst; new =3D call_inst; break; @@ -312,6 +354,12 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftr= ace *rec) ret |=3D ftrace_modify_code(ip, old, ppc_inst(ftrace_mcount_tramp_insns= [i])); =20 if (IS_ENABLED(CONFIG_PPC64)) { + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS) && + !IS_ALIGNED(ip, sizeof(unsigned long))) { + pr_err("0x%lx: Mis-aligned ftrace_ops patch site\n", ip); + return -EINVAL; + } + /* two more nops */ ret |=3D ftrace_validate_inst(ip, old); ip +=3D MCOUNT_INSN_SIZE; @@ -325,6 +373,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftra= ce *rec) /* nop at ftrace location */ ret |=3D ftrace_validate_inst(ip, old); =20 + if (!ret) + ret =3D ftrace_rec_set_nop_ops(rec); + return ret; } =20 @@ -383,6 +434,13 @@ int ftrace_update_ftrace_func(ftrace_func_t func) ppc_inst_t old, new; int ret; =20 + /* + * When using CALL_OPS, the function to call is associated with the + * call site, and we don't have a global function pointer to update. + */ + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS)) + return 0; + old =3D ppc_inst_read((u32 *)&ftrace_call); new =3D ftrace_create_branch_inst(ip, ppc_function_entry(func), 1); ret =3D ftrace_modify_code(ip, old, new); diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel= /trace/ftrace_entry.S index 537c14b12904..4d1220c2e32f 100644 --- a/arch/powerpc/kernel/trace/ftrace_entry.S +++ b/arch/powerpc/kernel/trace/ftrace_entry.S @@ -97,11 +97,6 @@ /* Save callee's TOC in the ABI compliant location */ std r2, STK_GOT(r1) LOAD_PACA_TOC() /* get kernel TOC in r2 */ - LOAD_REG_ADDR(r3, function_trace_op) - ld r5,0(r3) -#else - lis r3,function_trace_op@ha - lwz r5,function_trace_op@l(r3) #endif =20 #ifdef CONFIG_LIVEPATCH_64 @@ -177,20 +172,40 @@ #endif .endm =20 -_GLOBAL(ftrace_regs_caller) - ftrace_regs_entry 1 - /* ftrace_call(r3, r4, r5, r6) */ +.macro ftrace_regs_func allregs +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS + PPC_LL r5, -SZL(r3) + PPC_LL r12, FTRACE_OPS_FUNC(r5) + mtctr r12 + bctrl +#else +#ifdef CONFIG_PPC64 + LOAD_REG_ADDR(r5, function_trace_op) + ld r5, 0(r5) +#else + lis r5, function_trace_op@ha + lwz r5, function_trace_op@l(r5) +#endif + .if \allregs =3D=3D 1 .globl ftrace_regs_call ftrace_regs_call: + .else +.globl ftrace_call +ftrace_call: + .endif + /* ftrace_call(r3, r4, r5, r6) */ bl ftrace_stub +#endif +.endm + +_GLOBAL(ftrace_regs_caller) + ftrace_regs_entry 1 + ftrace_regs_func 1 ftrace_regs_exit 1 =20 _GLOBAL(ftrace_caller) ftrace_regs_entry 0 - /* ftrace_call(r3, r4, r5, r6) */ -.globl ftrace_call -ftrace_call: - bl ftrace_stub + ftrace_regs_func 0 ftrace_regs_exit 0 =20 _GLOBAL(ftrace_stub) --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14196C4167B for ; Fri, 8 Dec 2023 16:36:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574096AbjLHQgV (ORCPT ); Fri, 8 Dec 2023 11:36:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574469AbjLHQfc (ORCPT ); Fri, 8 Dec 2023 11:35:32 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7ED1319B3 for ; Fri, 8 Dec 2023 08:35:37 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 97072C433C8; Fri, 8 Dec 2023 16:35:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053337; bh=7raJIERHI+frfy4evcCjXbQCBLrz7+ndhekYbkUWCw8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ucggwy5F5BZXz172PhI07i2kTcoe04uwSX7QNPhw2P4840kQPSngfiErOdWEZVZUf 8T76BRVjSRpjIIU9xWEIo8pMG3XrF3vBB3vODslqGDQ2vY283eRo8d9c1KBSpQaQnn VUNhDQVCQR8kVKY1Hje9m5HxyBmBJELQ1OwdZaTl2b2ogywS4CFPwZC33E7WCdnS8m eyvRbf9C0z970RJOqzOUyc7lcK0vJ9Y7pDV5pvaqEEZLMzYrMLyIkhnFsL4Tl7DVOi 4yAMhNA/Idh3RtTl3h2SrraGMtbcBDfSTVXNghBw9OZNZFWT7rQJm83AGQK9WBHtKp UPBXMaKW9yzig== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 8/9] powerpc/ftrace: Add support for DYNAMIC_FTRACE_WITH_DIRECT_CALLS Date: Fri, 8 Dec 2023 22:00:47 +0530 Message-ID: <62b7c2fcaca546c790a825cf79b9cced1ac8d1db.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add support for DYNAMIC_FTRACE_WITH_DIRECT_CALLS similar to the arm64 implementation. ftrace direct calls allow custom trampolines to be called into directly from function ftrace call sites, bypassing the ftrace trampoline completely. This functionality is currently utilized by BPF trampolines to hook into kernel function entries. Since we have limited relative branch range, we support ftrace direct calls through support for DYNAMIC_FTRACE_WITH_CALL_OPS. In this approach, ftrace trampoline is not entirely bypassed. Rather, it is re-purposed into a stub that reads direct_call field from the associated ftrace_ops structure and branches into that, if it is not NULL. For this, it is sufficient if we can ensure that the ftrace trampoline is reachable from all traceable functions. When multiple ftrace_ops are associated with a call site, we utilize a call back to set pt_regs->orig_gpr3 that can then be tested on the return path from the ftrace trampoline to branch into the direct caller. Signed-off-by: Naveen N Rao --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/ftrace.h | 15 ++++ arch/powerpc/kernel/asm-offsets.c | 3 + arch/powerpc/kernel/trace/ftrace_entry.S | 99 ++++++++++++++++++------ 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c8ecc9dcc914..4fe04fdca33a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -235,6 +235,7 @@ config PPC select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_ARGS if ARCH_USING_PATCHABLE_FUNCTION_ENT= RY || MPROFILE_KERNEL || PPC32 select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if ARCH_USING_PATCHABLE_FUNCTION= _ENTRY + select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_= CALL_OPS select HAVE_DYNAMIC_FTRACE_WITH_REGS if ARCH_USING_PATCHABLE_FUNCTION_ENT= RY || MPROFILE_KERNEL || PPC32 select HAVE_EBPF_JIT select HAVE_EFFICIENT_UNALIGNED_ACCESS diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/f= trace.h index d9b99781bea3..986c4fffb9ec 100644 --- a/arch/powerpc/include/asm/ftrace.h +++ b/arch/powerpc/include/asm/ftrace.h @@ -93,6 +93,21 @@ struct ftrace_ops; #define ftrace_graph_func ftrace_graph_func void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, struct ftrace_ops *op, struct ftrace_regs *fregs); + +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS +/* + * When an ftrace registered caller is tracing a function that is also set= by a + * register_ftrace_direct() call, it needs to be differentiated in the + * ftrace_caller trampoline so that the direct call can be invoked after t= he + * other ftrace ops. To do this, place the direct caller in the orig_gpr3 = field + * of pt_regs. This tells ftrace_caller that there's a direct caller. + */ +static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs= , unsigned long addr) +{ + struct pt_regs *regs =3D &fregs->regs; + regs->orig_gpr3 =3D addr; +} +#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ #endif #endif /* __ASSEMBLY__ */ =20 diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-of= fsets.c index 8b8a39b57a9f..85da10726d98 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -678,6 +678,9 @@ int main(void) =20 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS OFFSET(FTRACE_OPS_FUNC, ftrace_ops, func); +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + OFFSET(FTRACE_OPS_DIRECT_CALL, ftrace_ops, direct_call); +#endif #endif =20 return 0; diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel= /trace/ftrace_entry.S index 4d1220c2e32f..ab60395fc34b 100644 --- a/arch/powerpc/kernel/trace/ftrace_entry.S +++ b/arch/powerpc/kernel/trace/ftrace_entry.S @@ -33,14 +33,57 @@ * and then arrange for the ftrace function to be called. */ .macro ftrace_regs_entry allregs - /* Save the original return address in A's stack frame */ - PPC_STL r0, LRSAVE(r1) /* Create a minimal stack frame for representing B */ PPC_STLU r1, -STACK_FRAME_MIN_SIZE(r1) =20 /* Create our stack frame + pt_regs */ PPC_STLU r1,-SWITCH_FRAME_SIZE(r1) =20 + .if \allregs =3D=3D 1 + SAVE_GPRS(11, 12, r1) + .endif + + /* Get the _mcount() call site out of LR */ + mflr r11 + +#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY + /* + * This points after the bl at 'mtlr r0', but this sequence could be + * outside the function. Move this to point just after the ftrace + * location inside the function for proper unwind. + */ + addi r11, r11, FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE + +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS + /* Load the ftrace_op */ + PPC_LL r12, -SZL-MCOUNT_INSN_SIZE(r11) + +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + /* Load direct_call from the ftrace_op */ + PPC_LL r12, FTRACE_OPS_DIRECT_CALL(r12) + PPC_LCMPI r12, 0 + beq 1f + mtctr r12 + .if \allregs =3D=3D 1 + REST_GPRS(11, 12, r1) + .endif + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE + bctr +1: +#endif +#endif +#endif + + /* Save the previous LR in pt_regs->link */ + PPC_STL r0, _LINK(r1) + /* Also save it in A's stack frame */ + PPC_STL r0, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE+LRSAVE(r1) + + /* Save our return address as pt_regs->nip */ + PPC_STL r11, _NIP(r1) + /* Also save it in B's stackframe header for proper unwind */ + PPC_STL r11, SWITCH_FRAME_SIZE+LRSAVE(r1) + /* Save all gprs to pt_regs */ SAVE_GPR(0, r1) SAVE_GPRS(3, 10, r1) @@ -54,7 +97,7 @@ =20 .if \allregs =3D=3D 1 SAVE_GPR(2, r1) - SAVE_GPRS(11, 31, r1) + SAVE_GPRS(13, 31, r1) .else #ifdef CONFIG_LIVEPATCH_64 SAVE_GPR(14, r1) @@ -65,6 +108,13 @@ addi r8, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE PPC_STL r8, GPR1(r1) =20 +#ifdef CONFIG_LIVEPATCH_64 + mr r14, r11 /* remember old NIP */ +#endif + + /* Calculate ip from nip-4 into r3 for call below */ + subi r3, r11, MCOUNT_INSN_SIZE + .if \allregs =3D=3D 1 /* Load special regs for save below */ mfmsr r8 @@ -76,22 +126,11 @@ li r8, 0 .endif =20 - /* Get the _mcount() call site out of LR */ - mflr r7 -#ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY - /* - * This points after the bl at 'mtlr r0', but this sequence could be - * outside the function. Move this to point just after the ftrace - * location inside the function for proper unwind. - */ - addi r7, r7, FTRACE_MCOUNT_TRAMP_OFFSET - MCOUNT_INSN_SIZE +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + /* Clear orig_gpr3 to later detect ftrace_direct call */ + li r7, 0 + PPC_STL r7, ORIG_GPR3(r1) #endif - /* Save it as pt_regs->nip */ - PPC_STL r7, _NIP(r1) - /* Also save it in B's stackframe header for proper unwind */ - PPC_STL r7, LRSAVE+SWITCH_FRAME_SIZE(r1) - /* Save the read LR in pt_regs->link */ - PPC_STL r0, _LINK(r1) =20 #ifdef CONFIG_PPC64 /* Save callee's TOC in the ABI compliant location */ @@ -99,13 +138,6 @@ LOAD_PACA_TOC() /* get kernel TOC in r2 */ #endif =20 -#ifdef CONFIG_LIVEPATCH_64 - mr r14, r7 /* remember old NIP */ -#endif - - /* Calculate ip from nip-4 into r3 for call below */ - subi r3, r7, MCOUNT_INSN_SIZE - /* Put the original return address in r4 as parent_ip */ mr r4, r0 =20 @@ -122,6 +154,13 @@ .endm =20 .macro ftrace_regs_exit allregs +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + /* Check orig_gpr3 to detect ftrace_direct call */ + PPC_LL r7, ORIG_GPR3(r1) + PPC_LCMPI cr1, r7, 0 + mtctr r7 +#endif + /* Load ctr with the possibly modified NIP */ PPC_LL r3, _NIP(r1) =20 @@ -164,8 +203,12 @@ /* Based on the cmpd above, if the NIP was altered handle livepatc= h */ bne- livepatch_handler #endif + /* jump after _mcount site */ #ifdef CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + bnectr cr1 +#endif blr #else bctr @@ -227,6 +270,12 @@ ftrace_no_trace: #endif #endif =20 +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS +SYM_FUNC_START(ftrace_stub_direct_tramp) + blr +SYM_FUNC_END(ftrace_stub_direct_tramp) +#endif + #ifdef CONFIG_LIVEPATCH_64 /* * This function runs in the mcount context, between two functions. As --=20 2.43.0 From nobody Tue Dec 16 16:35:23 2025 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD1C7C4167B for ; Fri, 8 Dec 2023 16:36:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1574001AbjLHQg1 (ORCPT ); Fri, 8 Dec 2023 11:36:27 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58292 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1574509AbjLHQfk (ORCPT ); Fri, 8 Dec 2023 11:35:40 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 57F5F1BE4 for ; Fri, 8 Dec 2023 08:35:42 -0800 (PST) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2D02EC433C8; Fri, 8 Dec 2023 16:35:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1702053341; bh=/Vr54DRtLZd4aKRU80jRMolyKRZJenT4nAxAfj9vNgU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Kqw5cSnRlXfjEbUQjs6WgIcysAOrhanmR902+VQbClMrPLkXY683HU5mJIYOzkTH3 Yyue4EEiHDrdVsjDxVESagqcPXSMMrn9ULPcPXs0DEBlcDzw1koo1hDb/ldwLf7+dA e4lSJPR3TjZWnnHX0GERGFLrWlb9svcRzxZYBGOShKnRhor2Tqf9WNmRQNeFlBOmT+ /mgGpK6XejchUuv4nmS/e8wkrrD+3+ViY72f1giw+hL5APgTaAmwVfen3vxcjdbjBs 2ELu3e14nWeWdIWRRznQnfFErm2+uXCMBhnQqsoRklEnJGMjFpu9JMgHdvpiT849pE sKPBxbOmYlk0g== From: Naveen N Rao To: , Cc: Michael Ellerman , Nicholas Piggin , Christophe Leroy , "Aneesh Kumar K.V" , Steven Rostedt , Mark Rutland , Florent Revest , Masami Hiramatsu Subject: [RFC PATCH 9/9] samples/ftrace: Add support for ftrace direct samples on powerpc Date: Fri, 8 Dec 2023 22:00:48 +0530 Message-ID: <4735fcdfb8977c6f437796590c0e3cbbf644d0de.1702045299.git.naveen@kernel.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add powerpc 32-bit and 64-bit samples for ftrace direct. This serves to show the sample instruction sequence to be used by ftrace direct calls to adhere to the ftrace ABI. On 64-bit powerpc, TOC setup requires some additional work. Signed-off-by: Naveen N Rao --- arch/powerpc/Kconfig | 2 + samples/ftrace/ftrace-direct-modify.c | 94 ++++++++++++++++- samples/ftrace/ftrace-direct-multi-modify.c | 110 +++++++++++++++++++- samples/ftrace/ftrace-direct-multi.c | 64 +++++++++++- samples/ftrace/ftrace-direct-too.c | 72 ++++++++++++- samples/ftrace/ftrace-direct.c | 61 ++++++++++- 6 files changed, 398 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 4fe04fdca33a..28de3a5f3e98 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -274,6 +274,8 @@ config PPC select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RELIABLE_STACKTRACE select HAVE_RSEQ + select HAVE_SAMPLE_FTRACE_DIRECT if HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS + select HAVE_SAMPLE_FTRACE_DIRECT_MULTI if HAVE_DYNAMIC_FTRACE_WITH_DIRECT= _CALLS select HAVE_SETUP_PER_CPU_AREA if PPC64 select HAVE_SOFTIRQ_ON_OWN_STACK select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-gua= rd=3Dtls -mstack-protector-guard-reg=3Dr2) diff --git a/samples/ftrace/ftrace-direct-modify.c b/samples/ftrace/ftrace-= direct-modify.c index e2a6a69352df..bd985035b937 100644 --- a/samples/ftrace/ftrace-direct-modify.c +++ b/samples/ftrace/ftrace-direct-modify.c @@ -2,7 +2,7 @@ #include #include #include -#ifndef CONFIG_ARM64 +#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32) #include #endif =20 @@ -164,6 +164,98 @@ asm ( =20 #endif /* CONFIG_LOONGARCH */ =20 +#ifdef CONFIG_PPC32 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp1, @function\n" +" .globl my_tramp1\n" +" my_tramp1:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" bl my_direct_func1\n" +" lwz 0, 20(1)\n" +" mtlr 0\n" +" addi 1, 1, 32\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp1, .-my_tramp1\n" + +" .type my_tramp2, @function\n" +" .globl my_tramp2\n" +" my_tramp2:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" bl my_direct_func2\n" +" lwz 0, 20(1)\n" +" mtlr 0\n" +" addi 1, 1, 32\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp2, .-my_tramp2\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp1, @function\n" +" .globl my_tramp1\n" +" my_tramp1:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" bl my_direct_func1\n" +" ld 2, 24(1)\n" +" ld 0, 48(1)\n" +" mtlr 0\n" +" addi 1, 1, 64\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp1, .-my_tramp1\n" + +" .type my_tramp2, @function\n" +" .globl my_tramp2\n" +" my_tramp2:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" bl my_direct_func2\n" +" ld 2, 24(1)\n" +" ld 0, 48(1)\n" +" mtlr 0\n" +" addi 1, 1, 64\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp2, .-my_tramp2\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC64 */ + static struct ftrace_ops direct; =20 static unsigned long my_tramp =3D (unsigned long)my_tramp1; diff --git a/samples/ftrace/ftrace-direct-multi-modify.c b/samples/ftrace/f= trace-direct-multi-modify.c index 2e349834d63c..478e879a23af 100644 --- a/samples/ftrace/ftrace-direct-multi-modify.c +++ b/samples/ftrace/ftrace-direct-multi-modify.c @@ -2,7 +2,7 @@ #include #include #include -#ifndef CONFIG_ARM64 +#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32) #include #endif =20 @@ -184,6 +184,114 @@ asm ( =20 #endif /* CONFIG_LOONGARCH */ =20 +#ifdef CONFIG_PPC32 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp1, @function\n" +" .globl my_tramp1\n" +" my_tramp1:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -24(1)\n" +" stw 3, 16(1)\n" +" mr 3, 0\n" +" addi 3, 3, 16\n" +" bl my_direct_func1\n" +" lwz 3, 16(1)\n" +" lwz 0, 28(1)\n" +" mtlr 0\n" +" addi 1, 1, 40\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp1, .-my_tramp1\n" + +" .type my_tramp2, @function\n" +" .globl my_tramp2\n" +" my_tramp2:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -24(1)\n" +" stw 3, 16(1)\n" +" mr 3, 0\n" +" addi 3, 3, 16\n" +" bl my_direct_func2\n" +" lwz 3, 16(1)\n" +" lwz 0, 28(1)\n" +" mtlr 0\n" +" addi 1, 1, 40\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp2, .-my_tramp2\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp1, @function\n" +" .globl my_tramp1\n" +" my_tramp1:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -48(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" std 3, 32(1)\n" +" mr 3, 0\n" +" addi 3, 3, 20\n" +" bl my_direct_func1\n" +" ld 3, 32(1)\n" +" ld 2, 24(1)\n" +" ld 0, 64(1)\n" +" mtlr 0\n" +" addi 1, 1, 80\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp1, .-my_tramp1\n" + +" .type my_tramp2, @function\n" +" .globl my_tramp2\n" +" my_tramp2:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -48(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" std 3, 32(1)\n" +" mr 3, 0\n" +" addi 3, 3, 20\n" +" bl my_direct_func2\n" +" ld 3, 32(1)\n" +" ld 2, 24(1)\n" +" ld 0, 64(1)\n" +" mtlr 0\n" +" addi 1, 1, 80\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp2, .-my_tramp2\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC64 */ + static unsigned long my_tramp =3D (unsigned long)my_tramp1; static unsigned long tramps[2] =3D { (unsigned long)my_tramp1, diff --git a/samples/ftrace/ftrace-direct-multi.c b/samples/ftrace/ftrace-d= irect-multi.c index 9243dbfe4d0c..558f4ad8d84a 100644 --- a/samples/ftrace/ftrace-direct-multi.c +++ b/samples/ftrace/ftrace-direct-multi.c @@ -4,7 +4,7 @@ #include /* for handle_mm_fault() */ #include #include -#ifndef CONFIG_ARM64 +#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32) #include #endif =20 @@ -116,6 +116,68 @@ asm ( =20 #endif /* CONFIG_LOONGARCH */ =20 +#ifdef CONFIG_PPC32 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -24(1)\n" +" stw 3, 16(1)\n" +" mr 3, 0\n" +" addi 3, 3, 16\n" +" bl my_direct_func\n" +" lwz 3, 16(1)\n" +" lwz 0, 28(1)\n" +" mtlr 0\n" +" addi 1, 1, 40\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -48(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" std 3, 32(1)\n" +" mr 3, 0\n" +" addi 3, 3, 20\n" +" bl my_direct_func\n" +" ld 3, 32(1)\n" +" ld 2, 24(1)\n" +" ld 0, 64(1)\n" +" mtlr 0\n" +" addi 1, 1, 80\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC64 */ + static struct ftrace_ops direct; =20 static int __init ftrace_direct_multi_init(void) diff --git a/samples/ftrace/ftrace-direct-too.c b/samples/ftrace/ftrace-dir= ect-too.c index e39c3563ae4e..2a35b5d88304 100644 --- a/samples/ftrace/ftrace-direct-too.c +++ b/samples/ftrace/ftrace-direct-too.c @@ -3,7 +3,7 @@ =20 #include /* for handle_mm_fault() */ #include -#ifndef CONFIG_ARM64 +#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32) #include #endif =20 @@ -125,6 +125,76 @@ asm ( =20 #endif /* CONFIG_LOONGARCH */ =20 +#ifdef CONFIG_PPC32 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -32(1)\n" +" stw 3, 16(1)\n" +" stw 4, 20(1)\n" +" stw 5, 24(1)\n" +" stw 6, 28(1)\n" +" bl my_direct_func\n" +" lwz 6, 28(1)\n" +" lwz 5, 24(1)\n" +" lwz 4, 20(1)\n" +" lwz 3, 16(1)\n" +" lwz 0, 36(1)\n" +" mtlr 0\n" +" addi 1, 1, 48\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -64(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" std 3, 32(1)\n" +" std 4, 40(1)\n" +" std 5, 48(1)\n" +" std 6, 56(1)\n" +" bl my_direct_func\n" +" ld 6, 56(1)\n" +" ld 5, 48(1)\n" +" ld 4, 40(1)\n" +" ld 3, 32(1)\n" +" ld 2, 24(1)\n" +" ld 0, 80(1)\n" +" mtlr 0\n" +" addi 1, 1, 96\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC64 */ + static struct ftrace_ops direct; =20 static int __init ftrace_direct_init(void) diff --git a/samples/ftrace/ftrace-direct.c b/samples/ftrace/ftrace-direct.c index 32c477da1e9a..5585ffb6dd41 100644 --- a/samples/ftrace/ftrace-direct.c +++ b/samples/ftrace/ftrace-direct.c @@ -3,7 +3,7 @@ =20 #include /* for wake_up_process() */ #include -#ifndef CONFIG_ARM64 +#if !defined(CONFIG_ARM64) && !defined(CONFIG_PPC32) #include #endif =20 @@ -110,6 +110,65 @@ asm ( =20 #endif /* CONFIG_LOONGARCH */ =20 +#ifdef CONFIG_PPC32 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" stw 0, 4(1)\n" +" stwu 1, -16(1)\n" +" mflr 0\n" +" stw 0, 4(1)\n" +" stwu 1, -24(1)\n" +" stw 3, 16(1)\n" +" bl my_direct_func\n" +" lwz 3, 16(1)\n" +" lwz 0, 28(1)\n" +" mtlr 0\n" +" addi 1, 1, 40\n" +" lwz 0, 4(1)\n" +" blr\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC32 */ + +#ifdef CONFIG_PPC64 + +asm ( +" .pushsection .text, \"ax\", @progbits\n" +" .type my_tramp, @function\n" +" .globl my_tramp\n" +" my_tramp:" +" std 0, 16(1)\n" +" stdu 1, -32(1)\n" +" mflr 0\n" +" std 0, 16(1)\n" +" stdu 1, -48(1)\n" +" std 2, 24(1)\n" +" bcl 20, 31, 1f\n" +" 1: mflr 12\n" +" ld 2, (2f - 1b)(12)\n" +" std 3, 32(1)\n" +" bl my_direct_func\n" +" ld 3, 32(1)\n" +" ld 2, 24(1)\n" +" ld 0, 64(1)\n" +" mtlr 0\n" +" addi 1, 1, 80\n" +" ld 0, 16(1)\n" +" blr\n" +" 2: .quad .TOC.@tocbase\n" +" .size my_tramp, .-my_tramp\n" +" .popsection\n" +); + +#endif /* CONFIG_PPC64 */ + + static struct ftrace_ops direct; =20 static int __init ftrace_direct_init(void) --=20 2.43.0