From nobody Mon Feb 9 06:13:43 2026 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 7835DC433FE for ; Tue, 15 Nov 2022 02:57:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237771AbiKOC5Q (ORCPT ); Mon, 14 Nov 2022 21:57:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237725AbiKOC4x (ORCPT ); Mon, 14 Nov 2022 21:56:53 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id ECED4167D0 for ; Mon, 14 Nov 2022 18:55:32 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8DxTtui_3JjZx8HAA--.21438S3; Tue, 15 Nov 2022 10:55:30 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S3; Tue, 15 Nov 2022 10:55:29 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Jinyang He Subject: [PATCH v6 1/9] LoongArch/ftrace: Add basic support Date: Tue, 15 Nov 2022 10:55:19 +0800 Message-Id: <20221115025527.13382-2-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S3 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoW3GFW5ZF1kXr1rGr1fXr1fZwb_yoW3ZF1DpF Zay3WkG397GFsakrWS9r15urn8Jws7Wry2qa9FyryFkFsFqr1rZwn2yryqqF97t397CrWI ga4fGr42kF45XwUanT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b3kYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jrv_JF1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2Iq xVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r 126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_JFI_Gr1lIxAIcVC0I7IYx2IY 6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67 AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x 07jz2NtUUUUU= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch contains basic ftrace support for LoongArch. Specifically, function tracer (HAVE_FUNCTION_TRACER), function graph tracer (HAVE_FUNCTION_GRAPH_TRACER) are implemented following the instructions in Documentation/trace/ftrace-design.txt. Use `-pg` makes stub like a child function `void _mcount(void *ra)`. Thus, it can be seen store RA and open stack before `call _mcount`. Find `open stack` at first, and then find `store RA` Note that the functions in both inst.c and time.c should not be hooked with the compiler's -pg option: to prevent infinite self- referencing for the former, and to ignore early setup stuff for the latter. Co-developed-by: Jinyang He Signed-off-by: Jinyang He Signed-off-by: Qing Zhang --- arch/loongarch/Kconfig | 2 + arch/loongarch/Makefile | 5 ++ arch/loongarch/include/asm/ftrace.h | 18 ++++++ arch/loongarch/kernel/Makefile | 8 +++ arch/loongarch/kernel/ftrace.c | 74 +++++++++++++++++++++++ arch/loongarch/kernel/mcount.S | 94 +++++++++++++++++++++++++++++ 6 files changed, 201 insertions(+) create mode 100644 arch/loongarch/include/asm/ftrace.h create mode 100644 arch/loongarch/kernel/ftrace.c create mode 100644 arch/loongarch/kernel/mcount.S diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 1943f840e494..92c4ec8c8527 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -91,6 +91,8 @@ config LOONGARCH select HAVE_EBPF_JIT select HAVE_EXIT_THREAD select HAVE_FAST_GUP + select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_FUNCTION_TRACER select HAVE_GENERIC_VDSO select HAVE_IOREMAP_PROT select HAVE_IRQ_EXIT_ON_IRQ_STACK diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index a0fc1f9980e3..6832a8f891fd 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -36,6 +36,11 @@ ifneq ($(SUBARCH),$(ARCH)) endif endif =20 +ifdef CONFIG_DYNAMIC_FTRACE +KBUILD_CPPFLAGS +=3D -DCC_USING_PATCHABLE_FUNCTION_ENTRY +CC_FLAGS_FTRACE :=3D -fpatchable-function-entry=3D2 +endif + ifdef CONFIG_64BIT ld-emul =3D $(64bit-emul) cflags-y +=3D -mabi=3Dlp64s diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/a= sm/ftrace.h new file mode 100644 index 000000000000..6a3e76234618 --- /dev/null +++ b/arch/loongarch/include/asm/ftrace.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 Loongson Technology Corporation Limited + */ + +#ifndef _ASM_LOONGARCH_FTRACE_H +#define _ASM_LOONGARCH_FTRACE_H + +#ifdef CONFIG_FUNCTION_TRACER +#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void _mcount(void); +#define mcount _mcount + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_FUNCTION_TRACER */ +#endif /* _ASM_LOONGARCH_FTRACE_H */ diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index 86744531b100..3f71bce1c7ce 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -15,6 +15,14 @@ obj-$(CONFIG_EFI) +=3D efi.o =20 obj-$(CONFIG_CPU_HAS_FPU) +=3D fpu.o =20 +ifdef CONFIG_FUNCTION_TRACER +obj-y +=3D mcount.o ftrace.o +CFLAGS_REMOVE_ftrace.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_inst.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_time.o =3D $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_perf_event.o =3D $(CC_FLAGS_FTRACE) +endif + obj-$(CONFIG_MODULES) +=3D module.o module-sections.o obj-$(CONFIG_STACKTRACE) +=3D stacktrace.o =20 diff --git a/arch/loongarch/kernel/ftrace.c b/arch/loongarch/kernel/ftrace.c new file mode 100644 index 000000000000..c8ddc5f11f32 --- /dev/null +++ b/arch/loongarch/kernel/ftrace.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Loongson Technology Corporation Limited + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + +/* + * As `call _mcount` follows LoongArch psABI, ra-saved operation and + * stack operation can be found before this insn. + */ + +static int ftrace_get_parent_ra_addr(unsigned long insn_addr, int *ra_off) +{ + union loongarch_instruction *insn; + int limit =3D 32; + + insn =3D (union loongarch_instruction *)insn_addr; + + do { + insn--; + limit--; + + if (is_ra_save_ins(insn)) + *ra_off =3D -((1 << 12) - insn->reg2i12_format.immediate); + + } while (!is_stack_alloc_ins(insn) && limit); + + if (!limit) + return -EINVAL; + + return 0; +} + +void prepare_ftrace_return(unsigned long self_addr, + unsigned long callsite_sp, unsigned long old) +{ + int ra_off; + unsigned long return_hooker =3D (unsigned long)&return_to_handler; + + if (unlikely(ftrace_graph_is_dead())) + return; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + if (ftrace_get_parent_ra_addr(self_addr, &ra_off)) + goto out; + + if (!function_graph_enter(old, self_addr, 0, NULL)) + *(unsigned long *)(callsite_sp + ra_off) =3D return_hooker; + + return; + +out: + ftrace_graph_stop(); + WARN_ON(1); +} +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/loongarch/kernel/mcount.S b/arch/loongarch/kernel/mcount.S new file mode 100644 index 000000000000..3de7c2d7fd12 --- /dev/null +++ b/arch/loongarch/kernel/mcount.S @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * LoongArch specific _mcount support + * + * Copyright (C) 2022 Loongson Technology Corporation Limited + */ + +#include +#include +#include +#include + + .text + +#define MCOUNT_STACK_SIZE (2 * SZREG) +#define MCOUNT_S0_OFFSET (0) +#define MCOUNT_RA_OFFSET (SZREG) + + .macro MCOUNT_SAVE_REGS + PTR_ADDI sp, sp, -MCOUNT_STACK_SIZE + PTR_S s0, sp, MCOUNT_S0_OFFSET + PTR_S ra, sp, MCOUNT_RA_OFFSET + move s0, a0 + .endm + + .macro MCOUNT_RESTORE_REGS + move a0, s0 + PTR_L ra, sp, MCOUNT_RA_OFFSET + PTR_L s0, sp, MCOUNT_S0_OFFSET + PTR_ADDI sp, sp, MCOUNT_STACK_SIZE + .endm + + +SYM_FUNC_START(_mcount) + la.pcrel t1, ftrace_stub + la.pcrel t2, ftrace_trace_function /* Prepare t2 for (1) */ + PTR_L t2, t2, 0 + beq t1, t2, fgraph_trace + + MCOUNT_SAVE_REGS + + move a0, ra /* arg0: self return address */ + move a1, s0 /* arg1: parent's return address */ + jirl ra, t2, 0 /* (1) call *ftrace_trace_function */ + + MCOUNT_RESTORE_REGS + +fgraph_trace: +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + la.pcrel t1, ftrace_stub + la.pcrel t3, ftrace_graph_return + PTR_L t3, t3, 0 + bne t1, t3, ftrace_graph_caller + la.pcrel t1, ftrace_graph_entry_stub + la.pcrel t3, ftrace_graph_entry + PTR_L t3, t3, 0 + bne t1, t3, ftrace_graph_caller +#endif + + .globl ftrace_stub +ftrace_stub: + jr ra +SYM_FUNC_END(_mcount) +EXPORT_SYMBOL(_mcount) + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +SYM_FUNC_START(ftrace_graph_caller) + MCOUNT_SAVE_REGS + + PTR_ADDI a0, ra, -4 /* arg0: Callsite self return addr */ + PTR_ADDI a1, sp, MCOUNT_STACK_SIZE /* arg1: Callsite sp */ + move a2, s0 /* arg2: Callsite parent ra */ + bl prepare_ftrace_return + + MCOUNT_RESTORE_REGS + jr ra +SYM_FUNC_END(ftrace_graph_caller) + +SYM_FUNC_START(return_to_handler) + PTR_ADDI sp, sp, -2 * SZREG + PTR_S a0, sp, 0 + PTR_S a1, sp, SZREG + + bl ftrace_return_to_handler + + /* restore the real parent address: a0 -> ra */ + move ra, a0 + + PTR_L a0, sp, 0 + PTR_L a1, sp, SZREG + PTR_ADDI sp, sp, 2 * SZREG + jr ra +SYM_FUNC_END(return_to_handler) +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 84A72C433FE for ; Tue, 15 Nov 2022 02:57:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237774AbiKOC5Z (ORCPT ); Mon, 14 Nov 2022 21:57:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237783AbiKOC45 (ORCPT ); Mon, 14 Nov 2022 21:56:57 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id B14B21EC55 for ; Mon, 14 Nov 2022 18:55:35 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Bxfdqj_3Jjbx8HAA--.21782S3; Tue, 15 Nov 2022 10:55:31 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S4; Tue, 15 Nov 2022 10:55:30 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v6 2/9] LoongArch/ftrace: Add recordmcount support Date: Tue, 15 Nov 2022 10:55:20 +0800 Message-Id: <20221115025527.13382-3-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S4 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxGr4UXFWrZr4xAFy8ury8Zrb_yoW5CrWDpr 4qvFyrJFs2qryfG3ZIy348ur15Zas7Kr4Svryfta1FyFyDXrZ5Gr47JrnrWFyUCrykJ34x WF4F9ry8ua1UJw7anT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b3AYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_JF0_JFyl8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2Iq xVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r 126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY 6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67 AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuY vjxU4OzVUUUUU Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Recordmcount utility under scripts is run, after compiling each object, to find out all the locations of calling _mcount() and put them into specific seciton named __mcount_loc. Then linker collects all such information into a table in the kernel image (between __start_mcount_loc and __stop_mcount_loc) for later use by ftrace. This patch adds loongarch specific definitions to identify such locations. On loongarch, only C version is used to build the kernel now that CONFIG_HAVE_C_RECORDMCOUNT is on. Signed-off-by: Qing Zhang --- arch/loongarch/Kconfig | 2 ++ scripts/recordmcount.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 92c4ec8c8527..e6b1defca1f1 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -86,11 +86,13 @@ config LOONGARCH select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ASM_MODVERSIONS select HAVE_CONTEXT_TRACKING_USER + select HAVE_C_RECORDMCOUNT select HAVE_DEBUG_STACKOVERFLOW select HAVE_DMA_CONTIGUOUS select HAVE_EBPF_JIT select HAVE_EXIT_THREAD select HAVE_FAST_GUP + select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GENERIC_VDSO diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index cce12e1971d8..ae42f9c5dc42 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c @@ -38,6 +38,13 @@ #define R_AARCH64_ABS64 257 #endif =20 +#ifndef EM_LOONGARCH +#define EM_LOONGARCH 258 +#define R_LARCH_64 2 +#define R_LARCH_MARK_LA 20 +#define R_LARCH_SOP_PUSH_PLT_PCREL 29 +#endif + #define R_ARM_PC24 1 #define R_ARM_THM_CALL 10 #define R_ARM_CALL 28 @@ -441,6 +448,17 @@ static int arm64_is_fake_mcount(Elf64_Rel const *rp) return ELF64_R_TYPE(w8(rp->r_info)) !=3D R_AARCH64_CALL26; } =20 +static int LARCH64_is_fake_mcount(Elf64_Rel const *rp) +{ + switch (ELF64_R_TYPE(w(rp->r_info))) { + case R_LARCH_MARK_LA: + case R_LARCH_SOP_PUSH_PLT_PCREL: + return 0; + } + + return 1; +} + /* 64-bit EM_MIPS has weird ELF64_Rela.r_info. * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-= 001.pdf * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.4= 0] @@ -558,6 +576,7 @@ static int do_file(char const *const fname) break; case EM_IA_64: reltype =3D R_IA64_IMM64; break; case EM_MIPS: /* reltype: e_class */ break; + case EM_LOONGARCH: /* reltype: e_class */ break; case EM_PPC: reltype =3D R_PPC_ADDR32; break; case EM_PPC64: reltype =3D R_PPC64_ADDR64; break; case EM_S390: /* reltype: e_class */ break; @@ -610,6 +629,10 @@ static int do_file(char const *const fname) Elf64_r_info =3D MIPS64_r_info; is_fake_mcount64 =3D MIPS64_is_fake_mcount; } + if (w2(ghdr->e_machine) =3D=3D EM_LOONGARCH) { + reltype =3D R_LARCH_64; + is_fake_mcount64 =3D LARCH64_is_fake_mcount; + } if (do64(ghdr, fname, reltype) < 0) goto out; break; --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 1DAF4C4332F for ; Tue, 15 Nov 2022 02:57:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237563AbiKOC5i (ORCPT ); Mon, 14 Nov 2022 21:57:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236406AbiKOC45 (ORCPT ); Mon, 14 Nov 2022 21:56:57 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3595017422 for ; Mon, 14 Nov 2022 18:55:34 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Cxbbej_3JjdB8HAA--.16316S3; Tue, 15 Nov 2022 10:55:31 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S5; Tue, 15 Nov 2022 10:55:30 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Jinyang He Subject: [PATCH v6 3/9] LoongArch/ftrace: Add dynamic function tracer support Date: Tue, 15 Nov 2022 10:55:21 +0800 Message-Id: <20221115025527.13382-4-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S5 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvAXoW3Kr4DKr15Ar1fXFyDKw18uFg_yoW8WrWDto Wa93Wj9r4rGFW29w4Yy3y5GFWjqr10kFZ8Z34ayrn8WF40yry3Xr1UKa15Ka43Jr95Gr43 Cr97uF48JayxXr97n29KB7ZKAUJUUUU7529EdanIXcx71UUUUU7KY7ZEXasCq-sGcSsGvf J3Ic02F40EFcxC0VAKzVAqx4xG6I80ebIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnRJU UU9Fb4IE77IF4wAFF20E14v26r1j6r4UM7CY07I20VC2zVCF04k26cxKx2IYs7xG6rWj6s 0DM7CIcVAFz4kK6r1a6r1DM28lY4IEw2IIxxk0rwA2F7IY1VAKz4vEj48ve4kI8wA2z4x0 Y4vE2Ix0cI8IcVAFwI0_Xr0_Ar1l84ACjcxK6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1l84 ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AKxVW8Jr0_Cr1U M2kKe7AKxVWUXVWUAwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zV CFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUtVWrXwAv7VC2 z280aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw2 8IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v26r1Y6r17MI8I 3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxV WUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26ryj6F1UMIIF0xvE2Ix0cI8I cVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aV AFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZE Xa7IU1xpnPUUUUU== Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The compiler has inserted 2 NOPs before the regular function prologue. T series registers are available and safe because of LoongArch psABI. At runtime, replace nop with bl to enable ftrace call and replace bl with nop to disable ftrace call. The bl requires us to save the original RA value, so here it saves RA at t0. details are: | Compiled | Disabled | Enabled | +------------+------------------------+------------------------+ | nop | move t0, ra | move t0, ra | | nop | nop | bl ftrace_caller | | func_body | func_body | func_body | The RA value will be recovered by ftrace_regs_entry, and restored into RA before returning to the regular function prologue. When a function is not being traced, the move t0, ra is not harmful. 1) ftrace_make_call, ftrace_make_nop (in kernel/ftrace.c) The two functions turn each recorded call site of filtered functions into a call to ftrace_caller or nops. 2) ftracce_update_ftrace_func (in kernel/ftrace.c) turns the nops at ftrace_call into a call to a generic entry for function tracers. 3) ftrace_caller (in kernel/mcount-dyn.S) The entry where each _mcount call sites calls to once they are filtered to be traced. Co-developed-by: Jinyang He Signed-off-by: Jinyang He Signed-off-by: Qing Zhang --- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/ftrace.h | 16 ++++ arch/loongarch/include/asm/inst.h | 15 ++++ arch/loongarch/include/asm/unwind.h | 2 +- arch/loongarch/kernel/Makefile | 5 ++ arch/loongarch/kernel/ftrace_dyn.c | 111 ++++++++++++++++++++++++ arch/loongarch/kernel/inst.c | 92 ++++++++++++++++++++ arch/loongarch/kernel/mcount-dyn.S | 89 +++++++++++++++++++ arch/loongarch/kernel/unwind_prologue.c | 35 ++++++-- 9 files changed, 360 insertions(+), 6 deletions(-) create mode 100644 arch/loongarch/kernel/ftrace_dyn.c create mode 100644 arch/loongarch/kernel/mcount-dyn.S diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index e6b1defca1f1..615ce62422b8 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -89,6 +89,7 @@ config LOONGARCH select HAVE_C_RECORDMCOUNT select HAVE_DEBUG_STACKOVERFLOW select HAVE_DMA_CONTIGUOUS + select HAVE_DYNAMIC_FTRACE select HAVE_EBPF_JIT select HAVE_EXIT_THREAD select HAVE_FAST_GUP diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/a= sm/ftrace.h index 6a3e76234618..76ca58767f4d 100644 --- a/arch/loongarch/include/asm/ftrace.h +++ b/arch/loongarch/include/asm/ftrace.h @@ -10,9 +10,25 @@ #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ =20 #ifndef __ASSEMBLY__ +#ifndef CONFIG_DYNAMIC_FTRACE extern void _mcount(void); #define mcount _mcount +#endif =20 +#ifdef CONFIG_DYNAMIC_FTRACE +static inline unsigned long ftrace_call_adjust(unsigned long addr) +{ + return addr; +} + +struct dyn_arch_ftrace { +}; + +struct dyn_ftrace; +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); +#define ftrace_init_nop ftrace_init_nop + +#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #endif /* _ASM_LOONGARCH_FTRACE_H */ diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm= /inst.h index a52913787183..0ec775d39ca5 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -11,6 +11,9 @@ #define INSN_NOP 0x03400000 #define INSN_BREAK 0x002a0000 =20 +#define INSN_NOP 0x03400000 +#define INSN_BREAK 0x002a0000 + #define ADDR_IMMMASK_LU52ID 0xFFF0000000000000 #define ADDR_IMMMASK_LU32ID 0x000FFFFF00000000 #define ADDR_IMMMASK_ADDU16ID 0x00000000FFFF0000 @@ -349,6 +352,18 @@ static inline bool is_stack_alloc_ins(union loongarch_= instruction *ip) is_imm12_negative(ip->reg2i12_format.immediate); } =20 +int larch_insn_read(void *addr, u32 *insnp); +int larch_insn_write(void *addr, u32 insn); +int larch_insn_patch_text(void *addr, u32 insn); + +u32 larch_insn_gen_nop(void); +u32 larch_insn_gen_b(unsigned long pc, unsigned long dest); +u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest); + +u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, + enum loongarch_gpr rk); +u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj); + u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm); u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, in= t imm); u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsi= gned long pc, unsigned long dest); diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/a= sm/unwind.h index 6af4718bdf01..a51eec00efb8 100644 --- a/arch/loongarch/include/asm/unwind.h +++ b/arch/loongarch/include/asm/unwind.h @@ -20,7 +20,7 @@ struct unwind_state { char type; /* UNWINDER_XXX */ struct stack_info stack_info; struct task_struct *task; - bool first, error; + bool first, error, is_ftrace; unsigned long sp, pc, ra; }; =20 diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index 3f71bce1c7ce..c5e2bfd8247d 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -16,8 +16,13 @@ obj-$(CONFIG_EFI) +=3D efi.o obj-$(CONFIG_CPU_HAS_FPU) +=3D fpu.o =20 ifdef CONFIG_FUNCTION_TRACER +ifndef CONFIG_DYNAMIC_FTRACE obj-y +=3D mcount.o ftrace.o CFLAGS_REMOVE_ftrace.o =3D $(CC_FLAGS_FTRACE) +else +obj-y +=3D mcount-dyn.o ftrace_dyn.o +CFLAGS_REMOVE_ftrace_dyn.o =3D $(CC_FLAGS_FTRACE) +endif CFLAGS_REMOVE_inst.o =3D $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_time.o =3D $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_perf_event.o =3D $(CC_FLAGS_FTRACE) diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftr= ace_dyn.c new file mode 100644 index 000000000000..1f8955be8b64 --- /dev/null +++ b/arch/loongarch/kernel/ftrace_dyn.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Based on arch/arm64/kernel/ftrace.c + * + * Copyright (C) 2022 Loongson Technology Corporation Limited + */ + +#include +#include + +#include + +static int ftrace_modify_code(unsigned long pc, u32 old, u32 new, + bool validate) +{ + u32 replaced; + + if (validate) { + if (larch_insn_read((void *)pc, &replaced)) + return -EFAULT; + + if (replaced !=3D old) + return -EINVAL; + } + + if (larch_insn_patch_text((void *)pc, new)) + return -EPERM; + + return 0; +} + +int ftrace_update_ftrace_func(ftrace_func_t func) +{ + unsigned long pc; + u32 new; + + pc =3D (unsigned long)&ftrace_call; + new =3D larch_insn_gen_bl(pc, (unsigned long)func); + + return ftrace_modify_code(pc, 0, new, false); +} + +/* + * The compiler has inserted 2 NOPs before the regular function prologue. + * T series registers are available and safe because of LoongArch psABI. + * + * At runtime, replace nop with bl to enable ftrace call and replace bl wi= th + * nop to disable ftrace call. The bl requires us to save the original RA = value, + * so here it saves RA at t0. + * details are: + * + * | Compiled | Disabled | Enabled | + * +------------+------------------------+------------------------+ + * | nop | move t0, ra | move t0, ra | + * | nop | nop | bl ftrace_caller | + * | func_body | func_body | func_body | + * + * The RA value will be recovered by ftrace_regs_entry, and restored into = RA + * before returning to the regular function prologue. When a function is n= ot + * being traced, the move t0, ra is not harmful. + */ + +int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) +{ + unsigned long pc; + u32 old, new; + + pc =3D rec->ip; + old =3D larch_insn_gen_nop(); + new =3D larch_insn_gen_move(LOONGARCH_GPR_T0, LOONGARCH_GPR_RA); + + return ftrace_modify_code(pc, old, new, true); +} + +int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) +{ + unsigned long pc; + u32 old, new; + + pc =3D rec->ip + LOONGARCH_INSN_SIZE; + + old =3D larch_insn_gen_nop(); + new =3D larch_insn_gen_bl(pc, addr); + + return ftrace_modify_code(pc, old, new, true); +} + +int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, + unsigned long addr) +{ + unsigned long pc; + u32 old, new; + + pc =3D rec->ip + LOONGARCH_INSN_SIZE; + + new =3D larch_insn_gen_nop(); + old =3D larch_insn_gen_bl(pc, addr); + + return ftrace_modify_code(pc, old, new, true); +} + +void arch_ftrace_update_code(int command) +{ + command |=3D FTRACE_MAY_SLEEP; + ftrace_modify_all_code(command); +} + +int __init ftrace_dyn_arch_init(void) +{ + return 0; +} diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index b1df0ec34bd1..d62cdf4a9ffb 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -2,8 +2,83 @@ /* * Copyright (C) 2020-2022 Loongson Technology Corporation Limited */ +#include +#include + +#include #include =20 +static DEFINE_RAW_SPINLOCK(patch_lock); + +int larch_insn_read(void *addr, u32 *insnp) +{ + int ret; + u32 val; + + ret =3D copy_from_kernel_nofault(&val, addr, LOONGARCH_INSN_SIZE); + if (!ret) + *insnp =3D val; + + return ret; +} + +int larch_insn_write(void *addr, u32 insn) +{ + int ret; + unsigned long flags =3D 0; + + raw_spin_lock_irqsave(&patch_lock, flags); + ret =3D copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE); + raw_spin_unlock_irqrestore(&patch_lock, flags); + + return ret; +} + +int larch_insn_patch_text(void *addr, u32 insn) +{ + int ret; + u32 *tp =3D addr; + + if ((unsigned long)tp & 3) + return -EINVAL; + + ret =3D larch_insn_write(tp, insn); + if (!ret) + flush_icache_range((unsigned long)tp, + (unsigned long)tp + LOONGARCH_INSN_SIZE); + + return ret; +} + +u32 larch_insn_gen_nop(void) +{ + return INSN_NOP; +} + +u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest) +{ + unsigned int immediate_l, immediate_h; + union loongarch_instruction insn; + long offset =3D dest - pc; + + if ((offset & 3) || offset < -SZ_128M || offset >=3D SZ_128M) { + pr_warn("The generated bl instruction is out of range.\n"); + return INSN_BREAK; + } + + offset >>=3D 2; + + immediate_l =3D offset & 0xffff; + offset >>=3D 16; + immediate_h =3D offset & 0x3ff; + + insn.reg0i26_format.opcode =3D bl_op; + insn.reg0i26_format.immediate_l =3D immediate_l; + insn.reg0i26_format.immediate_h =3D immediate_h; + + return insn.word; +} + u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm) { union loongarch_instruction insn; @@ -38,3 +113,20 @@ u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loo= ngarch_gpr rj, unsigned l =20 return insn.word; } + +u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum l= oongarch_gpr rk) +{ + union loongarch_instruction insn; + + insn.reg3_format.opcode =3D or_op; + insn.reg3_format.rd =3D rd; + insn.reg3_format.rj =3D rj; + insn.reg3_format.rk =3D rk; + + return insn.word; +} + +u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj) +{ + return larch_insn_gen_or(rd, rj, 0); +} diff --git a/arch/loongarch/kernel/mcount-dyn.S b/arch/loongarch/kernel/mco= unt-dyn.S new file mode 100644 index 000000000000..205925bc3822 --- /dev/null +++ b/arch/loongarch/kernel/mcount-dyn.S @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 Loongson Technology Corporation Limited + */ + +#include +#include +#include +#include + + .text +/* + * Due to -fpatchable-function-entry=3D2: the compiler inserted 2 NOPs bef= ore the + * regular C function prologue. When PC arrived here, the last 2 instructi= ons + * as follows, + * move t0, ra + * bl callsite (for modules, callsite is a tramplione) + * + * modules tramplione as follows, + * lu12i.w t1, callsite[31:12] + * lu32i.d t1, callsite[51:32] + * lu52i.d t1, t1, callsite[63:52] + * jirl zero, t1, callsite[11:0] >> 2 + * + * See arch/loongarch/kernel/ftrace_dyn.c for details. Here, pay attention= to + * that the T series regs are available and safe because each C functions + * follows the LoongArch psABI well. + */ + + .macro ftrace_regs_entry + PTR_ADDI sp, sp, -PT_SIZE + /* Save trace function ra at PT_ERA */ + PTR_S ra, sp, PT_ERA + /* Save parent ra at PT_R1(RA) */ + PTR_S t0, sp, PT_R1 + PTR_S a0, sp, PT_R4 + PTR_S a1, sp, PT_R5 + PTR_S a2, sp, PT_R6 + PTR_S a3, sp, PT_R7 + PTR_S a4, sp, PT_R8 + PTR_S a5, sp, PT_R9 + PTR_S a6, sp, PT_R10 + PTR_S a7, sp, PT_R11 + PTR_S fp, sp, PT_R22 + + PTR_ADDI t8, sp, PT_SIZE + PTR_S t8, sp, PT_R3 + + .endm + +SYM_CODE_START(ftrace_caller) + ftrace_regs_entry + b ftrace_common +SYM_CODE_END(ftrace_caller) + +SYM_CODE_START(ftrace_common) + PTR_ADDI a0, ra, -8 /* arg0: ip */ + move a1, t0 /* arg1: parent_ip */ + la.pcrel t1, function_trace_op + PTR_L a2, t1, 0 /* arg2: op */ + move a3, sp /* arg3: regs */ + .globl ftrace_call +ftrace_call: + bl ftrace_stub +/* + * As we didn't use S series regs in this assmembly code and all calls + * are C function which will save S series regs by themselves, there is + * no need to restore S series regs. The T series is available and safe + * at the callsite, so there is no need to restore the T series regs. + */ +ftrace_common_return: + PTR_L a0, sp, PT_R4 + PTR_L a1, sp, PT_R5 + PTR_L a2, sp, PT_R6 + PTR_L a3, sp, PT_R7 + PTR_L a4, sp, PT_R8 + PTR_L a5, sp, PT_R9 + PTR_L a6, sp, PT_R10 + PTR_L a7, sp, PT_R11 + PTR_L fp, sp, PT_R22 + PTR_L ra, sp, PT_R1 + PTR_L t0, sp, PT_ERA + PTR_ADDI sp, sp, PT_SIZE + jr t0 +SYM_CODE_END(ftrace_common) + +SYM_FUNC_START(ftrace_stub) + jr ra +SYM_FUNC_END(ftrace_stub) diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kerne= l/unwind_prologue.c index b206d9159205..c5df4ae73e0d 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -13,9 +13,7 @@ unsigned long unwind_get_return_address(struct unwind_sta= te *state) =20 if (unwind_done(state)) return 0; - else if (state->type) - return state->pc; - else if (state->first) + else if (state->type || state->first) return state->pc; =20 return *(unsigned long *)(state->sp); @@ -39,16 +37,41 @@ static bool unwind_by_guess(struct unwind_state *state) return false; } =20 +static inline void unwind_state_fixup(struct unwind_state *state) +{ +#ifdef CONFIG_DYNAMIC_FTRACE + static unsigned long ftrace_case =3D (unsigned long)ftrace_call + 4; + + if (state->pc =3D=3D ftrace_case) + state->is_ftrace =3D true; +#endif +} + static bool unwind_by_prologue(struct unwind_state *state) { struct stack_info *info =3D &state->stack_info; union loongarch_instruction *ip, *ip_end; unsigned long frame_size =3D 0, frame_ra =3D -1; unsigned long size, offset, pc =3D state->pc; + struct pt_regs *regs; =20 if (state->sp >=3D info->end || state->sp < info->begin) return false; =20 + if (state->is_ftrace) { + /* + * As we meet ftrace_regs_entry, reset first flag like first doing + * tracing, Prologue analysis will stop soon because PC is at entry. + */ + regs =3D (struct pt_regs *)state->sp; + state->pc =3D regs->csr_era; + state->ra =3D regs->regs[1]; + state->sp =3D regs->regs[3]; + state->first =3D true; + state->is_ftrace =3D false; + return true; + } + if (!kallsyms_lookup_size_offset(pc, &size, &offset)) return false; =20 @@ -94,7 +117,7 @@ static bool unwind_by_prologue(struct unwind_state *stat= e) =20 state->pc =3D *(unsigned long *)(state->sp + frame_ra); state->sp =3D state->sp + frame_size; - return !!__kernel_text_address(state->pc); + goto out; =20 first: state->first =3D false; @@ -103,7 +126,9 @@ static bool unwind_by_prologue(struct unwind_state *sta= te) =20 state->pc =3D state->ra; =20 - return !!__kernel_text_address(state->ra); +out: + unwind_state_fixup(state); + return !!__kernel_text_address(state->pc); } =20 void unwind_start(struct unwind_state *state, struct task_struct *task, --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 494D9C43217 for ; Tue, 15 Nov 2022 02:57:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236343AbiKOC5V (ORCPT ); Mon, 14 Nov 2022 21:57:21 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38516 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237765AbiKOC44 (ORCPT ); Mon, 14 Nov 2022 21:56:56 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 3A4EE1A3AA for ; Mon, 14 Nov 2022 18:55:34 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8AxDdmj_3Jjdh8HAA--.21030S3; Tue, 15 Nov 2022 10:55:31 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S6; Tue, 15 Nov 2022 10:55:31 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Jinyang He Subject: [PATCH v6 4/9] LoongArch/ftrace: Add dynamic function graph tracer support Date: Tue, 15 Nov 2022 10:55:22 +0800 Message-Id: <20221115025527.13382-5-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S6 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxGF4DAF1DKw4rGFWUtw4UXFb_yoWrKFyDpr y2y3ZxtrWjkFsakr9Igw4DXrW5J393W342qanrtryrCwsFqF13Aw1xA34qqFyaqw4UCryS vayrAr4jka1UXa7anT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b3AYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_JF0_JFyl8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2Iq xVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r 126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY 6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67 AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuY vjxU4OzVUUUUU Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Once the function_graph tracer is enabled, a filtered function has the following call sequence: 1) ftracer_caller =3D=3D> on/off by ftrace_make_call/ftrace_make_nop 2) ftrace_graph_caller 3) ftrace_graph_call =3D=3D> on/off by ftrace_en/disable_ftrace_graph_call= er 4) prepare_ftrace_return Considering the following DYNAMIC_FTRACE_WITH_REGS feature, it would be more extendable to have a ftrace_graph_caller function, instead of calling prepare_ftrace_return directly in ftrace_caller. Co-developed-by: Jinyang He Signed-off-by: Jinyang He Signed-off-by: Qing Zhang --- arch/loongarch/kernel/ftrace_dyn.c | 45 ++++++++++++++++++++++++++++++ arch/loongarch/kernel/inst.c | 24 ++++++++++++++++ arch/loongarch/kernel/mcount-dyn.S | 33 ++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftr= ace_dyn.c index 1f8955be8b64..3fe791b6783e 100644 --- a/arch/loongarch/kernel/ftrace_dyn.c +++ b/arch/loongarch/kernel/ftrace_dyn.c @@ -109,3 +109,48 @@ int __init ftrace_dyn_arch_init(void) { return 0; } + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +extern void ftrace_graph_call(void); + +void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent) +{ + unsigned long return_hooker =3D (unsigned long)&return_to_handler; + unsigned long old; + + if (unlikely(atomic_read(¤t->tracing_graph_pause))) + return; + + old =3D *parent; + + if (!function_graph_enter(old, self_addr, 0, NULL)) + *parent =3D return_hooker; +} + +static int ftrace_modify_graph_caller(bool enable) +{ + unsigned long pc, func; + u32 branch, nop; + + pc =3D (unsigned long)&ftrace_graph_call; + func =3D (unsigned long)&ftrace_graph_caller; + + branch =3D larch_insn_gen_b(pc, func); + nop =3D larch_insn_gen_nop(); + + if (enable) + return ftrace_modify_code(pc, nop, branch, true); + else + return ftrace_modify_code(pc, branch, nop, true); +} + +int ftrace_enable_ftrace_graph_caller(void) +{ + return ftrace_modify_graph_caller(true); +} + +int ftrace_disable_ftrace_graph_caller(void) +{ + return ftrace_modify_graph_caller(false); +} +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index d62cdf4a9ffb..2d2e942eb06a 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -55,6 +55,30 @@ u32 larch_insn_gen_nop(void) return INSN_NOP; } =20 +u32 larch_insn_gen_b(unsigned long pc, unsigned long dest) +{ + unsigned int immediate_l, immediate_h; + union loongarch_instruction insn; + long offset =3D dest - pc; + + if ((offset & 3) || offset < -SZ_128M || offset >=3D SZ_128M) { + pr_warn("The generated b instruction is out of range.\n"); + return INSN_BREAK; + } + + offset >>=3D 2; + + immediate_l =3D offset & 0xffff; + offset >>=3D 16; + immediate_h =3D offset & 0x3ff; + + insn.reg0i26_format.opcode =3D b_op; + insn.reg0i26_format.immediate_l =3D immediate_l; + insn.reg0i26_format.immediate_h =3D immediate_h; + + return insn.word; +} + u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest) { unsigned int immediate_l, immediate_h; diff --git a/arch/loongarch/kernel/mcount-dyn.S b/arch/loongarch/kernel/mco= unt-dyn.S index 205925bc3822..0c12cc108e6f 100644 --- a/arch/loongarch/kernel/mcount-dyn.S +++ b/arch/loongarch/kernel/mcount-dyn.S @@ -62,6 +62,11 @@ SYM_CODE_START(ftrace_common) .globl ftrace_call ftrace_call: bl ftrace_stub +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + .globl ftrace_graph_call +ftrace_graph_call: + nop /* b ftrace_graph_caller */ +#endif /* * As we didn't use S series regs in this assmembly code and all calls * are C function which will save S series regs by themselves, there is @@ -84,6 +89,34 @@ ftrace_common_return: jr t0 SYM_CODE_END(ftrace_common) =20 +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +SYM_CODE_START(ftrace_graph_caller) + PTR_L a0, sp, PT_ERA + PTR_ADDI a0, a0, -8 /* arg0: self_addr */ + PTR_ADDI a1, sp, PT_R1 /* arg1: parent */ + bl prepare_ftrace_return + b ftrace_common_return +SYM_CODE_END(ftrace_graph_caller) + +SYM_CODE_START(return_to_handler) + /* save return value regs */ + PTR_ADDI sp, sp, -2 * SZREG + PTR_S a0, sp, 0 + PTR_S a1, sp, SZREG + + move a0, zero /* Has no check FP now. */ + bl ftrace_return_to_handler + move ra, a0 /* parent ra */ + + /* restore return value regs */ + PTR_L a0, sp, 0 + PTR_L a1, sp, SZREG + PTR_ADDI sp, sp, 2 * SZREG + + jr ra +SYM_CODE_END(return_to_handler) +#endif + SYM_FUNC_START(ftrace_stub) jr ra SYM_FUNC_END(ftrace_stub) --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 E24D7C4332F for ; Tue, 15 Nov 2022 02:57:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237792AbiKOC5d (ORCPT ); Mon, 14 Nov 2022 21:57:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232592AbiKOC45 (ORCPT ); Mon, 14 Nov 2022 21:56:57 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id B151E1EC56 for ; Mon, 14 Nov 2022 18:55:35 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Axz7ek_3Jjex8HAA--.16482S3; Tue, 15 Nov 2022 10:55:32 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S7; Tue, 15 Nov 2022 10:55:31 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org, Jinyang He Subject: [PATCH v6 5/9] LoongArch/ftrace: Add DYNAMIC_FTRACE_WITH_REGS support Date: Tue, 15 Nov 2022 10:55:23 +0800 Message-Id: <20221115025527.13382-6-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S7 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxCF43Gry5Zr1ktr17XFWUJwb_yoWrWw1Dpr 97Arn5GFWj9FsagrWfK3s5Wrs8JrWvg34ava9rAFyrGr4qqF15Z3y8Cr1DZFyIq3yxG3yx XF1fCr4Yya17XwUanT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b3AYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jrv_JF1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26r1q6rW5McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2Iq xVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r 126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY 6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67 AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuY vjxU4AhLUUUUU Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch implements DYNAMIC_FTRACE_WITH_REGS on LoongArch, which allows a traced function's arguments (and some other registers) to be captured into a struct pt_regs, allowing these to be inspected and modified. Co-developed-by: Jinyang He Signed-off-by: Jinyang He Signed-off-by: Qing Zhang --- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/ftrace.h | 3 +++ arch/loongarch/kernel/ftrace_dyn.c | 17 ++++++++++++++ arch/loongarch/kernel/mcount-dyn.S | 36 +++++++++++++++++++++++++++-- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 615ce62422b8..12e3e91a68ae 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -90,6 +90,7 @@ config LOONGARCH select HAVE_DEBUG_STACKOVERFLOW select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_EBPF_JIT select HAVE_EXIT_THREAD select HAVE_FAST_GUP diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/a= sm/ftrace.h index 76ca58767f4d..a3f974a7a5ce 100644 --- a/arch/loongarch/include/asm/ftrace.h +++ b/arch/loongarch/include/asm/ftrace.h @@ -28,6 +28,9 @@ struct dyn_ftrace; int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); #define ftrace_init_nop ftrace_init_nop =20 +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +#define ARCH_SUPPORTS_FTRACE_OPS 1 +#endif #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftr= ace_dyn.c index 3fe791b6783e..ec3d951be50c 100644 --- a/arch/loongarch/kernel/ftrace_dyn.c +++ b/arch/loongarch/kernel/ftrace_dyn.c @@ -99,6 +99,23 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrac= e *rec, return ftrace_modify_code(pc, old, new, true); } =20 +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, + unsigned long addr) +{ + unsigned long pc; + long offset; + u32 old, new; + + pc =3D rec->ip + LOONGARCH_INSN_SIZE; + + old =3D larch_insn_gen_bl(pc, old_addr); + new =3D larch_insn_gen_bl(pc, addr); + + return ftrace_modify_code(pc, old, new, true); +} +#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ + void arch_ftrace_update_code(int command) { command |=3D FTRACE_MAY_SLEEP; diff --git a/arch/loongarch/kernel/mcount-dyn.S b/arch/loongarch/kernel/mco= unt-dyn.S index 0c12cc108e6f..02835186b463 100644 --- a/arch/loongarch/kernel/mcount-dyn.S +++ b/arch/loongarch/kernel/mcount-dyn.S @@ -27,7 +27,7 @@ * follows the LoongArch psABI well. */ =20 - .macro ftrace_regs_entry + .macro ftrace_regs_entry allregs=3D0 PTR_ADDI sp, sp, -PT_SIZE /* Save trace function ra at PT_ERA */ PTR_S ra, sp, PT_ERA @@ -43,16 +43,48 @@ PTR_S a7, sp, PT_R11 PTR_S fp, sp, PT_R22 =20 + .if \allregs + PTR_S t0, sp, PT_R12 + PTR_S t1, sp, PT_R13 + PTR_S t2, sp, PT_R14 + PTR_S t3, sp, PT_R15 + PTR_S t4, sp, PT_R16 + PTR_S t5, sp, PT_R17 + PTR_S t6, sp, PT_R18 + PTR_S t7, sp, PT_R19 + PTR_S t8, sp, PT_R20 + PTR_S s0, sp, PT_R23 + PTR_S s1, sp, PT_R24 + PTR_S s2, sp, PT_R25 + PTR_S s3, sp, PT_R26 + PTR_S s4, sp, PT_R27 + PTR_S s5, sp, PT_R28 + PTR_S s6, sp, PT_R29 + PTR_S s7, sp, PT_R30 + PTR_S s8, sp, PT_R31 + PTR_S tp, sp, PT_R2 + /* Clear it for later use as a flag sometimes. */ + PTR_S zero, sp, PT_R0 + PTR_S $r21, sp, PT_R21 + .endif + PTR_ADDI t8, sp, PT_SIZE PTR_S t8, sp, PT_R3 =20 .endm =20 SYM_CODE_START(ftrace_caller) - ftrace_regs_entry + ftrace_regs_entry allregs=3D0 b ftrace_common SYM_CODE_END(ftrace_caller) =20 +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS +SYM_CODE_START(ftrace_regs_caller) + ftrace_regs_entry allregs=3D1 + b ftrace_common +SYM_CODE_END(ftrace_regs_caller) +#endif + SYM_CODE_START(ftrace_common) PTR_ADDI a0, ra, -8 /* arg0: ip */ move a1, t0 /* arg1: parent_ip */ --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 B20E5C4332F for ; Tue, 15 Nov 2022 02:57:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237458AbiKOC5r (ORCPT ); Mon, 14 Nov 2022 21:57:47 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235613AbiKOC5A (ORCPT ); Mon, 14 Nov 2022 21:57:00 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7DBE11EC63 for ; Mon, 14 Nov 2022 18:55:37 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Dx_Nik_3JjgB8HAA--.21143S3; Tue, 15 Nov 2022 10:55:32 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S8; Tue, 15 Nov 2022 10:55:32 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v6 6/9] LoongArch/ftrace: Add HAVE_DYNAMIC_FTRACE_WITH_ARGS support Date: Tue, 15 Nov 2022 10:55:24 +0800 Message-Id: <20221115025527.13382-7-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S8 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxZrW3XFW3WrykGFWrWw13XFb_yoW5AF1DpF yIy3Z8JF47uFsa9asF9Fy5Wrs8Xr97u34avayxJa4rAF1DXFyUZr1xAr1DXFyUt3s7GrWI vFyrKwnIkF45X3JanT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b3AYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jrv_JF1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26rWY6Fy7McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2Iq xVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r 126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY 6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67 AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuY vjxUVCD7UUUUU Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Allow for arguments to be passed in to ftrace_regs by default, If this is set, then arguments and stack can be found from the pt_regs. 1. HAVE_DYNAMIC_FTRACE_WITH_ARGS don't need special hook for graph tracer entry point, but instead we can use graph_ops::func function to install the return_hooker. 2. Livepatch requires this option in the future. Signed-off-by: Qing Zhang --- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/ftrace.h | 17 +++++++++++++++++ arch/loongarch/kernel/ftrace_dyn.c | 12 ++++++++++++ 3 files changed, 30 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 12e3e91a68ae..5c4f1dc87f84 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -90,6 +90,7 @@ config LOONGARCH select HAVE_DEBUG_STACKOVERFLOW select HAVE_DMA_CONTIGUOUS select HAVE_DYNAMIC_FTRACE + select HAVE_DYNAMIC_FTRACE_WITH_ARGS select HAVE_DYNAMIC_FTRACE_WITH_REGS select HAVE_EBPF_JIT select HAVE_EXIT_THREAD diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/a= sm/ftrace.h index a3f974a7a5ce..5cc13ae48164 100644 --- a/arch/loongarch/include/asm/ftrace.h +++ b/arch/loongarch/include/asm/ftrace.h @@ -15,6 +15,23 @@ extern void _mcount(void); #define mcount _mcount #endif =20 +#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS +struct ftrace_ops; + +struct ftrace_regs { + struct pt_regs regs; +}; + +static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_= regs *fregs) +{ + return &fregs->regs; +} + +void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *op, struct ftrace_regs *fregs); +#define ftrace_graph_func ftrace_graph_func +#endif + #ifdef CONFIG_DYNAMIC_FTRACE static inline unsigned long ftrace_call_adjust(unsigned long addr) { diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftr= ace_dyn.c index ec3d951be50c..f538829312d7 100644 --- a/arch/loongarch/kernel/ftrace_dyn.c +++ b/arch/loongarch/kernel/ftrace_dyn.c @@ -144,6 +144,17 @@ void prepare_ftrace_return(unsigned long self_addr, un= signed long *parent) *parent =3D return_hooker; } =20 +#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS +void ftrace_graph_func(unsigned long ip, unsigned long parent_ip, + struct ftrace_ops *op, struct ftrace_regs *fregs) +{ + struct pt_regs *regs =3D &fregs->regs; + unsigned long *parent =3D (unsigned long *)®s->regs[1]; + + prepare_ftrace_return(ip, (unsigned long *)parent); +} +#else + static int ftrace_modify_graph_caller(bool enable) { unsigned long pc, func; @@ -170,4 +181,5 @@ int ftrace_disable_ftrace_graph_caller(void) { return ftrace_modify_graph_caller(false); } +#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 74642C433FE for ; Tue, 15 Nov 2022 02:57:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237834AbiKOC5v (ORCPT ); Mon, 14 Nov 2022 21:57:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39026 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237459AbiKOC5B (ORCPT ); Mon, 14 Nov 2022 21:57:01 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 929CD1EC64 for ; Mon, 14 Nov 2022 18:55:37 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Bx37el_3JjhR8HAA--.16416S3; Tue, 15 Nov 2022 10:55:33 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S9; Tue, 15 Nov 2022 10:55:32 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v6 7/9] LoongArch/ftrace: Add HAVE_FUNCTION_GRAPH_RET_ADDR_PTR support Date: Tue, 15 Nov 2022 10:55:25 +0800 Message-Id: <20221115025527.13382-8-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S9 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxAr43CF45Zr4xCr1fZr4ktFb_yoWrKFyUpF 9xCas5GrWxGF9agrnFqr1j9r4kGrn7Cw1agasFy34FkFsFqFy7Wrn2vryqqF4kt3ykWrWI g3Z5G390ka1UX3JanT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU b3AYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_Jrv_JF1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26rWY6Fy7McIj6I8E 87Iv67AKxVW8JVWxJwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41l42xK82 IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1l4IxYO2xFxVAFwI0_Jrv_JF1lx2Iq xVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r 126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Xr0_Ar1lIxAIcVC0I7IYx2IY 6xkF7I0E14v26r4j6F4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67 AKxVW8JVWxJwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73UjIFyTuY vjxUVCD7UUUUU Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Ftrace_graph_ret_addr can be called by stack unwinding code to convert a found stack return address ('ret') to its original value, in case the function graph tracer has modified it to be 'return_to_handler',If the hasn't been modified, the unchanged value of 'ret' is returned. Signed-off-by: Qing Zhang --- arch/loongarch/include/asm/ftrace.h | 3 +++ arch/loongarch/include/asm/unwind.h | 1 + arch/loongarch/kernel/ftrace_dyn.c | 2 +- arch/loongarch/kernel/unwind_guess.c | 4 +++- arch/loongarch/kernel/unwind_prologue.c | 11 +++++++++-- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/a= sm/ftrace.h index 5cc13ae48164..1583ec2171fc 100644 --- a/arch/loongarch/include/asm/ftrace.h +++ b/arch/loongarch/include/asm/ftrace.h @@ -6,6 +6,8 @@ #ifndef _ASM_LOONGARCH_FTRACE_H #define _ASM_LOONGARCH_FTRACE_H =20 +#define GRAPH_FAKE_OFFSET (sizeof(struct pt_regs) - offsetof(struct pt_reg= s, regs[1])) + #ifdef CONFIG_FUNCTION_TRACER #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ =20 @@ -33,6 +35,7 @@ void ftrace_graph_func(unsigned long ip, unsigned long pa= rent_ip, #endif =20 #ifdef CONFIG_DYNAMIC_FTRACE +#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR static inline unsigned long ftrace_call_adjust(unsigned long addr) { return addr; diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/a= sm/unwind.h index a51eec00efb8..f2b52b9ea93d 100644 --- a/arch/loongarch/include/asm/unwind.h +++ b/arch/loongarch/include/asm/unwind.h @@ -21,6 +21,7 @@ struct unwind_state { struct stack_info stack_info; struct task_struct *task; bool first, error, is_ftrace; + int graph_idx; unsigned long sp, pc, ra; }; =20 diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftr= ace_dyn.c index f538829312d7..cd64887e26b5 100644 --- a/arch/loongarch/kernel/ftrace_dyn.c +++ b/arch/loongarch/kernel/ftrace_dyn.c @@ -140,7 +140,7 @@ void prepare_ftrace_return(unsigned long self_addr, uns= igned long *parent) =20 old =3D *parent; =20 - if (!function_graph_enter(old, self_addr, 0, NULL)) + if (!function_graph_enter(old, self_addr, 0, parent)) *parent =3D return_hooker; } =20 diff --git a/arch/loongarch/kernel/unwind_guess.c b/arch/loongarch/kernel/u= nwind_guess.c index 5afa6064d73e..229ba014cea0 100644 --- a/arch/loongarch/kernel/unwind_guess.c +++ b/arch/loongarch/kernel/unwind_guess.c @@ -2,6 +2,7 @@ /* * Copyright (C) 2022 Loongson Technology Corporation Limited */ +#include #include =20 #include @@ -53,7 +54,8 @@ bool unwind_next_frame(struct unwind_state *state) state->sp < info->end; state->sp +=3D sizeof(unsigned long)) { addr =3D *(unsigned long *)(state->sp); - + state->pc =3D ftrace_graph_ret_addr(state->task, &state->graph_idx, + addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); if (__kernel_text_address(addr)) return true; } diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kerne= l/unwind_prologue.c index c5df4ae73e0d..48f7a120ec27 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -2,6 +2,7 @@ /* * Copyright (C) 2022 Loongson Technology Corporation Limited */ +#include #include =20 #include @@ -30,6 +31,8 @@ static bool unwind_by_guess(struct unwind_state *state) state->sp < info->end; state->sp +=3D sizeof(unsigned long)) { addr =3D *(unsigned long *)(state->sp); + state->pc =3D ftrace_graph_ret_addr(state->task, &state->graph_idx, + addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); if (__kernel_text_address(addr)) return true; } @@ -171,8 +174,11 @@ bool unwind_next_frame(struct unwind_state *state) break; =20 case UNWINDER_PROLOGUE: - if (unwind_by_prologue(state)) + if (unwind_by_prologue(state)) { + state->pc =3D ftrace_graph_ret_addr(state->task, &state->graph_idx, + state->pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); return true; + } =20 if (info->type =3D=3D STACK_TYPE_IRQ && info->end =3D=3D state->sp) { @@ -182,8 +188,9 @@ bool unwind_next_frame(struct unwind_state *state) if (user_mode(regs) || !__kernel_text_address(pc)) return false; =20 - state->pc =3D pc; state->sp =3D regs->regs[3]; + state->pc =3D ftrace_graph_ret_addr(state->task, &state->graph_idx, + pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); state->ra =3D regs->regs[1]; state->first =3D true; get_stack_info(state->sp, state->task, info); --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 D6E71C4332F for ; Tue, 15 Nov 2022 02:58:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232165AbiKOC6L (ORCPT ); Mon, 14 Nov 2022 21:58:11 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236990AbiKOC5F (ORCPT ); Mon, 14 Nov 2022 21:57:05 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 30E621EC78 for ; Mon, 14 Nov 2022 18:55:39 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8Dxu9im_3JjjR8HAA--.21168S3; Tue, 15 Nov 2022 10:55:34 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S10; Tue, 15 Nov 2022 10:55:33 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v6 8/9] LoongArch: modules/ftrace: Initialize PLT at load time Date: Tue, 15 Nov 2022 10:55:26 +0800 Message-Id: <20221115025527.13382-9-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S10 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWfGF47Jr13WF1UJFW8ZF17GFg_yoWDKF1kpF yqywn5GrWUGFn3Wa4v9wn8ur15GFZ7W342gFW3G34akw42qry5AF10kr90yFy0qws8uFWS ga1fur4j9FW7Xw7anT9S1TB71UUUUjUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj qI5I8CrVACY4xI64kE6c02F40Ex7xfYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUU baxYFVCjjxCrM7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s 1l1IIY67AEw4v_JF0_JFyl8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1l84 ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AKxVW8Jr0_Cr1U M2kKe7AKxVWUXVWUAwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zV CFFI0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWrXVW3AwAv7VC2 z280aVAFwI0_Cr0_Gr1UMcvjeVCFs4IE7xkEbVWUJVW8JwACjcxG0xvY0x0EwIxGrwCF04 k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwCFI7km07C267AKxVWUXVWUAwC2 0s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI 0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVW7JVWDJwCI42IY6xIIjxv2 0xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2js IE14v26r4j6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZF pf9x07j2ApnUUUUU= Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" To Implement ftrace trampiones through plt entry. Tested by forcing ftrace_make_call() to use the module PLT, and then loading up a module after setting up ftrace with: | echo ":mod:" > set_ftrace_filter; | echo function > current_tracer; | modprobe Since FTRACE_ADDR/FTRACE_REGS_ADDR is only defined when CONFIG_DYNAMIC_FTRA= CE is selected, we wrap its use along with most of module_init_ftrace_plt() wi= th ifdeffery rather than using IS_ENABLED(). Signed-off-by: Qing Zhang --- arch/loongarch/include/asm/ftrace.h | 4 ++ arch/loongarch/include/asm/inst.h | 3 + arch/loongarch/include/asm/module.h | 5 +- arch/loongarch/include/asm/module.lds.h | 1 + arch/loongarch/kernel/ftrace_dyn.c | 79 +++++++++++++++++++++++++ arch/loongarch/kernel/inst.c | 11 ++++ arch/loongarch/kernel/module-sections.c | 11 ++++ arch/loongarch/kernel/module.c | 22 +++++++ 8 files changed, 135 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/a= sm/ftrace.h index 1583ec2171fc..8d194f6da8af 100644 --- a/arch/loongarch/include/asm/ftrace.h +++ b/arch/loongarch/include/asm/ftrace.h @@ -8,6 +8,10 @@ =20 #define GRAPH_FAKE_OFFSET (sizeof(struct pt_regs) - offsetof(struct pt_reg= s, regs[1])) =20 +#define FTRACE_PLT_IDX 0 +#define FTRACE_REGS_PLT_IDX 1 +#define NR_FTRACE_PLTS 2 + #ifdef CONFIG_FUNCTION_TRACER #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ =20 diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm= /inst.h index 0ec775d39ca5..3c13fb673f1e 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -16,10 +16,12 @@ =20 #define ADDR_IMMMASK_LU52ID 0xFFF0000000000000 #define ADDR_IMMMASK_LU32ID 0x000FFFFF00000000 +#define ADDR_IMMMASK_LU12IW 0x00000000FFFFF000 #define ADDR_IMMMASK_ADDU16ID 0x00000000FFFF0000 =20 #define ADDR_IMMSHIFT_LU52ID 52 #define ADDR_IMMSHIFT_LU32ID 32 +#define ADDR_IMMSHIFT_LU12IW 12 #define ADDR_IMMSHIFT_ADDU16ID 16 =20 #define ADDR_IMM(addr, INSN) ((addr & ADDR_IMMMASK_##INSN) >> ADDR_IMMSHIF= T_##INSN) @@ -364,6 +366,7 @@ u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loong= arch_gpr rj, enum loongarch_gpr rk); u32 larch_insn_gen_move(enum loongarch_gpr rd, enum loongarch_gpr rj); =20 +u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm); u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm); u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, in= t imm); u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsi= gned long pc, unsigned long dest); diff --git a/arch/loongarch/include/asm/module.h b/arch/loongarch/include/a= sm/module.h index b29b19a46f42..a311cfec2b23 100644 --- a/arch/loongarch/include/asm/module.h +++ b/arch/loongarch/include/asm/module.h @@ -20,6 +20,9 @@ struct mod_arch_specific { struct mod_section got; struct mod_section plt; struct mod_section plt_idx; + + /* for CONFIG_DYNAMIC_FTRACE */ + struct plt_entry *ftrace_trampolines; }; =20 struct got_entry { @@ -49,7 +52,7 @@ static inline struct plt_entry emit_plt_entry(unsigned lo= ng val) { u32 lu12iw, lu32id, lu52id, jirl; =20 - lu12iw =3D (lu12iw_op << 25 | (((val >> 12) & 0xfffff) << 5) | LOONGARCH_= GPR_T1); + lu12iw =3D larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW)); lu32id =3D larch_insn_gen_lu32id(LOONGARCH_GPR_T1, ADDR_IMM(val, LU32ID)); lu52id =3D larch_insn_gen_lu52id(LOONGARCH_GPR_T1, LOONGARCH_GPR_T1, ADDR= _IMM(val, LU52ID)); jirl =3D larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, 0, (val & 0xfff)); diff --git a/arch/loongarch/include/asm/module.lds.h b/arch/loongarch/inclu= de/asm/module.lds.h index a3d1bc0fcc72..438f09d4ccf4 100644 --- a/arch/loongarch/include/asm/module.lds.h +++ b/arch/loongarch/include/asm/module.lds.h @@ -5,4 +5,5 @@ SECTIONS { .got : { BYTE(0) } .plt : { BYTE(0) } .plt.idx : { BYTE(0) } + .ftrace_trampoline : { BYTE(0) } } diff --git a/arch/loongarch/kernel/ftrace_dyn.c b/arch/loongarch/kernel/ftr= ace_dyn.c index cd64887e26b5..b070ce225989 100644 --- a/arch/loongarch/kernel/ftrace_dyn.c +++ b/arch/loongarch/kernel/ftrace_dyn.c @@ -9,6 +9,7 @@ #include =20 #include +#include =20 static int ftrace_modify_code(unsigned long pc, u32 old, u32 new, bool validate) @@ -72,12 +73,63 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftra= ce *rec) return ftrace_modify_code(pc, old, new, true); } =20 +static inline int __get_mod(struct module **mod, unsigned long addr) +{ + preempt_disable(); + *mod =3D __module_text_address(addr); + preempt_enable(); + + if (WARN_ON(!(*mod))) + return -EINVAL; + + return 0; +} + +static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long = addr) +{ + struct plt_entry *plt =3D mod->arch.ftrace_trampolines; + + if (addr =3D=3D FTRACE_ADDR) + return &plt[FTRACE_PLT_IDX]; + if (addr =3D=3D FTRACE_REGS_ADDR && + IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS)) + return &plt[FTRACE_REGS_PLT_IDX]; + + return NULL; +} + +static unsigned long get_plt_addr(struct module *mod, unsigned long addr) +{ + struct plt_entry *plt; + + plt =3D get_ftrace_plt(mod, addr); + if (!plt) { + pr_err("ftrace: no module PLT for %ps\n", (void *)addr); + return -EINVAL; + } + + return (unsigned long)plt; +} + int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { unsigned long pc; + long offset; u32 old, new; =20 pc =3D rec->ip + LOONGARCH_INSN_SIZE; + offset =3D (long)pc - (long)addr; + + if (offset < -SZ_128M || offset >=3D SZ_128M) { + int ret; + struct module *mod; + + ret =3D __get_mod(&mod, pc); + if (ret) + return ret; + + addr =3D get_plt_addr(mod, addr); + } =20 old =3D larch_insn_gen_nop(); new =3D larch_insn_gen_bl(pc, addr); @@ -89,9 +141,22 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftra= ce *rec, unsigned long addr) { unsigned long pc; + long offset; u32 old, new; =20 pc =3D rec->ip + LOONGARCH_INSN_SIZE; + offset =3D (long)pc - (long)addr; + + if (offset < -SZ_128M || offset >=3D SZ_128M) { + int ret; + struct module *mod; + + ret =3D __get_mod(&mod, pc); + if (ret) + return ret; + + addr =3D get_plt_addr(mod, addr); + } =20 new =3D larch_insn_gen_nop(); old =3D larch_insn_gen_bl(pc, addr); @@ -108,6 +173,20 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigne= d long old_addr, u32 old, new; =20 pc =3D rec->ip + LOONGARCH_INSN_SIZE; + offset =3D (long)pc - (long)addr; + + if (offset < -SZ_128M || offset >=3D SZ_128M) { + int ret; + struct module *mod; + + ret =3D __get_mod(&mod, pc); + if (ret) + return ret; + + addr =3D get_plt_addr(mod, addr); + + old_addr =3D get_plt_addr(mod, old_addr); + } =20 old =3D larch_insn_gen_bl(pc, old_addr); new =3D larch_insn_gen_bl(pc, addr); diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 2d2e942eb06a..0d6bd7000ba6 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -103,6 +103,17 @@ u32 larch_insn_gen_bl(unsigned long pc, unsigned long = dest) return insn.word; } =20 +u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm) +{ + union loongarch_instruction insn; + + insn.reg1i20_format.opcode =3D lu12iw_op; + insn.reg1i20_format.rd =3D rd; + insn.reg1i20_format.immediate =3D imm; + + return insn.word; +} + u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm) { union loongarch_instruction insn; diff --git a/arch/loongarch/kernel/module-sections.c b/arch/loongarch/kerne= l/module-sections.c index d296a70b758f..bd1a96691c98 100644 --- a/arch/loongarch/kernel/module-sections.c +++ b/arch/loongarch/kernel/module-sections.c @@ -4,6 +4,7 @@ */ =20 #include +#include #include #include =20 @@ -103,6 +104,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr = *sechdrs, char *secstrings, struct module *mod) { unsigned int i, num_plts =3D 0, num_gots =3D 0; + Elf_Shdr *tramp =3D NULL; =20 /* * Find the empty .plt sections. @@ -114,6 +116,8 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr = *sechdrs, mod->arch.plt.shdr =3D sechdrs + i; else if (!strcmp(secstrings + sechdrs[i].sh_name, ".plt.idx")) mod->arch.plt_idx.shdr =3D sechdrs + i; + else if (!strcmp(secstrings + sechdrs[i].sh_name, ".ftrace_trampoline")) + tramp =3D sechdrs + i; } =20 if (!mod->arch.got.shdr) { @@ -166,5 +170,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr= *sechdrs, mod->arch.plt_idx.num_entries =3D 0; mod->arch.plt_idx.max_entries =3D num_plts; =20 + if (tramp) { + tramp->sh_type =3D SHT_NOBITS; + tramp->sh_flags =3D SHF_EXECINSTR | SHF_ALLOC; + tramp->sh_addralign =3D __alignof__(struct plt_entry); + tramp->sh_size =3D NR_FTRACE_PLTS * sizeof(struct plt_entry); + } + return 0; } diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c index 825fcf77f9e7..a606a0cab968 100644 --- a/arch/loongarch/kernel/module.c +++ b/arch/loongarch/kernel/module.c @@ -10,6 +10,7 @@ =20 #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include =20 static int rela_stack_push(s64 stack_value, s64 *rela_stack, size_t *rela_= stack_top) { @@ -458,6 +460,24 @@ void *module_alloc(unsigned long size) GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, __builtin_return_address(0)); } =20 +static int module_init_ftrace_plt(const Elf_Ehdr *hdr, const Elf_Shdr *sec= hdrs, + struct module *mod) +{ +#ifdef CONFIG_DYNAMIC_FTRACE + struct plt_entry *ftrace_plts; + + ftrace_plts =3D (void *)sechdrs->sh_addr; + + ftrace_plts[FTRACE_PLT_IDX] =3D emit_plt_entry(FTRACE_ADDR); + + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS)) + ftrace_plts[FTRACE_REGS_PLT_IDX] =3D emit_plt_entry(FTRACE_REGS_ADDR); + + mod->arch.ftrace_trampolines =3D ftrace_plts; +#endif + return 0; +} + int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mod) { @@ -467,6 +487,8 @@ int module_finalize(const Elf_Ehdr *hdr, for (s =3D sechdrs, se =3D sechdrs + hdr->e_shnum; s < se; s++) { if (!strcmp(".altinstructions", secstrs + s->sh_name)) apply_alternatives((void *)s->sh_addr, (void *)s->sh_addr + s->sh_size); + if (!strcmp(".ftrace_trampoline", secstrs + s->sh_name)) + return module_init_ftrace_plt(hdr, s, mod); } =20 return 0; --=20 2.36.0 From nobody Mon Feb 9 06:13:43 2026 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 3DEC9C4332F for ; Tue, 15 Nov 2022 02:58:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231438AbiKOC6C (ORCPT ); Mon, 14 Nov 2022 21:58:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237555AbiKOC5C (ORCPT ); Mon, 14 Nov 2022 21:57:02 -0500 Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 759D11EC72 for ; Mon, 14 Nov 2022 18:55:39 -0800 (PST) Received: from loongson.cn (unknown [113.200.148.30]) by gateway (Coremail) with SMTP id _____8AxXbam_3Jjjx8HAA--.9232S3; Tue, 15 Nov 2022 10:55:34 +0800 (CST) Received: from localhost.localdomain (unknown [113.200.148.30]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxLuKf_3JjmywTAA--.51398S11; Tue, 15 Nov 2022 10:55:33 +0800 (CST) From: Qing Zhang To: Huacai Chen , Steven Rostedt , Ingo Molnar Cc: loongarch@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v6 9/9] LoongArch: Enable CONFIG_KALLSYMS_ALL and CONFIG_DEBUG_FS Date: Tue, 15 Nov 2022 10:55:27 +0800 Message-Id: <20221115025527.13382-10-zhangqing@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20221115025527.13382-1-zhangqing@loongson.cn> References: <20221115025527.13382-1-zhangqing@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: AQAAf8CxLuKf_3JjmywTAA--.51398S11 X-CM-SenderInfo: x2kd0wptlqwqxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvdXoW7JryrGFW5Gw1kGF15WF1Dtrb_yoWDGrb_Ja 1agw1Dur48J397uFn7Xw48W3yDA3WUXF1FkFnrXryxZa12gr13GrWDJw15C3WYga4UWrWY vaykAasxCr18tjkaLaAFLSUrUUUU8b8apTn2vfkv8UJUUUU8wcxFpf9Il3svdxBIdaVrn0 xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3UjIYCTnIWjp_UUUY v7kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0rVWrJVCq3w AFIxvE14AKwVWUAVWUZwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84ACjcxK 6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJwA2z4 x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1l n4kS14v26r1Y6r17M2AIxVAIcxkEcVAq07x20xvEncxIr21l57IF6xkI12xvs2x26I8E6x ACxx1l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20xvE14v26rWY6Fy7McIj6I8E 87Iv67AKxVWxJVW8Jr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw2 8IcxkI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMxCIbckI1I0E14v26r1Y6r17MI8I 3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxV WUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26F1j6w1UMIIF0xvE2Ix0cI8I cVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aV AFwI0_Gr0_Cr1lIxAIcVC2z280aVCY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZE Xa7IU0ec_3UUUUU== Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Defaults enable CONFIG_KALLSYMS_ALL and CONFIG_DEBUG_FS to convenient ftrace tests. Signed-off-by: Qing Zhang --- arch/loongarch/configs/loongson3_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/co= nfigs/loongson3_defconfig index 2d4678e6189a..0bbab17609b0 100644 --- a/arch/loongarch/configs/loongson3_defconfig +++ b/arch/loongarch/configs/loongson3_defconfig @@ -34,6 +34,7 @@ CONFIG_SYSFS_DEPRECATED=3Dy CONFIG_RELAY=3Dy CONFIG_BLK_DEV_INITRD=3Dy CONFIG_EXPERT=3Dy +CONFIG_KALLSYMS_ALL=3Dy CONFIG_USERFAULTFD=3Dy CONFIG_PERF_EVENTS=3Dy # CONFIG_COMPAT_BRK is not set @@ -845,6 +846,7 @@ CONFIG_CRYPTO_DEV_VIRTIO=3Dm CONFIG_PRINTK_TIME=3Dy CONFIG_STRIP_ASM_SYMS=3Dy CONFIG_MAGIC_SYSRQ=3Dy +CONFIG_DEBUG_FS=3Dy # CONFIG_SCHED_DEBUG is not set CONFIG_SCHEDSTATS=3Dy # CONFIG_DEBUG_PREEMPT is not set --=20 2.36.0