]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop some 6.13 patches for tracing
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Mar 2025 14:12:30 +0000 (15:12 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Mar 2025 14:12:30 +0000 (15:12 +0100)
Was disabling a config option :(

queue-6.13/fgraph-replace-fgraph_ret_regs-with-ftrace_regs.patch [deleted file]
queue-6.13/fprobe-rewrite-fprobe-on-function-graph-tracer.patch [deleted file]
queue-6.13/fprobe-use-ftrace_regs-in-fprobe-entry-handler.patch [deleted file]
queue-6.13/fprobe-use-ftrace_regs-in-fprobe-exit-handler.patch [deleted file]
queue-6.13/series
queue-6.13/tracing-add-ftrace_fill_perf_regs-for-perf-event.patch [deleted file]
queue-6.13/tracing-add-ftrace_partial_regs-for-converting-ftrac.patch [deleted file]
queue-6.13/tracing-fprobe-events-log-error-for-exceeding-the-nu.patch [deleted file]

diff --git a/queue-6.13/fgraph-replace-fgraph_ret_regs-with-ftrace_regs.patch b/queue-6.13/fgraph-replace-fgraph_ret_regs-with-ftrace_regs.patch
deleted file mode 100644 (file)
index 6682a8c..0000000
+++ /dev/null
@@ -1,766 +0,0 @@
-From 8d08d4ef90d31596e14da03d051eaa3dc100344a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Dec 2024 14:11:55 +0900
-Subject: fgraph: Replace fgraph_ret_regs with ftrace_regs
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit a3ed4157b7d89800a0008de0c9e46a438a5c3745 ]
-
-Use ftrace_regs instead of fgraph_ret_regs for tracing return value
-on function_graph tracer because of simplifying the callback interface.
-
-The CONFIG_HAVE_FUNCTION_GRAPH_RETVAL is also replaced by
-CONFIG_HAVE_FUNCTION_GRAPH_FREGS.
-
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Acked-by: Heiko Carstens <hca@linux.ibm.com>
-Acked-by: Will Deacon <will@kernel.org>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
-Cc: Florent Revest <revest@chromium.org>
-Cc: Martin KaFai Lau <martin.lau@linux.dev>
-Cc: bpf <bpf@vger.kernel.org>
-Cc: Alexei Starovoitov <ast@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Alan Maguire <alan.maguire@oracle.com>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Huacai Chen <chenhuacai@kernel.org>
-Cc: WANG Xuerui <kernel@xen0n.name>
-Cc: Paul Walmsley <paul.walmsley@sifive.com>
-Cc: Palmer Dabbelt <palmer@dabbelt.com>
-Cc: Albert Ou <aou@eecs.berkeley.edu>
-Cc: Vasily Gorbik <gor@linux.ibm.com>
-Cc: Alexander Gordeev <agordeev@linux.ibm.com>
-Cc: Heiko Carstens <hca@linux.ibm.com>
-Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
-Cc: Sven Schnelle <svens@linux.ibm.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: x86@kernel.org
-Cc: "H. Peter Anvin" <hpa@zytor.com>
-Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-Link: https://lore.kernel.org/173518991508.391279.16635322774382197642.stgit@devnote2
-Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Stable-dep-of: db5e228611b1 ("tracing: fprobe-events: Log error for exceeding the number of entry args")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/arm64/Kconfig                  |  1 +
- arch/arm64/include/asm/ftrace.h     | 23 ++++++---------------
- arch/arm64/kernel/asm-offsets.c     | 12 -----------
- arch/arm64/kernel/entry-ftrace.S    | 32 ++++++++++++++++-------------
- arch/loongarch/Kconfig              |  2 +-
- arch/loongarch/include/asm/ftrace.h | 26 ++++-------------------
- arch/loongarch/kernel/asm-offsets.c | 12 -----------
- arch/loongarch/kernel/mcount.S      | 17 ++++++++-------
- arch/loongarch/kernel/mcount_dyn.S  | 14 ++++++-------
- arch/riscv/Kconfig                  |  2 +-
- arch/riscv/include/asm/ftrace.h     | 26 +++++------------------
- arch/riscv/kernel/mcount.S          | 24 ++++++++++++----------
- arch/s390/Kconfig                   |  2 +-
- arch/s390/include/asm/ftrace.h      | 24 +++++++---------------
- arch/s390/kernel/asm-offsets.c      |  6 ------
- arch/s390/kernel/mcount.S           | 12 +++++------
- arch/x86/Kconfig                    |  2 +-
- arch/x86/include/asm/ftrace.h       | 20 ------------------
- arch/x86/kernel/ftrace_32.S         | 13 ++++++------
- arch/x86/kernel/ftrace_64.S         | 17 +++++++--------
- include/linux/ftrace.h              | 12 ++++++++---
- include/linux/ftrace_regs.h         |  2 ++
- kernel/trace/Kconfig                |  4 ++--
- kernel/trace/fgraph.c               | 21 ++++++++-----------
- 24 files changed, 119 insertions(+), 207 deletions(-)
-
-diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
-index 100570a048c5e..5f086777dad9b 100644
---- a/arch/arm64/Kconfig
-+++ b/arch/arm64/Kconfig
-@@ -219,6 +219,7 @@ config ARM64
-       select HAVE_FTRACE_MCOUNT_RECORD
-       select HAVE_FUNCTION_TRACER
-       select HAVE_FUNCTION_ERROR_INJECTION
-+      select HAVE_FUNCTION_GRAPH_FREGS
-       select HAVE_FUNCTION_GRAPH_TRACER
-       select HAVE_FUNCTION_GRAPH_RETVAL
-       select HAVE_GCC_PLUGINS
-diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
-index 5ccff4de7f091..b5fa57b61378e 100644
---- a/arch/arm64/include/asm/ftrace.h
-+++ b/arch/arm64/include/asm/ftrace.h
-@@ -129,6 +129,12 @@ ftrace_override_function_with_return(struct ftrace_regs *fregs)
-       arch_ftrace_regs(fregs)->pc = arch_ftrace_regs(fregs)->lr;
- }
-+static __always_inline unsigned long
-+ftrace_regs_get_frame_pointer(const struct ftrace_regs *fregs)
-+{
-+      return arch_ftrace_regs(fregs)->fp;
-+}
-+
- int ftrace_regs_query_register_offset(const char *name);
- int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
-@@ -186,23 +192,6 @@ static inline bool arch_syscall_match_sym_name(const char *sym,
- #ifndef __ASSEMBLY__
- #ifdef CONFIG_FUNCTION_GRAPH_TRACER
--struct fgraph_ret_regs {
--      /* x0 - x7 */
--      unsigned long regs[8];
--
--      unsigned long fp;
--      unsigned long __unused;
--};
--
--static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->regs[0];
--}
--
--static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->fp;
--}
- void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
-                          unsigned long frame_pointer);
-diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
-index 29bf85dacffe1..eb1a840e4110f 100644
---- a/arch/arm64/kernel/asm-offsets.c
-+++ b/arch/arm64/kernel/asm-offsets.c
-@@ -179,18 +179,6 @@ int main(void)
-   DEFINE(FTRACE_OPS_FUNC,             offsetof(struct ftrace_ops, func));
- #endif
-   BLANK();
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--  DEFINE(FGRET_REGS_X0,                       offsetof(struct fgraph_ret_regs, regs[0]));
--  DEFINE(FGRET_REGS_X1,                       offsetof(struct fgraph_ret_regs, regs[1]));
--  DEFINE(FGRET_REGS_X2,                       offsetof(struct fgraph_ret_regs, regs[2]));
--  DEFINE(FGRET_REGS_X3,                       offsetof(struct fgraph_ret_regs, regs[3]));
--  DEFINE(FGRET_REGS_X4,                       offsetof(struct fgraph_ret_regs, regs[4]));
--  DEFINE(FGRET_REGS_X5,                       offsetof(struct fgraph_ret_regs, regs[5]));
--  DEFINE(FGRET_REGS_X6,                       offsetof(struct fgraph_ret_regs, regs[6]));
--  DEFINE(FGRET_REGS_X7,                       offsetof(struct fgraph_ret_regs, regs[7]));
--  DEFINE(FGRET_REGS_FP,                       offsetof(struct fgraph_ret_regs, fp));
--  DEFINE(FGRET_REGS_SIZE,             sizeof(struct fgraph_ret_regs));
--#endif
- #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-   DEFINE(FTRACE_OPS_DIRECT_CALL,      offsetof(struct ftrace_ops, direct_call));
- #endif
-diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S
-index f0c16640ef215..169ccf600066b 100644
---- a/arch/arm64/kernel/entry-ftrace.S
-+++ b/arch/arm64/kernel/entry-ftrace.S
-@@ -329,24 +329,28 @@ SYM_FUNC_END(ftrace_stub_graph)
-  * @fp is checked against the value passed by ftrace_graph_caller().
-  */
- SYM_CODE_START(return_to_handler)
--      /* save return value regs */
--      sub sp, sp, #FGRET_REGS_SIZE
--      stp x0, x1, [sp, #FGRET_REGS_X0]
--      stp x2, x3, [sp, #FGRET_REGS_X2]
--      stp x4, x5, [sp, #FGRET_REGS_X4]
--      stp x6, x7, [sp, #FGRET_REGS_X6]
--      str x29,    [sp, #FGRET_REGS_FP]        // parent's fp
-+      /* Make room for ftrace_regs */
-+      sub     sp, sp, #FREGS_SIZE
-+
-+      /* Save return value regs */
-+      stp     x0, x1, [sp, #FREGS_X0]
-+      stp     x2, x3, [sp, #FREGS_X2]
-+      stp     x4, x5, [sp, #FREGS_X4]
-+      stp     x6, x7, [sp, #FREGS_X6]
-+
-+      /* Save the callsite's FP */
-+      str     x29, [sp, #FREGS_FP]
-       mov     x0, sp
--      bl      ftrace_return_to_handler        // addr = ftrace_return_to_hander(regs);
-+      bl      ftrace_return_to_handler        // addr = ftrace_return_to_hander(fregs);
-       mov     x30, x0                         // restore the original return address
--      /* restore return value regs */
--      ldp x0, x1, [sp, #FGRET_REGS_X0]
--      ldp x2, x3, [sp, #FGRET_REGS_X2]
--      ldp x4, x5, [sp, #FGRET_REGS_X4]
--      ldp x6, x7, [sp, #FGRET_REGS_X6]
--      add sp, sp, #FGRET_REGS_SIZE
-+      /* Restore return value regs */
-+      ldp     x0, x1, [sp, #FREGS_X0]
-+      ldp     x2, x3, [sp, #FREGS_X2]
-+      ldp     x4, x5, [sp, #FREGS_X4]
-+      ldp     x6, x7, [sp, #FREGS_X6]
-+      add     sp, sp, #FREGS_SIZE
-       ret
- SYM_CODE_END(return_to_handler)
-diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
-index dae3a9104ca65..49f5bfc00e5a1 100644
---- a/arch/loongarch/Kconfig
-+++ b/arch/loongarch/Kconfig
-@@ -137,7 +137,7 @@ config LOONGARCH
-       select HAVE_FTRACE_MCOUNT_RECORD
-       select HAVE_FUNCTION_ARG_ACCESS_API
-       select HAVE_FUNCTION_ERROR_INJECTION
--      select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
-+      select HAVE_FUNCTION_GRAPH_FREGS
-       select HAVE_FUNCTION_GRAPH_TRACER
-       select HAVE_FUNCTION_TRACER
-       select HAVE_GCC_PLUGINS
-diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/asm/ftrace.h
-index 8f13eaeaa3251..ceb3e3d9c0d3d 100644
---- a/arch/loongarch/include/asm/ftrace.h
-+++ b/arch/loongarch/include/asm/ftrace.h
-@@ -57,6 +57,10 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs, unsigned long ip)
-       instruction_pointer_set(&arch_ftrace_regs(fregs)->regs, ip);
- }
-+#undef ftrace_regs_get_frame_pointer
-+#define ftrace_regs_get_frame_pointer(fregs) \
-+      (arch_ftrace_regs(fregs)->regs.regs[22])
-+
- #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);
-@@ -78,26 +82,4 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
- #endif /* CONFIG_FUNCTION_TRACER */
--#ifndef __ASSEMBLY__
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--struct fgraph_ret_regs {
--      /* a0 - a1 */
--      unsigned long regs[2];
--
--      unsigned long fp;
--      unsigned long __unused;
--};
--
--static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->regs[0];
--}
--
--static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->fp;
--}
--#endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
--#endif
--
- #endif /* _ASM_LOONGARCH_FTRACE_H */
-diff --git a/arch/loongarch/kernel/asm-offsets.c b/arch/loongarch/kernel/asm-offsets.c
-index 049c5c3e370cb..8be1c38ad8eb2 100644
---- a/arch/loongarch/kernel/asm-offsets.c
-+++ b/arch/loongarch/kernel/asm-offsets.c
-@@ -280,18 +280,6 @@ static void __used output_pbe_defines(void)
- }
- #endif
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--static void __used output_fgraph_ret_regs_defines(void)
--{
--      COMMENT("LoongArch fgraph_ret_regs offsets.");
--      OFFSET(FGRET_REGS_A0, fgraph_ret_regs, regs[0]);
--      OFFSET(FGRET_REGS_A1, fgraph_ret_regs, regs[1]);
--      OFFSET(FGRET_REGS_FP, fgraph_ret_regs, fp);
--      DEFINE(FGRET_REGS_SIZE, sizeof(struct fgraph_ret_regs));
--      BLANK();
--}
--#endif
--
- static void __used output_kvm_defines(void)
- {
-       COMMENT("KVM/LoongArch Specific offsets.");
-diff --git a/arch/loongarch/kernel/mcount.S b/arch/loongarch/kernel/mcount.S
-index 3015896016a0b..b6850503e061b 100644
---- a/arch/loongarch/kernel/mcount.S
-+++ b/arch/loongarch/kernel/mcount.S
-@@ -79,10 +79,11 @@ SYM_FUNC_START(ftrace_graph_caller)
- SYM_FUNC_END(ftrace_graph_caller)
- SYM_FUNC_START(return_to_handler)
--      PTR_ADDI        sp, sp, -FGRET_REGS_SIZE
--      PTR_S           a0, sp, FGRET_REGS_A0
--      PTR_S           a1, sp, FGRET_REGS_A1
--      PTR_S           zero, sp, FGRET_REGS_FP
-+      /* Save return value regs */
-+      PTR_ADDI        sp, sp, -PT_SIZE
-+      PTR_S           a0, sp, PT_R4
-+      PTR_S           a1, sp, PT_R5
-+      PTR_S           zero, sp, PT_R22
-       move            a0, sp
-       bl              ftrace_return_to_handler
-@@ -90,9 +91,11 @@ SYM_FUNC_START(return_to_handler)
-       /* Restore the real parent address: a0 -> ra */
-       move            ra, a0
--      PTR_L           a0, sp, FGRET_REGS_A0
--      PTR_L           a1, sp, FGRET_REGS_A1
--      PTR_ADDI        sp, sp, FGRET_REGS_SIZE
-+      /* Restore return value regs */
-+      PTR_L           a0, sp, PT_R4
-+      PTR_L           a1, sp, PT_R5
-+      PTR_ADDI        sp, sp, PT_SIZE
-+
-       jr              ra
- SYM_FUNC_END(return_to_handler)
- #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
-diff --git a/arch/loongarch/kernel/mcount_dyn.S b/arch/loongarch/kernel/mcount_dyn.S
-index 0c65cf09110cd..d6b474ad1d5e5 100644
---- a/arch/loongarch/kernel/mcount_dyn.S
-+++ b/arch/loongarch/kernel/mcount_dyn.S
-@@ -140,19 +140,19 @@ SYM_CODE_END(ftrace_graph_caller)
- SYM_CODE_START(return_to_handler)
-       UNWIND_HINT_UNDEFINED
-       /* Save return value regs */
--      PTR_ADDI        sp, sp, -FGRET_REGS_SIZE
--      PTR_S           a0, sp, FGRET_REGS_A0
--      PTR_S           a1, sp, FGRET_REGS_A1
--      PTR_S           zero, sp, FGRET_REGS_FP
-+      PTR_ADDI        sp, sp, -PT_SIZE
-+      PTR_S           a0, sp, PT_R4
-+      PTR_S           a1, sp, PT_R5
-+      PTR_S           zero, sp, PT_R22
-       move            a0, sp
-       bl              ftrace_return_to_handler
-       move            ra, a0
-       /* Restore return value regs */
--      PTR_L           a0, sp, FGRET_REGS_A0
--      PTR_L           a1, sp, FGRET_REGS_A1
--      PTR_ADDI        sp, sp, FGRET_REGS_SIZE
-+      PTR_L           a0, sp, PT_R4
-+      PTR_L           a1, sp, PT_R5
-+      PTR_ADDI        sp, sp, PT_SIZE
-       jr              ra
- SYM_CODE_END(return_to_handler)
-diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
-index d4a7ca0388c07..1e807c61258fb 100644
---- a/arch/riscv/Kconfig
-+++ b/arch/riscv/Kconfig
-@@ -148,7 +148,7 @@ config RISCV
-       select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
-       select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
-       select HAVE_FUNCTION_GRAPH_TRACER
--      select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER
-+      select HAVE_FUNCTION_GRAPH_FREGS
-       select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !PREEMPTION
-       select HAVE_EBPF_JIT if MMU
-       select HAVE_GUP_FAST if MMU
-diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
-index 3d66437a10297..9372f8d7036f8 100644
---- a/arch/riscv/include/asm/ftrace.h
-+++ b/arch/riscv/include/asm/ftrace.h
-@@ -168,6 +168,11 @@ static __always_inline unsigned long ftrace_regs_get_stack_pointer(const struct
-       return arch_ftrace_regs(fregs)->sp;
- }
-+static __always_inline unsigned long ftrace_regs_get_frame_pointer(const struct ftrace_regs *fregs)
-+{
-+      return arch_ftrace_regs(fregs)->s0;
-+}
-+
- static __always_inline unsigned long ftrace_regs_get_argument(struct ftrace_regs *fregs,
-                                                             unsigned int n)
- {
-@@ -208,25 +213,4 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsi
- #endif /* CONFIG_DYNAMIC_FTRACE */
--#ifndef __ASSEMBLY__
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--struct fgraph_ret_regs {
--      unsigned long a1;
--      unsigned long a0;
--      unsigned long s0;
--      unsigned long ra;
--};
--
--static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->a0;
--}
--
--static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->s0;
--}
--#endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
--#endif
--
- #endif /* _ASM_RISCV_FTRACE_H */
-diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S
-index 3a42f6287909d..068168046e0ef 100644
---- a/arch/riscv/kernel/mcount.S
-+++ b/arch/riscv/kernel/mcount.S
-@@ -12,6 +12,8 @@
- #include <asm/asm-offsets.h>
- #include <asm/ftrace.h>
-+#define ABI_SIZE_ON_STACK     80
-+
-       .text
-       .macro SAVE_ABI_STATE
-@@ -26,12 +28,12 @@
-        * register if a0 was not saved.
-        */
-       .macro SAVE_RET_ABI_STATE
--      addi    sp, sp, -4*SZREG
--      REG_S   s0, 2*SZREG(sp)
--      REG_S   ra, 3*SZREG(sp)
--      REG_S   a0, 1*SZREG(sp)
--      REG_S   a1, 0*SZREG(sp)
--      addi    s0, sp, 4*SZREG
-+      addi    sp, sp, -ABI_SIZE_ON_STACK
-+      REG_S   ra, 1*SZREG(sp)
-+      REG_S   s0, 8*SZREG(sp)
-+      REG_S   a0, 10*SZREG(sp)
-+      REG_S   a1, 11*SZREG(sp)
-+      addi    s0, sp, ABI_SIZE_ON_STACK
-       .endm
-       .macro RESTORE_ABI_STATE
-@@ -41,11 +43,11 @@
-       .endm
-       .macro RESTORE_RET_ABI_STATE
--      REG_L   ra, 3*SZREG(sp)
--      REG_L   s0, 2*SZREG(sp)
--      REG_L   a0, 1*SZREG(sp)
--      REG_L   a1, 0*SZREG(sp)
--      addi    sp, sp, 4*SZREG
-+      REG_L   ra, 1*SZREG(sp)
-+      REG_L   s0, 8*SZREG(sp)
-+      REG_L   a0, 10*SZREG(sp)
-+      REG_L   a1, 11*SZREG(sp)
-+      addi    sp, sp, ABI_SIZE_ON_STACK
-       .endm
- SYM_TYPED_FUNC_START(ftrace_stub)
-diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
-index 83b1d7bbd8880..a8cecae74fe81 100644
---- a/arch/s390/Kconfig
-+++ b/arch/s390/Kconfig
-@@ -193,7 +193,7 @@ config S390
-       select HAVE_FTRACE_MCOUNT_RECORD
-       select HAVE_FUNCTION_ARG_ACCESS_API
-       select HAVE_FUNCTION_ERROR_INJECTION
--      select HAVE_FUNCTION_GRAPH_RETVAL
-+      select HAVE_FUNCTION_GRAPH_FREGS
-       select HAVE_FUNCTION_GRAPH_TRACER
-       select HAVE_FUNCTION_TRACER
-       select HAVE_GCC_PLUGINS
-diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
-index fc97d75dc752c..5c94c1fc1bc1c 100644
---- a/arch/s390/include/asm/ftrace.h
-+++ b/arch/s390/include/asm/ftrace.h
-@@ -62,23 +62,6 @@ static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *
-       return NULL;
- }
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--struct fgraph_ret_regs {
--      unsigned long gpr2;
--      unsigned long fp;
--};
--
--static __always_inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->gpr2;
--}
--
--static __always_inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->fp;
--}
--#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
--
- static __always_inline void
- ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
-                                   unsigned long ip)
-@@ -86,6 +69,13 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
-       arch_ftrace_regs(fregs)->regs.psw.addr = ip;
- }
-+#undef ftrace_regs_get_frame_pointer
-+static __always_inline unsigned long
-+ftrace_regs_get_frame_pointer(struct ftrace_regs *fregs)
-+{
-+      return ftrace_regs_get_stack_pointer(fregs);
-+}
-+
- #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
- /*
-  * When an ftrace registered caller is tracing a function that is
-diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
-index 862a9140528e9..36709112ae7a2 100644
---- a/arch/s390/kernel/asm-offsets.c
-+++ b/arch/s390/kernel/asm-offsets.c
-@@ -175,12 +175,6 @@ int main(void)
-       DEFINE(OLDMEM_SIZE, PARMAREA + offsetof(struct parmarea, oldmem_size));
-       DEFINE(COMMAND_LINE, PARMAREA + offsetof(struct parmarea, command_line));
-       DEFINE(MAX_COMMAND_LINE_SIZE, PARMAREA + offsetof(struct parmarea, max_command_line_size));
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--      /* function graph return value tracing */
--      OFFSET(__FGRAPH_RET_GPR2, fgraph_ret_regs, gpr2);
--      OFFSET(__FGRAPH_RET_FP, fgraph_ret_regs, fp);
--      DEFINE(__FGRAPH_RET_SIZE, sizeof(struct fgraph_ret_regs));
--#endif
-       OFFSET(__FTRACE_REGS_PT_REGS, __arch_ftrace_regs, regs);
-       DEFINE(__FTRACE_REGS_SIZE, sizeof(struct __arch_ftrace_regs));
-diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S
-index 7e267ef63a7fe..2b628aa3d8095 100644
---- a/arch/s390/kernel/mcount.S
-+++ b/arch/s390/kernel/mcount.S
-@@ -134,14 +134,14 @@ SYM_CODE_END(ftrace_common)
- SYM_FUNC_START(return_to_handler)
-       stmg    %r2,%r5,32(%r15)
-       lgr     %r1,%r15
--      aghi    %r15,-(STACK_FRAME_OVERHEAD+__FGRAPH_RET_SIZE)
-+      # allocate ftrace_regs and stack frame for ftrace_return_to_handler
-+      aghi    %r15,-STACK_FRAME_SIZE_FREGS
-       stg     %r1,__SF_BACKCHAIN(%r15)
--      la      %r3,STACK_FRAME_OVERHEAD(%r15)
--      stg     %r1,__FGRAPH_RET_FP(%r3)
--      stg     %r2,__FGRAPH_RET_GPR2(%r3)
--      lgr     %r2,%r3
-+      stg     %r2,(STACK_FREGS_PTREGS_GPRS+2*8)(%r15)
-+      stg     %r1,(STACK_FREGS_PTREGS_GPRS+15*8)(%r15)
-+      la      %r2,STACK_FRAME_OVERHEAD(%r15)
-       brasl   %r14,ftrace_return_to_handler
--      aghi    %r15,STACK_FRAME_OVERHEAD+__FGRAPH_RET_SIZE
-+      aghi    %r15,STACK_FRAME_SIZE_FREGS
-       lgr     %r14,%r2
-       lmg     %r2,%r5,32(%r15)
-       BR_EX   %r14
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index 757333fe82c76..aa317f6064b89 100644
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -234,7 +234,7 @@ config X86
-       select HAVE_GUP_FAST
-       select HAVE_FENTRY                      if X86_64 || DYNAMIC_FTRACE
-       select HAVE_FTRACE_MCOUNT_RECORD
--      select HAVE_FUNCTION_GRAPH_RETVAL       if HAVE_FUNCTION_GRAPH_TRACER
-+      select HAVE_FUNCTION_GRAPH_FREGS        if HAVE_FUNCTION_GRAPH_TRACER
-       select HAVE_FUNCTION_GRAPH_TRACER       if X86_32 || (X86_64 && DYNAMIC_FTRACE)
-       select HAVE_FUNCTION_TRACER
-       select HAVE_GCC_PLUGINS
-diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
-index 6e8cf0fa48fc6..d61407c680c28 100644
---- a/arch/x86/include/asm/ftrace.h
-+++ b/arch/x86/include/asm/ftrace.h
-@@ -134,24 +134,4 @@ static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
- #endif /* !COMPILE_OFFSETS */
- #endif /* !__ASSEMBLY__ */
--#ifndef __ASSEMBLY__
--#ifdef CONFIG_FUNCTION_GRAPH_TRACER
--struct fgraph_ret_regs {
--      unsigned long ax;
--      unsigned long dx;
--      unsigned long bp;
--};
--
--static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->ax;
--}
--
--static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
--{
--      return ret_regs->bp;
--}
--#endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
--#endif
--
- #endif /* _ASM_X86_FTRACE_H */
-diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S
-index 58d9ed50fe617..f4e0c33612342 100644
---- a/arch/x86/kernel/ftrace_32.S
-+++ b/arch/x86/kernel/ftrace_32.S
-@@ -187,14 +187,15 @@ SYM_CODE_END(ftrace_graph_caller)
- .globl return_to_handler
- return_to_handler:
--      pushl   $0
--      pushl   %edx
--      pushl   %eax
-+      subl    $(PTREGS_SIZE), %esp
-+      movl    $0, PT_EBP(%esp)
-+      movl    %edx, PT_EDX(%esp)
-+      movl    %eax, PT_EAX(%esp)
-       movl    %esp, %eax
-       call    ftrace_return_to_handler
-       movl    %eax, %ecx
--      popl    %eax
--      popl    %edx
--      addl    $4, %esp                # skip ebp
-+      movl    PT_EAX(%esp), %eax
-+      movl    PT_EDX(%esp), %edx
-+      addl    $(PTREGS_SIZE), %esp
-       JMP_NOSPEC ecx
- #endif
-diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S
-index 214f30e9f0c01..d516472285967 100644
---- a/arch/x86/kernel/ftrace_64.S
-+++ b/arch/x86/kernel/ftrace_64.S
-@@ -348,21 +348,22 @@ STACK_FRAME_NON_STANDARD_FP(__fentry__)
- SYM_CODE_START(return_to_handler)
-       UNWIND_HINT_UNDEFINED
-       ANNOTATE_NOENDBR
--      subq  $24, %rsp
--      /* Save the return values */
--      movq %rax, (%rsp)
--      movq %rdx, 8(%rsp)
--      movq %rbp, 16(%rsp)
-+      /* Save ftrace_regs for function exit context  */
-+      subq $(FRAME_SIZE), %rsp
-+
-+      movq %rax, RAX(%rsp)
-+      movq %rdx, RDX(%rsp)
-+      movq %rbp, RBP(%rsp)
-       movq %rsp, %rdi
-       call ftrace_return_to_handler
-       movq %rax, %rdi
--      movq 8(%rsp), %rdx
--      movq (%rsp), %rax
-+      movq RDX(%rsp), %rdx
-+      movq RAX(%rsp), %rax
--      addq $24, %rsp
-+      addq $(FRAME_SIZE), %rsp
-       /*
-        * Jump back to the old return address. This cannot be JMP_NOSPEC rdi
-        * since IBT would demand that contain ENDBR, which simply isn't so for
-diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
-index aa9ddd1e4bb6a..b7407004c799e 100644
---- a/include/linux/ftrace.h
-+++ b/include/linux/ftrace.h
-@@ -43,9 +43,8 @@ struct dyn_ftrace;
- char *arch_ftrace_match_adjust(char *str, const char *search);
--#ifdef CONFIG_HAVE_FUNCTION_GRAPH_RETVAL
--struct fgraph_ret_regs;
--unsigned long ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs);
-+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FREGS
-+unsigned long ftrace_return_to_handler(struct ftrace_regs *fregs);
- #else
- unsigned long ftrace_return_to_handler(unsigned long frame_pointer);
- #endif
-@@ -134,6 +133,13 @@ extern int ftrace_enabled;
-  * Also, architecture dependent fields can be used for internal process.
-  * (e.g. orig_ax on x86_64)
-  *
-+ * Basically, ftrace_regs stores the registers related to the context.
-+ * On function entry, registers for function parameters and hooking the
-+ * function call are stored, and on function exit, registers for function
-+ * return value and frame pointers are stored.
-+ *
-+ * And also, it dpends on the context that which registers are restored
-+ * from the ftrace_regs.
-  * On the function entry, those registers will be restored except for
-  * the stack pointer, so that user can change the function parameters
-  * and instruction pointer (e.g. live patching.)
-diff --git a/include/linux/ftrace_regs.h b/include/linux/ftrace_regs.h
-index be1ed0c891d07..bbc1873ca6b8e 100644
---- a/include/linux/ftrace_regs.h
-+++ b/include/linux/ftrace_regs.h
-@@ -30,6 +30,8 @@ struct ftrace_regs;
-       override_function_with_return(&arch_ftrace_regs(fregs)->regs)
- #define ftrace_regs_query_register_offset(name) \
-       regs_query_register_offset(name)
-+#define ftrace_regs_get_frame_pointer(fregs) \
-+      frame_pointer(&arch_ftrace_regs(fregs)->regs)
- #endif /* HAVE_ARCH_FTRACE_REGS */
-diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
-index 74c2b1d43bb98..c5ab2a561272d 100644
---- a/kernel/trace/Kconfig
-+++ b/kernel/trace/Kconfig
-@@ -31,7 +31,7 @@ config HAVE_FUNCTION_GRAPH_TRACER
-       help
-         See Documentation/trace/ftrace-design.rst
--config HAVE_FUNCTION_GRAPH_RETVAL
-+config HAVE_FUNCTION_GRAPH_FREGS
-       bool
- config HAVE_DYNAMIC_FTRACE
-@@ -232,7 +232,7 @@ config FUNCTION_GRAPH_TRACER
- config FUNCTION_GRAPH_RETVAL
-       bool "Kernel Function Graph Return Value"
--      depends on HAVE_FUNCTION_GRAPH_RETVAL
-+      depends on HAVE_FUNCTION_GRAPH_FREGS
-       depends on FUNCTION_GRAPH_TRACER
-       default n
-       help
-diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c
-index 30e3ddc8a8a84..6e55759b45776 100644
---- a/kernel/trace/fgraph.c
-+++ b/kernel/trace/fgraph.c
-@@ -792,15 +792,12 @@ static struct notifier_block ftrace_suspend_notifier = {
-       .notifier_call = ftrace_suspend_notifier_call,
- };
--/* fgraph_ret_regs is not defined without CONFIG_FUNCTION_GRAPH_RETVAL */
--struct fgraph_ret_regs;
--
- /*
-  * Send the trace to the ring-buffer.
-  * @return the original return address.
-  */
--static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs,
--                                              unsigned long frame_pointer)
-+static inline unsigned long
-+__ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointer)
- {
-       struct ftrace_ret_stack *ret_stack;
-       struct ftrace_graph_ret trace;
-@@ -820,7 +817,7 @@ static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs
-       trace.rettime = trace_clock_local();
- #ifdef CONFIG_FUNCTION_GRAPH_RETVAL
--      trace.retval = fgraph_ret_regs_return_value(ret_regs);
-+      trace.retval = ftrace_regs_get_return_value(fregs);
- #endif
-       bitmap = get_bitmap_bits(current, offset);
-@@ -855,14 +852,14 @@ static unsigned long __ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs
- }
- /*
-- * After all architecures have selected HAVE_FUNCTION_GRAPH_RETVAL, we can
-- * leave only ftrace_return_to_handler(ret_regs).
-+ * After all architecures have selected HAVE_FUNCTION_GRAPH_FREGS, we can
-+ * leave only ftrace_return_to_handler(fregs).
-  */
--#ifdef CONFIG_HAVE_FUNCTION_GRAPH_RETVAL
--unsigned long ftrace_return_to_handler(struct fgraph_ret_regs *ret_regs)
-+#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FREGS
-+unsigned long ftrace_return_to_handler(struct ftrace_regs *fregs)
- {
--      return __ftrace_return_to_handler(ret_regs,
--                              fgraph_ret_regs_frame_pointer(ret_regs));
-+      return __ftrace_return_to_handler(fregs,
-+                              ftrace_regs_get_frame_pointer(fregs));
- }
- #else
- unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
--- 
-2.39.5
-
diff --git a/queue-6.13/fprobe-rewrite-fprobe-on-function-graph-tracer.patch b/queue-6.13/fprobe-rewrite-fprobe-on-function-graph-tracer.patch
deleted file mode 100644 (file)
index 04302fe..0000000
+++ /dev/null
@@ -1,1168 +0,0 @@
-From 98b2c6a182a85ab61910f92b12b78f066e34fd38 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Dec 2024 14:13:59 +0900
-Subject: fprobe: Rewrite fprobe on function-graph tracer
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit 4346ba1604093305a287e08eb465a9c15ba05b80 ]
-
-Rewrite fprobe implementation on function-graph tracer.
-Major API changes are:
- -  'nr_maxactive' field is deprecated.
- -  This depends on CONFIG_DYNAMIC_FTRACE_WITH_ARGS or
-    !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS, and
-    CONFIG_HAVE_FUNCTION_GRAPH_FREGS. So currently works only
-    on x86_64.
- -  Currently the entry size is limited in 15 * sizeof(long).
- -  If there is too many fprobe exit handler set on the same
-    function, it will fail to probe.
-
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Acked-by: Heiko Carstens <hca@linux.ibm.com> # s390
-Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
-Cc: Florent Revest <revest@chromium.org>
-Cc: Martin KaFai Lau <martin.lau@linux.dev>
-Cc: bpf <bpf@vger.kernel.org>
-Cc: Alexei Starovoitov <ast@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Alan Maguire <alan.maguire@oracle.com>
-Cc: Heiko Carstens <hca@linux.ibm.com>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Will Deacon <will@kernel.org>
-Cc: Huacai Chen <chenhuacai@kernel.org>
-Cc: WANG Xuerui <kernel@xen0n.name>
-Cc: Michael Ellerman <mpe@ellerman.id.au>
-Cc: Nicholas Piggin <npiggin@gmail.com>
-Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
-Cc: Naveen N Rao <naveen@kernel.org>
-Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
-Cc: Paul Walmsley <paul.walmsley@sifive.com>
-Cc: Palmer Dabbelt <palmer@dabbelt.com>
-Cc: Albert Ou <aou@eecs.berkeley.edu>
-Cc: Vasily Gorbik <gor@linux.ibm.com>
-Cc: Alexander Gordeev <agordeev@linux.ibm.com>
-Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
-Cc: Sven Schnelle <svens@linux.ibm.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: x86@kernel.org
-Cc: "H. Peter Anvin" <hpa@zytor.com>
-Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Link: https://lore.kernel.org/173519003970.391279.14406792285453830996.stgit@devnote2
-Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Stable-dep-of: db5e228611b1 ("tracing: fprobe-events: Log error for exceeding the number of entry args")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/arm64/include/asm/ftrace.h     |   6 +
- arch/loongarch/include/asm/ftrace.h |   6 +
- arch/powerpc/include/asm/ftrace.h   |   6 +
- arch/riscv/include/asm/ftrace.h     |   5 +
- arch/s390/include/asm/ftrace.h      |   6 +
- arch/x86/include/asm/ftrace.h       |   6 +
- include/linux/fprobe.h              |  58 ++-
- kernel/trace/Kconfig                |   8 +-
- kernel/trace/fprobe.c               | 637 ++++++++++++++++++++--------
- lib/test_fprobe.c                   |  45 --
- 10 files changed, 538 insertions(+), 245 deletions(-)
-
-diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
-index 10e56522122aa..876e88ad4119f 100644
---- a/arch/arm64/include/asm/ftrace.h
-+++ b/arch/arm64/include/asm/ftrace.h
-@@ -135,6 +135,12 @@ ftrace_regs_get_frame_pointer(const struct ftrace_regs *fregs)
-       return arch_ftrace_regs(fregs)->fp;
- }
-+static __always_inline unsigned long
-+ftrace_regs_get_return_address(const struct ftrace_regs *fregs)
-+{
-+      return arch_ftrace_regs(fregs)->lr;
-+}
-+
- static __always_inline struct pt_regs *
- ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
- {
-diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/asm/ftrace.h
-index ceb3e3d9c0d3d..6e0a99763a9a7 100644
---- a/arch/loongarch/include/asm/ftrace.h
-+++ b/arch/loongarch/include/asm/ftrace.h
-@@ -61,6 +61,12 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs, unsigned long ip)
- #define ftrace_regs_get_frame_pointer(fregs) \
-       (arch_ftrace_regs(fregs)->regs.regs[22])
-+static __always_inline unsigned long
-+ftrace_regs_get_return_address(struct ftrace_regs *fregs)
-+{
-+      return *(unsigned long *)(arch_ftrace_regs(fregs)->regs.regs[1]);
-+}
-+
- #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);
-diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
-index fe181bafdca4f..82da7c7a1d125 100644
---- a/arch/powerpc/include/asm/ftrace.h
-+++ b/arch/powerpc/include/asm/ftrace.h
-@@ -57,6 +57,12 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
-       regs_set_return_ip(&arch_ftrace_regs(fregs)->regs, ip);
- }
-+static __always_inline unsigned long
-+ftrace_regs_get_return_address(struct ftrace_regs *fregs)
-+{
-+      return arch_ftrace_regs(fregs)->regs.link;
-+}
-+
- struct ftrace_ops;
- #define ftrace_graph_func ftrace_graph_func
-diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
-index 7064a530794b6..c4721ce44ca47 100644
---- a/arch/riscv/include/asm/ftrace.h
-+++ b/arch/riscv/include/asm/ftrace.h
-@@ -186,6 +186,11 @@ static __always_inline unsigned long ftrace_regs_get_return_value(const struct f
-       return arch_ftrace_regs(fregs)->a0;
- }
-+static __always_inline unsigned long ftrace_regs_get_return_address(const struct ftrace_regs *fregs)
-+{
-+      return arch_ftrace_regs(fregs)->ra;
-+}
-+
- static __always_inline void ftrace_regs_set_return_value(struct ftrace_regs *fregs,
-                                                        unsigned long ret)
- {
-diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
-index 5b7cb49c41ee0..8c94a330c70c9 100644
---- a/arch/s390/include/asm/ftrace.h
-+++ b/arch/s390/include/asm/ftrace.h
-@@ -76,6 +76,12 @@ ftrace_regs_get_frame_pointer(struct ftrace_regs *fregs)
-       return ftrace_regs_get_stack_pointer(fregs);
- }
-+static __always_inline unsigned long
-+ftrace_regs_get_return_address(const struct ftrace_regs *fregs)
-+{
-+      return arch_ftrace_regs(fregs)->regs.gprs[14];
-+}
-+
- #define arch_ftrace_fill_perf_regs(fregs, _regs)       do {           \
-               (_regs)->psw.mask = 0;                                  \
-               (_regs)->psw.addr = arch_ftrace_regs(fregs)->regs.psw.addr;             \
-diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
-index 7e06f8c7937aa..cc92c99ef2760 100644
---- a/arch/x86/include/asm/ftrace.h
-+++ b/arch/x86/include/asm/ftrace.h
-@@ -58,6 +58,12 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs)
-       do { arch_ftrace_regs(fregs)->regs.ip = (_ip); } while (0)
-+static __always_inline unsigned long
-+ftrace_regs_get_return_address(struct ftrace_regs *fregs)
-+{
-+      return *(unsigned long *)ftrace_regs_get_stack_pointer(fregs);
-+}
-+
- struct ftrace_ops;
- #define ftrace_graph_func ftrace_graph_func
- void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
-diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h
-index ef609bcca0f92..91337bcb452ff 100644
---- a/include/linux/fprobe.h
-+++ b/include/linux/fprobe.h
-@@ -5,10 +5,11 @@
- #include <linux/compiler.h>
- #include <linux/ftrace.h>
--#include <linux/rethook.h>
-+#include <linux/rcupdate.h>
-+#include <linux/refcount.h>
-+#include <linux/slab.h>
- struct fprobe;
--
- typedef int (*fprobe_entry_cb)(struct fprobe *fp, unsigned long entry_ip,
-                              unsigned long ret_ip, struct ftrace_regs *regs,
-                              void *entry_data);
-@@ -17,35 +18,57 @@ typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
-                              unsigned long ret_ip, struct ftrace_regs *regs,
-                              void *entry_data);
-+/**
-+ * struct fprobe_hlist_node - address based hash list node for fprobe.
-+ *
-+ * @hlist: The hlist node for address search hash table.
-+ * @addr: One of the probing address of @fp.
-+ * @fp: The fprobe which owns this.
-+ */
-+struct fprobe_hlist_node {
-+      struct hlist_node       hlist;
-+      unsigned long           addr;
-+      struct fprobe           *fp;
-+};
-+
-+/**
-+ * struct fprobe_hlist - hash list nodes for fprobe.
-+ *
-+ * @hlist: The hlist node for existence checking hash table.
-+ * @rcu: rcu_head for RCU deferred release.
-+ * @fp: The fprobe which owns this fprobe_hlist.
-+ * @size: The size of @array.
-+ * @array: The fprobe_hlist_node for each address to probe.
-+ */
-+struct fprobe_hlist {
-+      struct hlist_node               hlist;
-+      struct rcu_head                 rcu;
-+      struct fprobe                   *fp;
-+      int                             size;
-+      struct fprobe_hlist_node        array[] __counted_by(size);
-+};
-+
- /**
-  * struct fprobe - ftrace based probe.
-- * @ops: The ftrace_ops.
-+ *
-  * @nmissed: The counter for missing events.
-  * @flags: The status flag.
-- * @rethook: The rethook data structure. (internal data)
-  * @entry_data_size: The private data storage size.
-- * @nr_maxactive: The max number of active functions.
-+ * @nr_maxactive: The max number of active functions. (*deprecated)
-  * @entry_handler: The callback function for function entry.
-  * @exit_handler: The callback function for function exit.
-+ * @hlist_array: The fprobe_hlist for fprobe search from IP hash table.
-  */
- struct fprobe {
--#ifdef CONFIG_FUNCTION_TRACER
--      /*
--       * If CONFIG_FUNCTION_TRACER is not set, CONFIG_FPROBE is disabled too.
--       * But user of fprobe may keep embedding the struct fprobe on their own
--       * code. To avoid build error, this will keep the fprobe data structure
--       * defined here, but remove ftrace_ops data structure.
--       */
--      struct ftrace_ops       ops;
--#endif
-       unsigned long           nmissed;
-       unsigned int            flags;
--      struct rethook          *rethook;
-       size_t                  entry_data_size;
-       int                     nr_maxactive;
-       fprobe_entry_cb entry_handler;
-       fprobe_exit_cb  exit_handler;
-+
-+      struct fprobe_hlist     *hlist_array;
- };
- /* This fprobe is soft-disabled. */
-@@ -121,4 +144,9 @@ static inline void enable_fprobe(struct fprobe *fp)
-               fp->flags &= ~FPROBE_FL_DISABLED;
- }
-+/* The entry data size is 4 bits (=16) * sizeof(long) in maximum */
-+#define FPROBE_DATA_SIZE_BITS         4
-+#define MAX_FPROBE_DATA_SIZE_WORD     ((1L << FPROBE_DATA_SIZE_BITS) - 1)
-+#define MAX_FPROBE_DATA_SIZE          (MAX_FPROBE_DATA_SIZE_WORD * sizeof(long))
-+
- #endif
-diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
-index 7f8165f2049a5..69954212c77d1 100644
---- a/kernel/trace/Kconfig
-+++ b/kernel/trace/Kconfig
-@@ -302,11 +302,9 @@ config DYNAMIC_FTRACE_WITH_ARGS
- config FPROBE
-       bool "Kernel Function Probe (fprobe)"
--      depends on FUNCTION_TRACER
--      depends on DYNAMIC_FTRACE_WITH_REGS || DYNAMIC_FTRACE_WITH_ARGS
--      depends on HAVE_FTRACE_REGS_HAVING_PT_REGS || !HAVE_DYNAMIC_FTRACE_WITH_ARGS
--      depends on HAVE_RETHOOK
--      select RETHOOK
-+      depends on HAVE_FUNCTION_GRAPH_FREGS && HAVE_FTRACE_GRAPH_FUNC
-+      depends on DYNAMIC_FTRACE_WITH_ARGS
-+      select FUNCTION_GRAPH_TRACER
-       default n
-       help
-         This option enables kernel function probe (fprobe) based on ftrace.
-diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
-index 90a3c8e2bbdf1..ed9c1d79426a2 100644
---- a/kernel/trace/fprobe.c
-+++ b/kernel/trace/fprobe.c
-@@ -8,98 +8,195 @@
- #include <linux/fprobe.h>
- #include <linux/kallsyms.h>
- #include <linux/kprobes.h>
--#include <linux/rethook.h>
-+#include <linux/list.h>
-+#include <linux/mutex.h>
- #include <linux/slab.h>
- #include <linux/sort.h>
- #include "trace.h"
--struct fprobe_rethook_node {
--      struct rethook_node node;
--      unsigned long entry_ip;
--      unsigned long entry_parent_ip;
--      char data[];
--};
-+#define FPROBE_IP_HASH_BITS 8
-+#define FPROBE_IP_TABLE_SIZE (1 << FPROBE_IP_HASH_BITS)
--static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip,
--                      struct ftrace_ops *ops, struct ftrace_regs *fregs)
--{
--      struct fprobe_rethook_node *fpr;
--      struct rethook_node *rh = NULL;
--      struct fprobe *fp;
--      void *entry_data = NULL;
--      int ret = 0;
-+#define FPROBE_HASH_BITS 6
-+#define FPROBE_TABLE_SIZE (1 << FPROBE_HASH_BITS)
--      fp = container_of(ops, struct fprobe, ops);
-+#define SIZE_IN_LONG(x) ((x + sizeof(long) - 1) >> (sizeof(long) == 8 ? 3 : 2))
--      if (fp->exit_handler) {
--              rh = rethook_try_get(fp->rethook);
--              if (!rh) {
--                      fp->nmissed++;
--                      return;
--              }
--              fpr = container_of(rh, struct fprobe_rethook_node, node);
--              fpr->entry_ip = ip;
--              fpr->entry_parent_ip = parent_ip;
--              if (fp->entry_data_size)
--                      entry_data = fpr->data;
-+/*
-+ * fprobe_table: hold 'fprobe_hlist::hlist' for checking the fprobe still
-+ *   exists. The key is the address of fprobe instance.
-+ * fprobe_ip_table: hold 'fprobe_hlist::array[*]' for searching the fprobe
-+ *   instance related to the funciton address. The key is the ftrace IP
-+ *   address.
-+ *
-+ * When unregistering the fprobe, fprobe_hlist::fp and fprobe_hlist::array[*].fp
-+ * are set NULL and delete those from both hash tables (by hlist_del_rcu).
-+ * After an RCU grace period, the fprobe_hlist itself will be released.
-+ *
-+ * fprobe_table and fprobe_ip_table can be accessed from either
-+ *  - Normal hlist traversal and RCU add/del under 'fprobe_mutex' is held.
-+ *  - RCU hlist traversal under disabling preempt
-+ */
-+static struct hlist_head fprobe_table[FPROBE_TABLE_SIZE];
-+static struct hlist_head fprobe_ip_table[FPROBE_IP_TABLE_SIZE];
-+static DEFINE_MUTEX(fprobe_mutex);
-+
-+/*
-+ * Find first fprobe in the hlist. It will be iterated twice in the entry
-+ * probe, once for correcting the total required size, the second time is
-+ * calling back the user handlers.
-+ * Thus the hlist in the fprobe_table must be sorted and new probe needs to
-+ * be added *before* the first fprobe.
-+ */
-+static struct fprobe_hlist_node *find_first_fprobe_node(unsigned long ip)
-+{
-+      struct fprobe_hlist_node *node;
-+      struct hlist_head *head;
-+
-+      head = &fprobe_ip_table[hash_ptr((void *)ip, FPROBE_IP_HASH_BITS)];
-+      hlist_for_each_entry_rcu(node, head, hlist,
-+                               lockdep_is_held(&fprobe_mutex)) {
-+              if (node->addr == ip)
-+                      return node;
-       }
-+      return NULL;
-+}
-+NOKPROBE_SYMBOL(find_first_fprobe_node);
--      if (fp->entry_handler)
--              ret = fp->entry_handler(fp, ip, parent_ip, fregs, entry_data);
-+/* Node insertion and deletion requires the fprobe_mutex */
-+static void insert_fprobe_node(struct fprobe_hlist_node *node)
-+{
-+      unsigned long ip = node->addr;
-+      struct fprobe_hlist_node *next;
-+      struct hlist_head *head;
--      /* If entry_handler returns !0, nmissed is not counted. */
--      if (rh) {
--              if (ret)
--                      rethook_recycle(rh);
--              else
--                      rethook_hook(rh, ftrace_get_regs(fregs), true);
-+      lockdep_assert_held(&fprobe_mutex);
-+
-+      next = find_first_fprobe_node(ip);
-+      if (next) {
-+              hlist_add_before_rcu(&node->hlist, &next->hlist);
-+              return;
-       }
-+      head = &fprobe_ip_table[hash_ptr((void *)ip, FPROBE_IP_HASH_BITS)];
-+      hlist_add_head_rcu(&node->hlist, head);
- }
--static void fprobe_handler(unsigned long ip, unsigned long parent_ip,
--              struct ftrace_ops *ops, struct ftrace_regs *fregs)
-+/* Return true if there are synonims */
-+static bool delete_fprobe_node(struct fprobe_hlist_node *node)
- {
--      struct fprobe *fp;
--      int bit;
-+      lockdep_assert_held(&fprobe_mutex);
--      fp = container_of(ops, struct fprobe, ops);
--      if (fprobe_disabled(fp))
--              return;
-+      WRITE_ONCE(node->fp, NULL);
-+      hlist_del_rcu(&node->hlist);
-+      return !!find_first_fprobe_node(node->addr);
-+}
--      /* recursion detection has to go before any traceable function and
--       * all functions before this point should be marked as notrace
--       */
--      bit = ftrace_test_recursion_trylock(ip, parent_ip);
--      if (bit < 0) {
--              fp->nmissed++;
--              return;
-+/* Check existence of the fprobe */
-+static bool is_fprobe_still_exist(struct fprobe *fp)
-+{
-+      struct hlist_head *head;
-+      struct fprobe_hlist *fph;
-+
-+      head = &fprobe_table[hash_ptr(fp, FPROBE_HASH_BITS)];
-+      hlist_for_each_entry_rcu(fph, head, hlist,
-+                               lockdep_is_held(&fprobe_mutex)) {
-+              if (fph->fp == fp)
-+                      return true;
-       }
--      __fprobe_handler(ip, parent_ip, ops, fregs);
--      ftrace_test_recursion_unlock(bit);
-+      return false;
-+}
-+NOKPROBE_SYMBOL(is_fprobe_still_exist);
-+
-+static int add_fprobe_hash(struct fprobe *fp)
-+{
-+      struct fprobe_hlist *fph = fp->hlist_array;
-+      struct hlist_head *head;
-+
-+      lockdep_assert_held(&fprobe_mutex);
-+
-+      if (WARN_ON_ONCE(!fph))
-+              return -EINVAL;
-+
-+      if (is_fprobe_still_exist(fp))
-+              return -EEXIST;
-+      head = &fprobe_table[hash_ptr(fp, FPROBE_HASH_BITS)];
-+      hlist_add_head_rcu(&fp->hlist_array->hlist, head);
-+      return 0;
- }
--NOKPROBE_SYMBOL(fprobe_handler);
--static void fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip,
--                                struct ftrace_ops *ops, struct ftrace_regs *fregs)
-+static int del_fprobe_hash(struct fprobe *fp)
- {
-+      struct fprobe_hlist *fph = fp->hlist_array;
-+
-+      lockdep_assert_held(&fprobe_mutex);
-+
-+      if (WARN_ON_ONCE(!fph))
-+              return -EINVAL;
-+
-+      if (!is_fprobe_still_exist(fp))
-+              return -ENOENT;
-+
-+      fph->fp = NULL;
-+      hlist_del_rcu(&fph->hlist);
-+      return 0;
-+}
-+
-+/* Generic fprobe_header */
-+struct __fprobe_header {
-       struct fprobe *fp;
--      int bit;
-+      unsigned long size_words;
-+} __packed;
--      fp = container_of(ops, struct fprobe, ops);
--      if (fprobe_disabled(fp))
--              return;
-+#define FPROBE_HEADER_SIZE_IN_LONG    SIZE_IN_LONG(sizeof(struct __fprobe_header))
--      /* recursion detection has to go before any traceable function and
--       * all functions called before this point should be marked as notrace
--       */
--      bit = ftrace_test_recursion_trylock(ip, parent_ip);
--      if (bit < 0) {
--              fp->nmissed++;
--              return;
--      }
-+static inline bool write_fprobe_header(unsigned long *stack,
-+                                      struct fprobe *fp, unsigned int size_words)
-+{
-+      struct __fprobe_header *fph = (struct __fprobe_header *)stack;
-+      if (WARN_ON_ONCE(size_words > MAX_FPROBE_DATA_SIZE_WORD))
-+              return false;
-+
-+      fph->fp = fp;
-+      fph->size_words = size_words;
-+      return true;
-+}
-+
-+static inline void read_fprobe_header(unsigned long *stack,
-+                                      struct fprobe **fp, unsigned int *size_words)
-+{
-+      struct __fprobe_header *fph = (struct __fprobe_header *)stack;
-+
-+      *fp = fph->fp;
-+      *size_words = fph->size_words;
-+}
-+
-+/*
-+ * fprobe shadow stack management:
-+ * Since fprobe shares a single fgraph_ops, it needs to share the stack entry
-+ * among the probes on the same function exit. Note that a new probe can be
-+ * registered before a target function is returning, we can not use the hash
-+ * table to find the corresponding probes. Thus the probe address is stored on
-+ * the shadow stack with its entry data size.
-+ *
-+ */
-+static inline int __fprobe_handler(unsigned long ip, unsigned long parent_ip,
-+                                 struct fprobe *fp, struct ftrace_regs *fregs,
-+                                 void *data)
-+{
-+      if (!fp->entry_handler)
-+              return 0;
-+
-+      return fp->entry_handler(fp, ip, parent_ip, fregs, data);
-+}
-+
-+static inline int __fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip,
-+                                        struct fprobe *fp, struct ftrace_regs *fregs,
-+                                        void *data)
-+{
-+      int ret;
-       /*
-        * This user handler is shared with other kprobes and is not expected to be
-        * called recursively. So if any other kprobe handler is running, this will
-@@ -108,45 +205,183 @@ static void fprobe_kprobe_handler(unsigned long ip, unsigned long parent_ip,
-        */
-       if (unlikely(kprobe_running())) {
-               fp->nmissed++;
--              goto recursion_unlock;
-+              return 0;
-       }
-       kprobe_busy_begin();
--      __fprobe_handler(ip, parent_ip, ops, fregs);
-+      ret = __fprobe_handler(ip, parent_ip, fp, fregs, data);
-       kprobe_busy_end();
--
--recursion_unlock:
--      ftrace_test_recursion_unlock(bit);
-+      return ret;
- }
--static void fprobe_exit_handler(struct rethook_node *rh, void *data,
--                              unsigned long ret_ip, struct pt_regs *regs)
-+static int fprobe_entry(struct ftrace_graph_ent *trace, struct fgraph_ops *gops,
-+                      struct ftrace_regs *fregs)
- {
--      struct fprobe *fp = (struct fprobe *)data;
--      struct fprobe_rethook_node *fpr;
--      struct ftrace_regs *fregs = (struct ftrace_regs *)regs;
--      int bit;
-+      struct fprobe_hlist_node *node, *first;
-+      unsigned long *fgraph_data = NULL;
-+      unsigned long func = trace->func;
-+      unsigned long ret_ip;
-+      int reserved_words;
-+      struct fprobe *fp;
-+      int used, ret;
--      if (!fp || fprobe_disabled(fp))
--              return;
-+      if (WARN_ON_ONCE(!fregs))
-+              return 0;
--      fpr = container_of(rh, struct fprobe_rethook_node, node);
-+      first = node = find_first_fprobe_node(func);
-+      if (unlikely(!first))
-+              return 0;
-+
-+      reserved_words = 0;
-+      hlist_for_each_entry_from_rcu(node, hlist) {
-+              if (node->addr != func)
-+                      break;
-+              fp = READ_ONCE(node->fp);
-+              if (!fp || !fp->exit_handler)
-+                      continue;
-+              /*
-+               * Since fprobe can be enabled until the next loop, we ignore the
-+               * fprobe's disabled flag in this loop.
-+               */
-+              reserved_words +=
-+                      FPROBE_HEADER_SIZE_IN_LONG + SIZE_IN_LONG(fp->entry_data_size);
-+      }
-+      node = first;
-+      if (reserved_words) {
-+              fgraph_data = fgraph_reserve_data(gops->idx, reserved_words * sizeof(long));
-+              if (unlikely(!fgraph_data)) {
-+                      hlist_for_each_entry_from_rcu(node, hlist) {
-+                              if (node->addr != func)
-+                                      break;
-+                              fp = READ_ONCE(node->fp);
-+                              if (fp && !fprobe_disabled(fp))
-+                                      fp->nmissed++;
-+                      }
-+                      return 0;
-+              }
-+      }
-       /*
--       * we need to assure no calls to traceable functions in-between the
--       * end of fprobe_handler and the beginning of fprobe_exit_handler.
-+       * TODO: recursion detection has been done in the fgraph. Thus we need
-+       * to add a callback to increment missed counter.
-        */
--      bit = ftrace_test_recursion_trylock(fpr->entry_ip, fpr->entry_parent_ip);
--      if (bit < 0) {
--              fp->nmissed++;
-+      ret_ip = ftrace_regs_get_return_address(fregs);
-+      used = 0;
-+      hlist_for_each_entry_from_rcu(node, hlist) {
-+              int data_size;
-+              void *data;
-+
-+              if (node->addr != func)
-+                      break;
-+              fp = READ_ONCE(node->fp);
-+              if (!fp || fprobe_disabled(fp))
-+                      continue;
-+
-+              data_size = fp->entry_data_size;
-+              if (data_size && fp->exit_handler)
-+                      data = fgraph_data + used + FPROBE_HEADER_SIZE_IN_LONG;
-+              else
-+                      data = NULL;
-+
-+              if (fprobe_shared_with_kprobes(fp))
-+                      ret = __fprobe_kprobe_handler(func, ret_ip, fp, fregs, data);
-+              else
-+                      ret = __fprobe_handler(func, ret_ip, fp, fregs, data);
-+
-+              /* If entry_handler returns !0, nmissed is not counted but skips exit_handler. */
-+              if (!ret && fp->exit_handler) {
-+                      int size_words = SIZE_IN_LONG(data_size);
-+
-+                      if (write_fprobe_header(&fgraph_data[used], fp, size_words))
-+                              used += FPROBE_HEADER_SIZE_IN_LONG + size_words;
-+              }
-+      }
-+      if (used < reserved_words)
-+              memset(fgraph_data + used, 0, reserved_words - used);
-+
-+      /* If any exit_handler is set, data must be used. */
-+      return used != 0;
-+}
-+NOKPROBE_SYMBOL(fprobe_entry);
-+
-+static void fprobe_return(struct ftrace_graph_ret *trace,
-+                        struct fgraph_ops *gops,
-+                        struct ftrace_regs *fregs)
-+{
-+      unsigned long *fgraph_data = NULL;
-+      unsigned long ret_ip;
-+      struct fprobe *fp;
-+      int size, curr;
-+      int size_words;
-+
-+      fgraph_data = (unsigned long *)fgraph_retrieve_data(gops->idx, &size);
-+      if (WARN_ON_ONCE(!fgraph_data))
-               return;
-+      size_words = SIZE_IN_LONG(size);
-+      ret_ip = ftrace_regs_get_instruction_pointer(fregs);
-+
-+      preempt_disable();
-+
-+      curr = 0;
-+      while (size_words > curr) {
-+              read_fprobe_header(&fgraph_data[curr], &fp, &size);
-+              if (!fp)
-+                      break;
-+              curr += FPROBE_HEADER_SIZE_IN_LONG;
-+              if (is_fprobe_still_exist(fp) && !fprobe_disabled(fp)) {
-+                      if (WARN_ON_ONCE(curr + size > size_words))
-+                              break;
-+                      fp->exit_handler(fp, trace->func, ret_ip, fregs,
-+                                       size ? fgraph_data + curr : NULL);
-+              }
-+              curr += size;
-       }
-+      preempt_enable();
-+}
-+NOKPROBE_SYMBOL(fprobe_return);
-+
-+static struct fgraph_ops fprobe_graph_ops = {
-+      .entryfunc      = fprobe_entry,
-+      .retfunc        = fprobe_return,
-+};
-+static int fprobe_graph_active;
-+
-+/* Add @addrs to the ftrace filter and register fgraph if needed. */
-+static int fprobe_graph_add_ips(unsigned long *addrs, int num)
-+{
-+      int ret;
--      fp->exit_handler(fp, fpr->entry_ip, ret_ip, fregs,
--                       fp->entry_data_size ? (void *)fpr->data : NULL);
--      ftrace_test_recursion_unlock(bit);
-+      lockdep_assert_held(&fprobe_mutex);
-+
-+      ret = ftrace_set_filter_ips(&fprobe_graph_ops.ops, addrs, num, 0, 0);
-+      if (ret)
-+              return ret;
-+
-+      if (!fprobe_graph_active) {
-+              ret = register_ftrace_graph(&fprobe_graph_ops);
-+              if (WARN_ON_ONCE(ret)) {
-+                      ftrace_free_filter(&fprobe_graph_ops.ops);
-+                      return ret;
-+              }
-+      }
-+      fprobe_graph_active++;
-+      return 0;
-+}
-+
-+/* Remove @addrs from the ftrace filter and unregister fgraph if possible. */
-+static void fprobe_graph_remove_ips(unsigned long *addrs, int num)
-+{
-+      lockdep_assert_held(&fprobe_mutex);
-+
-+      fprobe_graph_active--;
-+      if (!fprobe_graph_active) {
-+              /* Q: should we unregister it ? */
-+              unregister_ftrace_graph(&fprobe_graph_ops);
-+              return;
-+      }
-+
-+      ftrace_set_filter_ips(&fprobe_graph_ops.ops, addrs, num, 1, 0);
- }
--NOKPROBE_SYMBOL(fprobe_exit_handler);
- static int symbols_cmp(const void *a, const void *b)
- {
-@@ -176,54 +411,97 @@ static unsigned long *get_ftrace_locations(const char **syms, int num)
-       return ERR_PTR(-ENOENT);
- }
--static void fprobe_init(struct fprobe *fp)
--{
--      fp->nmissed = 0;
--      if (fprobe_shared_with_kprobes(fp))
--              fp->ops.func = fprobe_kprobe_handler;
--      else
--              fp->ops.func = fprobe_handler;
--
--      fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS;
--}
-+struct filter_match_data {
-+      const char *filter;
-+      const char *notfilter;
-+      size_t index;
-+      size_t size;
-+      unsigned long *addrs;
-+};
--static int fprobe_init_rethook(struct fprobe *fp, int num)
-+static int filter_match_callback(void *data, const char *name, unsigned long addr)
- {
--      int size;
-+      struct filter_match_data *match = data;
--      if (!fp->exit_handler) {
--              fp->rethook = NULL;
-+      if (!glob_match(match->filter, name) ||
-+          (match->notfilter && glob_match(match->notfilter, name)))
-               return 0;
--      }
--      /* Initialize rethook if needed */
--      if (fp->nr_maxactive)
--              num = fp->nr_maxactive;
--      else
--              num *= num_possible_cpus() * 2;
--      if (num <= 0)
--              return -EINVAL;
-+      if (!ftrace_location(addr))
-+              return 0;
--      size = sizeof(struct fprobe_rethook_node) + fp->entry_data_size;
-+      if (match->addrs)
-+              match->addrs[match->index] = addr;
--      /* Initialize rethook */
--      fp->rethook = rethook_alloc((void *)fp, fprobe_exit_handler, size, num);
--      if (IS_ERR(fp->rethook))
--              return PTR_ERR(fp->rethook);
-+      match->index++;
-+      return match->index == match->size;
-+}
--      return 0;
-+/*
-+ * Make IP list from the filter/no-filter glob patterns.
-+ * Return the number of matched symbols, or -ENOENT.
-+ */
-+static int ip_list_from_filter(const char *filter, const char *notfilter,
-+                             unsigned long *addrs, size_t size)
-+{
-+      struct filter_match_data match = { .filter = filter, .notfilter = notfilter,
-+              .index = 0, .size = size, .addrs = addrs};
-+      int ret;
-+
-+      ret = kallsyms_on_each_symbol(filter_match_callback, &match);
-+      if (ret < 0)
-+              return ret;
-+      ret = module_kallsyms_on_each_symbol(NULL, filter_match_callback, &match);
-+      if (ret < 0)
-+              return ret;
-+
-+      return match.index ?: -ENOENT;
- }
- static void fprobe_fail_cleanup(struct fprobe *fp)
- {
--      if (!IS_ERR_OR_NULL(fp->rethook)) {
--              /* Don't need to cleanup rethook->handler because this is not used. */
--              rethook_free(fp->rethook);
--              fp->rethook = NULL;
-+      kfree(fp->hlist_array);
-+      fp->hlist_array = NULL;
-+}
-+
-+/* Initialize the fprobe data structure. */
-+static int fprobe_init(struct fprobe *fp, unsigned long *addrs, int num)
-+{
-+      struct fprobe_hlist *hlist_array;
-+      unsigned long addr;
-+      int size, i;
-+
-+      if (!fp || !addrs || num <= 0)
-+              return -EINVAL;
-+
-+      size = ALIGN(fp->entry_data_size, sizeof(long));
-+      if (size > MAX_FPROBE_DATA_SIZE)
-+              return -E2BIG;
-+      fp->entry_data_size = size;
-+
-+      hlist_array = kzalloc(struct_size(hlist_array, array, num), GFP_KERNEL);
-+      if (!hlist_array)
-+              return -ENOMEM;
-+
-+      fp->nmissed = 0;
-+
-+      hlist_array->size = num;
-+      fp->hlist_array = hlist_array;
-+      hlist_array->fp = fp;
-+      for (i = 0; i < num; i++) {
-+              hlist_array->array[i].fp = fp;
-+              addr = ftrace_location(addrs[i]);
-+              if (!addr) {
-+                      fprobe_fail_cleanup(fp);
-+                      return -ENOENT;
-+              }
-+              hlist_array->array[i].addr = addr;
-       }
--      ftrace_free_filter(&fp->ops);
-+      return 0;
- }
-+#define FPROBE_IPS_MAX        INT_MAX
-+
- /**
-  * register_fprobe() - Register fprobe to ftrace by pattern.
-  * @fp: A fprobe data structure to be registered.
-@@ -237,46 +515,24 @@ static void fprobe_fail_cleanup(struct fprobe *fp)
-  */
- int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter)
- {
--      struct ftrace_hash *hash;
--      unsigned char *str;
--      int ret, len;
-+      unsigned long *addrs;
-+      int ret;
-       if (!fp || !filter)
-               return -EINVAL;
--      fprobe_init(fp);
--
--      len = strlen(filter);
--      str = kstrdup(filter, GFP_KERNEL);
--      ret = ftrace_set_filter(&fp->ops, str, len, 0);
--      kfree(str);
--      if (ret)
-+      ret = ip_list_from_filter(filter, notfilter, NULL, FPROBE_IPS_MAX);
-+      if (ret < 0)
-               return ret;
--      if (notfilter) {
--              len = strlen(notfilter);
--              str = kstrdup(notfilter, GFP_KERNEL);
--              ret = ftrace_set_notrace(&fp->ops, str, len, 0);
--              kfree(str);
--              if (ret)
--                      goto out;
--      }
--
--      /* TODO:
--       * correctly calculate the total number of filtered symbols
--       * from both filter and notfilter.
--       */
--      hash = rcu_access_pointer(fp->ops.local_hash.filter_hash);
--      if (WARN_ON_ONCE(!hash))
--              goto out;
--
--      ret = fprobe_init_rethook(fp, (int)hash->count);
--      if (!ret)
--              ret = register_ftrace_function(&fp->ops);
-+      addrs = kcalloc(ret, sizeof(unsigned long), GFP_KERNEL);
-+      if (!addrs)
-+              return -ENOMEM;
-+      ret = ip_list_from_filter(filter, notfilter, addrs, ret);
-+      if (ret > 0)
-+              ret = register_fprobe_ips(fp, addrs, ret);
--out:
--      if (ret)
--              fprobe_fail_cleanup(fp);
-+      kfree(addrs);
-       return ret;
- }
- EXPORT_SYMBOL_GPL(register_fprobe);
-@@ -284,7 +540,7 @@ EXPORT_SYMBOL_GPL(register_fprobe);
- /**
-  * register_fprobe_ips() - Register fprobe to ftrace by address.
-  * @fp: A fprobe data structure to be registered.
-- * @addrs: An array of target ftrace location addresses.
-+ * @addrs: An array of target function address.
-  * @num: The number of entries of @addrs.
-  *
-  * Register @fp to ftrace for enabling the probe on the address given by @addrs.
-@@ -296,23 +552,27 @@ EXPORT_SYMBOL_GPL(register_fprobe);
-  */
- int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num)
- {
--      int ret;
--
--      if (!fp || !addrs || num <= 0)
--              return -EINVAL;
-+      struct fprobe_hlist *hlist_array;
-+      int ret, i;
--      fprobe_init(fp);
--
--      ret = ftrace_set_filter_ips(&fp->ops, addrs, num, 0, 0);
-+      ret = fprobe_init(fp, addrs, num);
-       if (ret)
-               return ret;
--      ret = fprobe_init_rethook(fp, num);
--      if (!ret)
--              ret = register_ftrace_function(&fp->ops);
-+      mutex_lock(&fprobe_mutex);
-+
-+      hlist_array = fp->hlist_array;
-+      ret = fprobe_graph_add_ips(addrs, num);
-+      if (!ret) {
-+              add_fprobe_hash(fp);
-+              for (i = 0; i < hlist_array->size; i++)
-+                      insert_fprobe_node(&hlist_array->array[i]);
-+      }
-+      mutex_unlock(&fprobe_mutex);
-       if (ret)
-               fprobe_fail_cleanup(fp);
-+
-       return ret;
- }
- EXPORT_SYMBOL_GPL(register_fprobe_ips);
-@@ -350,14 +610,13 @@ EXPORT_SYMBOL_GPL(register_fprobe_syms);
- bool fprobe_is_registered(struct fprobe *fp)
- {
--      if (!fp || (fp->ops.saved_func != fprobe_handler &&
--                  fp->ops.saved_func != fprobe_kprobe_handler))
-+      if (!fp || !fp->hlist_array)
-               return false;
-       return true;
- }
- /**
-- * unregister_fprobe() - Unregister fprobe from ftrace
-+ * unregister_fprobe() - Unregister fprobe.
-  * @fp: A fprobe data structure to be unregistered.
-  *
-  * Unregister fprobe (and remove ftrace hooks from the function entries).
-@@ -366,23 +625,41 @@ bool fprobe_is_registered(struct fprobe *fp)
-  */
- int unregister_fprobe(struct fprobe *fp)
- {
--      int ret;
-+      struct fprobe_hlist *hlist_array;
-+      unsigned long *addrs = NULL;
-+      int ret = 0, i, count;
--      if (!fprobe_is_registered(fp))
--              return -EINVAL;
-+      mutex_lock(&fprobe_mutex);
-+      if (!fp || !is_fprobe_still_exist(fp)) {
-+              ret = -EINVAL;
-+              goto out;
-+      }
--      if (!IS_ERR_OR_NULL(fp->rethook))
--              rethook_stop(fp->rethook);
-+      hlist_array = fp->hlist_array;
-+      addrs = kcalloc(hlist_array->size, sizeof(unsigned long), GFP_KERNEL);
-+      if (!addrs) {
-+              ret = -ENOMEM;  /* TODO: Fallback to one-by-one loop */
-+              goto out;
-+      }
--      ret = unregister_ftrace_function(&fp->ops);
--      if (ret < 0)
--              return ret;
-+      /* Remove non-synonim ips from table and hash */
-+      count = 0;
-+      for (i = 0; i < hlist_array->size; i++) {
-+              if (!delete_fprobe_node(&hlist_array->array[i]))
-+                      addrs[count++] = hlist_array->array[i].addr;
-+      }
-+      del_fprobe_hash(fp);
--      if (!IS_ERR_OR_NULL(fp->rethook))
--              rethook_free(fp->rethook);
-+      if (count)
-+              fprobe_graph_remove_ips(addrs, count);
--      ftrace_free_filter(&fp->ops);
-+      kfree_rcu(hlist_array, rcu);
-+      fp->hlist_array = NULL;
-+out:
-+      mutex_unlock(&fprobe_mutex);
-+
-+      kfree(addrs);
-       return ret;
- }
- EXPORT_SYMBOL_GPL(unregister_fprobe);
-diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c
-index 271ce0caeec03..cf92111b5c79d 100644
---- a/lib/test_fprobe.c
-+++ b/lib/test_fprobe.c
-@@ -17,10 +17,8 @@ static u32 rand1, entry_val, exit_val;
- /* Use indirect calls to avoid inlining the target functions */
- static u32 (*target)(u32 value);
- static u32 (*target2)(u32 value);
--static u32 (*target_nest)(u32 value, u32 (*nest)(u32));
- static unsigned long target_ip;
- static unsigned long target2_ip;
--static unsigned long target_nest_ip;
- static int entry_return_value;
- static noinline u32 fprobe_selftest_target(u32 value)
-@@ -33,11 +31,6 @@ static noinline u32 fprobe_selftest_target2(u32 value)
-       return (value / div_factor) + 1;
- }
--static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32))
--{
--      return nest(value + 2);
--}
--
- static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
-                                   unsigned long ret_ip,
-                                   struct ftrace_regs *fregs, void *data)
-@@ -79,22 +72,6 @@ static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip,
-               KUNIT_EXPECT_NULL(current_test, data);
- }
--static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip,
--                                    unsigned long ret_ip,
--                                    struct ftrace_regs *fregs, void *data)
--{
--      KUNIT_EXPECT_FALSE(current_test, preemptible());
--      return 0;
--}
--
--static notrace void nest_exit_handler(struct fprobe *fp, unsigned long ip,
--                                    unsigned long ret_ip,
--                                    struct ftrace_regs *fregs, void *data)
--{
--      KUNIT_EXPECT_FALSE(current_test, preemptible());
--      KUNIT_EXPECT_EQ(current_test, ip, target_nest_ip);
--}
--
- /* Test entry only (no rethook) */
- static void test_fprobe_entry(struct kunit *test)
- {
-@@ -191,25 +168,6 @@ static void test_fprobe_data(struct kunit *test)
-       KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
- }
--/* Test nr_maxactive */
--static void test_fprobe_nest(struct kunit *test)
--{
--      static const char *syms[] = {"fprobe_selftest_target", "fprobe_selftest_nest_target"};
--      struct fprobe fp = {
--              .entry_handler = nest_entry_handler,
--              .exit_handler = nest_exit_handler,
--              .nr_maxactive = 1,
--      };
--
--      current_test = test;
--      KUNIT_EXPECT_EQ(test, 0, register_fprobe_syms(&fp, syms, 2));
--
--      target_nest(rand1, target);
--      KUNIT_EXPECT_EQ(test, 1, fp.nmissed);
--
--      KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
--}
--
- static void test_fprobe_skip(struct kunit *test)
- {
-       struct fprobe fp = {
-@@ -247,10 +205,8 @@ static int fprobe_test_init(struct kunit *test)
-       rand1 = get_random_u32_above(div_factor);
-       target = fprobe_selftest_target;
-       target2 = fprobe_selftest_target2;
--      target_nest = fprobe_selftest_nest_target;
-       target_ip = get_ftrace_location(target);
-       target2_ip = get_ftrace_location(target2);
--      target_nest_ip = get_ftrace_location(target_nest);
-       return 0;
- }
-@@ -260,7 +216,6 @@ static struct kunit_case fprobe_testcases[] = {
-       KUNIT_CASE(test_fprobe),
-       KUNIT_CASE(test_fprobe_syms),
-       KUNIT_CASE(test_fprobe_data),
--      KUNIT_CASE(test_fprobe_nest),
-       KUNIT_CASE(test_fprobe_skip),
-       {}
- };
--- 
-2.39.5
-
diff --git a/queue-6.13/fprobe-use-ftrace_regs-in-fprobe-entry-handler.patch b/queue-6.13/fprobe-use-ftrace_regs-in-fprobe-entry-handler.patch
deleted file mode 100644 (file)
index 0c7d70e..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-From 96eedf4d4d07660c69478c2a7c41d8ceee750de6 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Dec 2024 14:12:20 +0900
-Subject: fprobe: Use ftrace_regs in fprobe entry handler
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit 46bc082388560a95e3649b698a4675e5ea3262e6 ]
-
-This allows fprobes to be available with CONFIG_DYNAMIC_FTRACE_WITH_ARGS
-instead of CONFIG_DYNAMIC_FTRACE_WITH_REGS, then we can enable fprobe
-on arm64.
-
-Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
-Cc: Martin KaFai Lau <martin.lau@linux.dev>
-Cc: bpf <bpf@vger.kernel.org>
-Cc: Alexei Starovoitov <ast@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Alan Maguire <alan.maguire@oracle.com>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Link: https://lore.kernel.org/173518994037.391279.2786805566359674586.stgit@devnote2
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Acked-by: Florent Revest <revest@chromium.org>
-Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Stable-dep-of: db5e228611b1 ("tracing: fprobe-events: Log error for exceeding the number of entry args")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/fprobe.h          |  2 +-
- kernel/trace/Kconfig            |  3 ++-
- kernel/trace/bpf_trace.c        | 10 +++++++---
- kernel/trace/fprobe.c           |  3 ++-
- kernel/trace/trace_fprobe.c     | 11 ++++++++---
- lib/test_fprobe.c               |  4 ++--
- samples/fprobe/fprobe_example.c |  2 +-
- 7 files changed, 23 insertions(+), 12 deletions(-)
-
-diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h
-index f398695881175..ca64ee5e45d2c 100644
---- a/include/linux/fprobe.h
-+++ b/include/linux/fprobe.h
-@@ -10,7 +10,7 @@
- struct fprobe;
- typedef int (*fprobe_entry_cb)(struct fprobe *fp, unsigned long entry_ip,
--                             unsigned long ret_ip, struct pt_regs *regs,
-+                             unsigned long ret_ip, struct ftrace_regs *regs,
-                              void *entry_data);
- typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
-diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
-index c5ab2a561272d..f10ca86fbfad2 100644
---- a/kernel/trace/Kconfig
-+++ b/kernel/trace/Kconfig
-@@ -297,7 +297,7 @@ config DYNAMIC_FTRACE_WITH_ARGS
- config FPROBE
-       bool "Kernel Function Probe (fprobe)"
-       depends on FUNCTION_TRACER
--      depends on DYNAMIC_FTRACE_WITH_REGS
-+      depends on DYNAMIC_FTRACE_WITH_REGS || DYNAMIC_FTRACE_WITH_ARGS
-       depends on HAVE_RETHOOK
-       select RETHOOK
-       default n
-@@ -682,6 +682,7 @@ config FPROBE_EVENTS
-       select TRACING
-       select PROBE_EVENTS
-       select DYNAMIC_EVENTS
-+      depends on DYNAMIC_FTRACE_WITH_REGS
-       default y
-       help
-         This allows user to add tracing events on the function entry and
-diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
-index 2c2205e91fee9..6b58e84995e46 100644
---- a/kernel/trace/bpf_trace.c
-+++ b/kernel/trace/bpf_trace.c
-@@ -2562,7 +2562,7 @@ struct bpf_session_run_ctx {
-       void *data;
- };
--#ifdef CONFIG_FPROBE
-+#if defined(CONFIG_FPROBE) && defined(CONFIG_DYNAMIC_FTRACE_WITH_REGS)
- struct bpf_kprobe_multi_link {
-       struct bpf_link link;
-       struct fprobe fp;
-@@ -2814,12 +2814,16 @@ kprobe_multi_link_prog_run(struct bpf_kprobe_multi_link *link,
- static int
- kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
--                        unsigned long ret_ip, struct pt_regs *regs,
-+                        unsigned long ret_ip, struct ftrace_regs *fregs,
-                         void *data)
- {
-+      struct pt_regs *regs = ftrace_get_regs(fregs);
-       struct bpf_kprobe_multi_link *link;
-       int err;
-+      if (!regs)
-+              return 0;
-+
-       link = container_of(fp, struct bpf_kprobe_multi_link, fp);
-       err = kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs, false, data);
-       return is_kprobe_session(link->link.prog) ? err : 0;
-@@ -3094,7 +3098,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr
-       kvfree(cookies);
-       return err;
- }
--#else /* !CONFIG_FPROBE */
-+#else /* !CONFIG_FPROBE || !CONFIG_DYNAMIC_FTRACE_WITH_REGS */
- int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
- {
-       return -EOPNOTSUPP;
-diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
-index 9ff0182458408..3d37892838739 100644
---- a/kernel/trace/fprobe.c
-+++ b/kernel/trace/fprobe.c
-@@ -46,7 +46,7 @@ static inline void __fprobe_handler(unsigned long ip, unsigned long parent_ip,
-       }
-       if (fp->entry_handler)
--              ret = fp->entry_handler(fp, ip, parent_ip, ftrace_get_regs(fregs), entry_data);
-+              ret = fp->entry_handler(fp, ip, parent_ip, fregs, entry_data);
-       /* If entry_handler returns !0, nmissed is not counted. */
-       if (rh) {
-@@ -182,6 +182,7 @@ static void fprobe_init(struct fprobe *fp)
-               fp->ops.func = fprobe_kprobe_handler;
-       else
-               fp->ops.func = fprobe_handler;
-+
-       fp->ops.flags |= FTRACE_OPS_FL_SAVE_REGS;
- }
-diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c
-index 99048c3303822..c1eef70212b25 100644
---- a/kernel/trace/trace_fprobe.c
-+++ b/kernel/trace/trace_fprobe.c
-@@ -217,12 +217,13 @@ NOKPROBE_SYMBOL(fentry_trace_func);
- /* function exit handler */
- static int trace_fprobe_entry_handler(struct fprobe *fp, unsigned long entry_ip,
--                              unsigned long ret_ip, struct pt_regs *regs,
-+                              unsigned long ret_ip, struct ftrace_regs *fregs,
-                               void *entry_data)
- {
-       struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp);
-+      struct pt_regs *regs = ftrace_get_regs(fregs);
--      if (tf->tp.entry_arg)
-+      if (regs && tf->tp.entry_arg)
-               store_trace_entry_data(entry_data, &tf->tp, regs);
-       return 0;
-@@ -339,12 +340,16 @@ NOKPROBE_SYMBOL(fexit_perf_func);
- #endif        /* CONFIG_PERF_EVENTS */
- static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip,
--                           unsigned long ret_ip, struct pt_regs *regs,
-+                           unsigned long ret_ip, struct ftrace_regs *fregs,
-                            void *entry_data)
- {
-       struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp);
-+      struct pt_regs *regs = ftrace_get_regs(fregs);
-       int ret = 0;
-+      if (!regs)
-+              return 0;
-+
-       if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE))
-               fentry_trace_func(tf, entry_ip, regs);
- #ifdef CONFIG_PERF_EVENTS
-diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c
-index 24de0e5ff8599..ff607babba189 100644
---- a/lib/test_fprobe.c
-+++ b/lib/test_fprobe.c
-@@ -40,7 +40,7 @@ static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32))
- static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
-                                   unsigned long ret_ip,
--                                  struct pt_regs *regs, void *data)
-+                                  struct ftrace_regs *fregs, void *data)
- {
-       KUNIT_EXPECT_FALSE(current_test, preemptible());
-       /* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */
-@@ -81,7 +81,7 @@ static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip,
- static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip,
-                                     unsigned long ret_ip,
--                                    struct pt_regs *regs, void *data)
-+                                    struct ftrace_regs *fregs, void *data)
- {
-       KUNIT_EXPECT_FALSE(current_test, preemptible());
-       return 0;
-diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c
-index 0a50b05add969..c234afae52d6f 100644
---- a/samples/fprobe/fprobe_example.c
-+++ b/samples/fprobe/fprobe_example.c
-@@ -50,7 +50,7 @@ static void show_backtrace(void)
- static int sample_entry_handler(struct fprobe *fp, unsigned long ip,
-                               unsigned long ret_ip,
--                              struct pt_regs *regs, void *data)
-+                              struct ftrace_regs *fregs, void *data)
- {
-       if (use_trace)
-               /*
--- 
-2.39.5
-
diff --git a/queue-6.13/fprobe-use-ftrace_regs-in-fprobe-exit-handler.patch b/queue-6.13/fprobe-use-ftrace_regs-in-fprobe-exit-handler.patch
deleted file mode 100644 (file)
index 5e3632e..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-From 9ec816522c378200971176807181e023885863af Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Dec 2024 14:12:31 +0900
-Subject: fprobe: Use ftrace_regs in fprobe exit handler
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit 762abbc0d09f7ae123c82d315eb1a961c1a2cf7b ]
-
-Change the fprobe exit handler to use ftrace_regs structure instead of
-pt_regs. This also introduce HAVE_FTRACE_REGS_HAVING_PT_REGS which
-means the ftrace_regs is including the pt_regs so that ftrace_regs
-can provide pt_regs without memory allocation.
-Fprobe introduces a new dependency with that.
-
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Acked-by: Heiko Carstens <hca@linux.ibm.com> # s390
-Cc: Huacai Chen <chenhuacai@kernel.org>
-Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
-Cc: Florent Revest <revest@chromium.org>
-Cc: bpf <bpf@vger.kernel.org>
-Cc: Alan Maguire <alan.maguire@oracle.com>
-Cc: Heiko Carstens <hca@linux.ibm.com>
-Cc: WANG Xuerui <kernel@xen0n.name>
-Cc: Vasily Gorbik <gor@linux.ibm.com>
-Cc: Alexander Gordeev <agordeev@linux.ibm.com>
-Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
-Cc: Sven Schnelle <svens@linux.ibm.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: x86@kernel.org
-Cc: "H. Peter Anvin" <hpa@zytor.com>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
-Cc: Song Liu <song@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: KP Singh <kpsingh@kernel.org>
-Cc: Matt Bobrowski <mattbobrowski@google.com>
-Cc: Alexei Starovoitov <ast@kernel.org>
-Cc: Daniel Borkmann <daniel@iogearbox.net>
-Cc: Andrii Nakryiko <andrii@kernel.org>
-Cc: Martin KaFai Lau <martin.lau@linux.dev>
-Cc: Eduard Zingerman <eddyz87@gmail.com>
-Cc: Yonghong Song <yonghong.song@linux.dev>
-Cc: John Fastabend <john.fastabend@gmail.com>
-Cc: Stanislav Fomichev <sdf@fomichev.me>
-Cc: Hao Luo <haoluo@google.com>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Link: https://lore.kernel.org/173518995092.391279.6765116450352977627.stgit@devnote2
-Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Stable-dep-of: db5e228611b1 ("tracing: fprobe-events: Log error for exceeding the number of entry args")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/loongarch/Kconfig          | 1 +
- arch/s390/Kconfig               | 1 +
- arch/x86/Kconfig                | 1 +
- include/linux/fprobe.h          | 2 +-
- include/linux/ftrace.h          | 6 ++++++
- kernel/trace/Kconfig            | 7 +++++++
- kernel/trace/bpf_trace.c        | 6 +++++-
- kernel/trace/fprobe.c           | 3 ++-
- kernel/trace/trace_fprobe.c     | 6 +++++-
- lib/test_fprobe.c               | 6 +++---
- samples/fprobe/fprobe_example.c | 2 +-
- 11 files changed, 33 insertions(+), 8 deletions(-)
-
-diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
-index 49f5bfc00e5a1..6396615ec035e 100644
---- a/arch/loongarch/Kconfig
-+++ b/arch/loongarch/Kconfig
-@@ -128,6 +128,7 @@ config LOONGARCH
-       select HAVE_DMA_CONTIGUOUS
-       select HAVE_DYNAMIC_FTRACE
-       select HAVE_DYNAMIC_FTRACE_WITH_ARGS
-+      select HAVE_FTRACE_REGS_HAVING_PT_REGS
-       select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-       select HAVE_DYNAMIC_FTRACE_WITH_REGS
-       select HAVE_EBPF_JIT
-diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
-index a8cecae74fe81..c7a7f91a6ce19 100644
---- a/arch/s390/Kconfig
-+++ b/arch/s390/Kconfig
-@@ -184,6 +184,7 @@ config S390
-       select HAVE_DMA_CONTIGUOUS
-       select HAVE_DYNAMIC_FTRACE
-       select HAVE_DYNAMIC_FTRACE_WITH_ARGS
-+      select HAVE_FTRACE_REGS_HAVING_PT_REGS
-       select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-       select HAVE_DYNAMIC_FTRACE_WITH_REGS
-       select HAVE_EBPF_JIT if HAVE_MARCH_Z196_FEATURES
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index aa317f6064b89..9b20a96651671 100644
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -224,6 +224,7 @@ config X86
-       select HAVE_DYNAMIC_FTRACE
-       select HAVE_DYNAMIC_FTRACE_WITH_REGS
-       select HAVE_DYNAMIC_FTRACE_WITH_ARGS    if X86_64
-+      select HAVE_FTRACE_REGS_HAVING_PT_REGS  if X86_64
-       select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-       select HAVE_SAMPLE_FTRACE_DIRECT        if X86_64
-       select HAVE_SAMPLE_FTRACE_DIRECT_MULTI  if X86_64
-diff --git a/include/linux/fprobe.h b/include/linux/fprobe.h
-index ca64ee5e45d2c..ef609bcca0f92 100644
---- a/include/linux/fprobe.h
-+++ b/include/linux/fprobe.h
-@@ -14,7 +14,7 @@ typedef int (*fprobe_entry_cb)(struct fprobe *fp, unsigned long entry_ip,
-                              void *entry_data);
- typedef void (*fprobe_exit_cb)(struct fprobe *fp, unsigned long entry_ip,
--                             unsigned long ret_ip, struct pt_regs *regs,
-+                             unsigned long ret_ip, struct ftrace_regs *regs,
-                              void *entry_data);
- /**
-diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
-index b7407004c799e..46ac44366c90a 100644
---- a/include/linux/ftrace.h
-+++ b/include/linux/ftrace.h
-@@ -176,6 +176,12 @@ static inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs)
- #define ftrace_regs_set_instruction_pointer(fregs, ip) do { } while (0)
- #endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
-+#ifdef CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS
-+
-+static_assert(sizeof(struct pt_regs) == ftrace_regs_size());
-+
-+#endif /* CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */
-+
- static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs)
- {
-       if (!fregs)
-diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
-index f10ca86fbfad2..7f8165f2049a5 100644
---- a/kernel/trace/Kconfig
-+++ b/kernel/trace/Kconfig
-@@ -57,6 +57,12 @@ config HAVE_DYNAMIC_FTRACE_WITH_ARGS
-        This allows for use of ftrace_regs_get_argument() and
-        ftrace_regs_get_stack_pointer().
-+config HAVE_FTRACE_REGS_HAVING_PT_REGS
-+      bool
-+      help
-+       If this is set, ftrace_regs has pt_regs, thus it can convert to
-+       pt_regs without allocating memory.
-+
- config HAVE_DYNAMIC_FTRACE_NO_PATCHABLE
-       bool
-       help
-@@ -298,6 +304,7 @@ config FPROBE
-       bool "Kernel Function Probe (fprobe)"
-       depends on FUNCTION_TRACER
-       depends on DYNAMIC_FTRACE_WITH_REGS || DYNAMIC_FTRACE_WITH_ARGS
-+      depends on HAVE_FTRACE_REGS_HAVING_PT_REGS || !HAVE_DYNAMIC_FTRACE_WITH_ARGS
-       depends on HAVE_RETHOOK
-       select RETHOOK
-       default n
-diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
-index 6b58e84995e46..968520b04b6d3 100644
---- a/kernel/trace/bpf_trace.c
-+++ b/kernel/trace/bpf_trace.c
-@@ -2831,10 +2831,14 @@ kprobe_multi_link_handler(struct fprobe *fp, unsigned long fentry_ip,
- static void
- kprobe_multi_link_exit_handler(struct fprobe *fp, unsigned long fentry_ip,
--                             unsigned long ret_ip, struct pt_regs *regs,
-+                             unsigned long ret_ip, struct ftrace_regs *fregs,
-                              void *data)
- {
-       struct bpf_kprobe_multi_link *link;
-+      struct pt_regs *regs = ftrace_get_regs(fregs);
-+
-+      if (!regs)
-+              return;
-       link = container_of(fp, struct bpf_kprobe_multi_link, fp);
-       kprobe_multi_link_prog_run(link, get_entry_ip(fentry_ip), regs, true, data);
-diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
-index 3d37892838739..90a3c8e2bbdf1 100644
---- a/kernel/trace/fprobe.c
-+++ b/kernel/trace/fprobe.c
-@@ -124,6 +124,7 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data,
- {
-       struct fprobe *fp = (struct fprobe *)data;
-       struct fprobe_rethook_node *fpr;
-+      struct ftrace_regs *fregs = (struct ftrace_regs *)regs;
-       int bit;
-       if (!fp || fprobe_disabled(fp))
-@@ -141,7 +142,7 @@ static void fprobe_exit_handler(struct rethook_node *rh, void *data,
-               return;
-       }
--      fp->exit_handler(fp, fpr->entry_ip, ret_ip, regs,
-+      fp->exit_handler(fp, fpr->entry_ip, ret_ip, fregs,
-                        fp->entry_data_size ? (void *)fpr->data : NULL);
-       ftrace_test_recursion_unlock(bit);
- }
-diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c
-index c1eef70212b25..d906baba2d40c 100644
---- a/kernel/trace/trace_fprobe.c
-+++ b/kernel/trace/trace_fprobe.c
-@@ -361,10 +361,14 @@ static int fentry_dispatcher(struct fprobe *fp, unsigned long entry_ip,
- NOKPROBE_SYMBOL(fentry_dispatcher);
- static void fexit_dispatcher(struct fprobe *fp, unsigned long entry_ip,
--                           unsigned long ret_ip, struct pt_regs *regs,
-+                           unsigned long ret_ip, struct ftrace_regs *fregs,
-                            void *entry_data)
- {
-       struct trace_fprobe *tf = container_of(fp, struct trace_fprobe, fp);
-+      struct pt_regs *regs = ftrace_get_regs(fregs);
-+
-+      if (!regs)
-+              return;
-       if (trace_probe_test_flag(&tf->tp, TP_FLAG_TRACE))
-               fexit_trace_func(tf, entry_ip, ret_ip, regs, entry_data);
-diff --git a/lib/test_fprobe.c b/lib/test_fprobe.c
-index ff607babba189..271ce0caeec03 100644
---- a/lib/test_fprobe.c
-+++ b/lib/test_fprobe.c
-@@ -59,9 +59,9 @@ static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
- static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip,
-                                   unsigned long ret_ip,
--                                  struct pt_regs *regs, void *data)
-+                                  struct ftrace_regs *fregs, void *data)
- {
--      unsigned long ret = regs_return_value(regs);
-+      unsigned long ret = ftrace_regs_get_return_value(fregs);
-       KUNIT_EXPECT_FALSE(current_test, preemptible());
-       if (ip != target_ip) {
-@@ -89,7 +89,7 @@ static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip,
- static notrace void nest_exit_handler(struct fprobe *fp, unsigned long ip,
-                                     unsigned long ret_ip,
--                                    struct pt_regs *regs, void *data)
-+                                    struct ftrace_regs *fregs, void *data)
- {
-       KUNIT_EXPECT_FALSE(current_test, preemptible());
-       KUNIT_EXPECT_EQ(current_test, ip, target_nest_ip);
-diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c
-index c234afae52d6f..bfe98ce826f3a 100644
---- a/samples/fprobe/fprobe_example.c
-+++ b/samples/fprobe/fprobe_example.c
-@@ -67,7 +67,7 @@ static int sample_entry_handler(struct fprobe *fp, unsigned long ip,
- }
- static void sample_exit_handler(struct fprobe *fp, unsigned long ip,
--                              unsigned long ret_ip, struct pt_regs *regs,
-+                              unsigned long ret_ip, struct ftrace_regs *regs,
-                               void *data)
- {
-       unsigned long rip = ret_ip;
--- 
-2.39.5
-
index f8a1d21ec4330792142ea4c71b42479aad1e2761..47b48d517b7d2f2375579d15e41a3fcd877c0adc 100644 (file)
@@ -94,13 +94,6 @@ nvme-ioctl-fix-leaked-requests-on-mapping-error.patch
 wifi-mac80211-support-parsing-epcs-ml-element.patch
 wifi-mac80211-fix-mle-non-inheritance-parsing.patch
 wifi-mac80211-fix-vendor-specific-inheritance.patch
-fgraph-replace-fgraph_ret_regs-with-ftrace_regs.patch
-fprobe-use-ftrace_regs-in-fprobe-entry-handler.patch
-fprobe-use-ftrace_regs-in-fprobe-exit-handler.patch
-tracing-add-ftrace_partial_regs-for-converting-ftrac.patch
-tracing-add-ftrace_fill_perf_regs-for-perf-event.patch
-fprobe-rewrite-fprobe-on-function-graph-tracer.patch
-tracing-fprobe-events-log-error-for-exceeding-the-nu.patch
 drm-nouveau-select-fw-caching.patch
 bluetooth-btusb-initialize-.owner-field-of-force_pol.patch
 nvmet-remove-old-function-prototype.patch
diff --git a/queue-6.13/tracing-add-ftrace_fill_perf_regs-for-perf-event.patch b/queue-6.13/tracing-add-ftrace_fill_perf_regs-for-perf-event.patch
deleted file mode 100644 (file)
index 1921c31..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-From 2dc177cc7af51eb92a7f8ee3b81edfcc1601d361 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Dec 2024 14:12:59 +0900
-Subject: tracing: Add ftrace_fill_perf_regs() for perf event
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit d5d01b71996ec03af51b3c0736c92d0fc89703b5 ]
-
-Add ftrace_fill_perf_regs() which should be compatible with the
-perf_fetch_caller_regs(). In other words, the pt_regs returned from the
-ftrace_fill_perf_regs() must satisfy 'user_mode(regs) == false' and can be
-used for stack tracing.
-
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Acked-by: Will Deacon <will@kernel.org>
-Acked-by: Heiko Carstens <hca@linux.ibm.com> # s390
-Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
-Cc: Florent Revest <revest@chromium.org>
-Cc: Martin KaFai Lau <martin.lau@linux.dev>
-Cc: bpf <bpf@vger.kernel.org>
-Cc: Alexei Starovoitov <ast@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Alan Maguire <alan.maguire@oracle.com>
-Cc: Heiko Carstens <hca@linux.ibm.com>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Will Deacon <will@kernel.org>
-Cc: Michael Ellerman <mpe@ellerman.id.au>
-Cc: Nicholas Piggin <npiggin@gmail.com>
-Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
-Cc: Naveen N Rao <naveen@kernel.org>
-Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
-Cc: Vasily Gorbik <gor@linux.ibm.com>
-Cc: Alexander Gordeev <agordeev@linux.ibm.com>
-Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
-Cc: Sven Schnelle <svens@linux.ibm.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Ingo Molnar <mingo@redhat.com>
-Cc: Borislav Petkov <bp@alien8.de>
-Cc: Dave Hansen <dave.hansen@linux.intel.com>
-Cc: x86@kernel.org
-Cc: "H. Peter Anvin" <hpa@zytor.com>
-Link: https://lore.kernel.org/173518997908.391279.15910334347345106424.stgit@devnote2
-Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Stable-dep-of: db5e228611b1 ("tracing: fprobe-events: Log error for exceeding the number of entry args")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/arm64/include/asm/ftrace.h   |  7 +++++++
- arch/powerpc/include/asm/ftrace.h |  7 +++++++
- arch/s390/include/asm/ftrace.h    |  6 ++++++
- arch/x86/include/asm/ftrace.h     |  7 +++++++
- include/linux/ftrace.h            | 31 +++++++++++++++++++++++++++++++
- 5 files changed, 58 insertions(+)
-
-diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
-index 09210f853f12d..10e56522122aa 100644
---- a/arch/arm64/include/asm/ftrace.h
-+++ b/arch/arm64/include/asm/ftrace.h
-@@ -148,6 +148,13 @@ ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
-       return regs;
- }
-+#define arch_ftrace_fill_perf_regs(fregs, _regs) do {         \
-+              (_regs)->pc = arch_ftrace_regs(fregs)->pc;                      \
-+              (_regs)->regs[29] = arch_ftrace_regs(fregs)->fp;                \
-+              (_regs)->sp = arch_ftrace_regs(fregs)->sp;                      \
-+              (_regs)->pstate = PSR_MODE_EL1h;                \
-+      } while (0)
-+
- int ftrace_regs_query_register_offset(const char *name);
- int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
-diff --git a/arch/powerpc/include/asm/ftrace.h b/arch/powerpc/include/asm/ftrace.h
-index db481b336bca4..fe181bafdca4f 100644
---- a/arch/powerpc/include/asm/ftrace.h
-+++ b/arch/powerpc/include/asm/ftrace.h
-@@ -43,6 +43,13 @@ static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *
-       return arch_ftrace_regs(fregs)->regs.msr ? &arch_ftrace_regs(fregs)->regs : NULL;
- }
-+#define arch_ftrace_fill_perf_regs(fregs, _regs) do {         \
-+              (_regs)->result = 0;                            \
-+              (_regs)->nip = arch_ftrace_regs(fregs)->regs.nip;               \
-+              (_regs)->gpr[1] = arch_ftrace_regs(fregs)->regs.gpr[1];         \
-+              asm volatile("mfmsr %0" : "=r" ((_regs)->msr)); \
-+      } while (0)
-+
- static __always_inline void
- ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
-                                   unsigned long ip)
-diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h
-index 5c94c1fc1bc1c..5b7cb49c41ee0 100644
---- a/arch/s390/include/asm/ftrace.h
-+++ b/arch/s390/include/asm/ftrace.h
-@@ -76,6 +76,12 @@ ftrace_regs_get_frame_pointer(struct ftrace_regs *fregs)
-       return ftrace_regs_get_stack_pointer(fregs);
- }
-+#define arch_ftrace_fill_perf_regs(fregs, _regs)       do {           \
-+              (_regs)->psw.mask = 0;                                  \
-+              (_regs)->psw.addr = arch_ftrace_regs(fregs)->regs.psw.addr;             \
-+              (_regs)->gprs[15] = arch_ftrace_regs(fregs)->regs.gprs[15];             \
-+      } while (0)
-+
- #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
- /*
-  * When an ftrace registered caller is tracing a function that is
-diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
-index d61407c680c28..7e06f8c7937aa 100644
---- a/arch/x86/include/asm/ftrace.h
-+++ b/arch/x86/include/asm/ftrace.h
-@@ -47,6 +47,13 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs)
-       return &arch_ftrace_regs(fregs)->regs;
- }
-+#define arch_ftrace_fill_perf_regs(fregs, _regs) do { \
-+              (_regs)->ip = arch_ftrace_regs(fregs)->regs.ip;         \
-+              (_regs)->sp = arch_ftrace_regs(fregs)->regs.sp;         \
-+              (_regs)->cs = __KERNEL_CS;              \
-+              (_regs)->flags = 0;                     \
-+      } while (0)
-+
- #define ftrace_regs_set_instruction_pointer(fregs, _ip)       \
-       do { arch_ftrace_regs(fregs)->regs.ip = (_ip); } while (0)
-diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
-index 863c014dff683..56cb3d243c6c4 100644
---- a/include/linux/ftrace.h
-+++ b/include/linux/ftrace.h
-@@ -207,6 +207,37 @@ ftrace_partial_regs(struct ftrace_regs *fregs, struct pt_regs *regs)
- #endif /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS || CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */
-+#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
-+
-+/*
-+ * Please define arch dependent pt_regs which compatible to the
-+ * perf_arch_fetch_caller_regs() but based on ftrace_regs.
-+ * This requires
-+ *   - user_mode(_regs) returns false (always kernel mode).
-+ *   - able to use the _regs for stack trace.
-+ */
-+#ifndef arch_ftrace_fill_perf_regs
-+/* As same as perf_arch_fetch_caller_regs(), do nothing by default */
-+#define arch_ftrace_fill_perf_regs(fregs, _regs) do {} while (0)
-+#endif
-+
-+static __always_inline struct pt_regs *
-+ftrace_fill_perf_regs(struct ftrace_regs *fregs, struct pt_regs *regs)
-+{
-+      arch_ftrace_fill_perf_regs(fregs, regs);
-+      return regs;
-+}
-+
-+#else /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
-+
-+static __always_inline struct pt_regs *
-+ftrace_fill_perf_regs(struct ftrace_regs *fregs, struct pt_regs *regs)
-+{
-+      return &arch_ftrace_regs(fregs)->regs;
-+}
-+
-+#endif
-+
- /*
-  * When true, the ftrace_regs_{get,set}_*() functions may be used on fregs.
-  * Note: this can be true even when ftrace_get_regs() cannot provide a pt_regs.
--- 
-2.39.5
-
diff --git a/queue-6.13/tracing-add-ftrace_partial_regs-for-converting-ftrac.patch b/queue-6.13/tracing-add-ftrace_partial_regs-for-converting-ftrac.patch
deleted file mode 100644 (file)
index 418f517..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-From d610ad390f261355db36806d148174e492d32f0c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 26 Dec 2024 14:12:47 +0900
-Subject: tracing: Add ftrace_partial_regs() for converting ftrace_regs to
- pt_regs
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit b9b55c8912ce1e5555715d126486bdd63ddfeaec ]
-
-Add ftrace_partial_regs() which converts the ftrace_regs to pt_regs.
-This is for the eBPF which needs this to keep the same pt_regs interface
-to access registers.
-Thus when replacing the pt_regs with ftrace_regs in fprobes (which is
-used by kprobe_multi eBPF event), this will be used.
-
-If the architecture defines its own ftrace_regs, this copies partial
-registers to pt_regs and returns it. If not, ftrace_regs is the same as
-pt_regs and ftrace_partial_regs() will return ftrace_regs::regs.
-
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Acked-by: Florent Revest <revest@chromium.org>
-Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
-Cc: Martin KaFai Lau <martin.lau@linux.dev>
-Cc: bpf <bpf@vger.kernel.org>
-Cc: Alexei Starovoitov <ast@kernel.org>
-Cc: Jiri Olsa <jolsa@kernel.org>
-Cc: Alan Maguire <alan.maguire@oracle.com>
-Cc: Mark Rutland <mark.rutland@arm.com>
-Cc: Catalin Marinas <catalin.marinas@arm.com>
-Cc: Will Deacon <will@kernel.org>
-Cc: Paul Walmsley <paul.walmsley@sifive.com>
-Cc: Palmer Dabbelt <palmer@dabbelt.com>
-Cc: Albert Ou <aou@eecs.berkeley.edu>
-Link: https://lore.kernel.org/173518996761.391279.4987911298206448122.stgit@devnote2
-Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Stable-dep-of: db5e228611b1 ("tracing: fprobe-events: Log error for exceeding the number of entry args")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- arch/arm64/include/asm/ftrace.h | 13 +++++++++++++
- arch/riscv/include/asm/ftrace.h | 14 ++++++++++++++
- include/linux/ftrace.h          | 17 +++++++++++++++++
- 3 files changed, 44 insertions(+)
-
-diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
-index b5fa57b61378e..09210f853f12d 100644
---- a/arch/arm64/include/asm/ftrace.h
-+++ b/arch/arm64/include/asm/ftrace.h
-@@ -135,6 +135,19 @@ ftrace_regs_get_frame_pointer(const struct ftrace_regs *fregs)
-       return arch_ftrace_regs(fregs)->fp;
- }
-+static __always_inline struct pt_regs *
-+ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
-+{
-+      struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);
-+
-+      memcpy(regs->regs, afregs->regs, sizeof(afregs->regs));
-+      regs->sp = afregs->sp;
-+      regs->pc = afregs->pc;
-+      regs->regs[29] = afregs->fp;
-+      regs->regs[30] = afregs->lr;
-+      return regs;
-+}
-+
- int ftrace_regs_query_register_offset(const char *name);
- int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
-diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
-index 9372f8d7036f8..7064a530794b6 100644
---- a/arch/riscv/include/asm/ftrace.h
-+++ b/arch/riscv/include/asm/ftrace.h
-@@ -197,6 +197,20 @@ static __always_inline void ftrace_override_function_with_return(struct ftrace_r
-       arch_ftrace_regs(fregs)->epc = arch_ftrace_regs(fregs)->ra;
- }
-+static __always_inline struct pt_regs *
-+ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
-+{
-+      struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);
-+
-+      memcpy(&regs->a0, afregs->args, sizeof(afregs->args));
-+      regs->epc = afregs->epc;
-+      regs->ra = afregs->ra;
-+      regs->sp = afregs->sp;
-+      regs->s0 = afregs->s0;
-+      regs->t1 = afregs->t1;
-+      return regs;
-+}
-+
- int ftrace_regs_query_register_offset(const char *name);
- void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
-diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
-index 46ac44366c90a..863c014dff683 100644
---- a/include/linux/ftrace.h
-+++ b/include/linux/ftrace.h
-@@ -190,6 +190,23 @@ static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs
-       return arch_ftrace_get_regs(fregs);
- }
-+#if !defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS) || \
-+      defined(CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS)
-+
-+static __always_inline struct pt_regs *
-+ftrace_partial_regs(struct ftrace_regs *fregs, struct pt_regs *regs)
-+{
-+      /*
-+       * If CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS=y, ftrace_regs memory
-+       * layout is including pt_regs. So always returns that address.
-+       * Since arch_ftrace_get_regs() will check some members and may return
-+       * NULL, we can not use it.
-+       */
-+      return &arch_ftrace_regs(fregs)->regs;
-+}
-+
-+#endif /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS || CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */
-+
- /*
-  * When true, the ftrace_regs_{get,set}_*() functions may be used on fregs.
-  * Note: this can be true even when ftrace_get_regs() cannot provide a pt_regs.
--- 
-2.39.5
-
diff --git a/queue-6.13/tracing-fprobe-events-log-error-for-exceeding-the-nu.patch b/queue-6.13/tracing-fprobe-events-log-error-for-exceeding-the-nu.patch
deleted file mode 100644 (file)
index 5886cd0..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-From b9d5ba4f995b836db2e9dfec82979f43671868b0 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 26 Feb 2025 15:19:02 +0900
-Subject: tracing: fprobe-events: Log error for exceeding the number of entry
- args
-
-From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-
-[ Upstream commit db5e228611b118cf7b1f8084063feda5c037f4a7 ]
-
-Add error message when the number of entry argument exceeds the
-maximum size of entry data.
-This is currently checked when registering fprobe, but in this case
-no error message is shown in the error_log file.
-
-Link: https://lore.kernel.org/all/174055074269.4079315.17809232650360988538.stgit@mhiramat.tok.corp.google.com/
-
-Fixes: 25f00e40ce79 ("tracing/probes: Support $argN in return probe (kprobe and fprobe)")
-Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
-Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- kernel/trace/trace_fprobe.c | 5 +++++
- kernel/trace/trace_probe.h  | 3 ++-
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
-diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c
-index d906baba2d40c..94fe261218771 100644
---- a/kernel/trace/trace_fprobe.c
-+++ b/kernel/trace/trace_fprobe.c
-@@ -1242,6 +1242,11 @@ static int __trace_fprobe_create(int argc, const char *argv[])
-       if (is_return && tf->tp.entry_arg) {
-               tf->fp.entry_handler = trace_fprobe_entry_handler;
-               tf->fp.entry_data_size = traceprobe_get_entry_data_size(&tf->tp);
-+              if (ALIGN(tf->fp.entry_data_size, sizeof(long)) > MAX_FPROBE_DATA_SIZE) {
-+                      trace_probe_log_set_index(2);
-+                      trace_probe_log_err(0, TOO_MANY_EARGS);
-+                      return -E2BIG;
-+              }
-       }
-       ret = traceprobe_set_print_fmt(&tf->tp,
-diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
-index fba3ede870541..c47ca002347a7 100644
---- a/kernel/trace/trace_probe.h
-+++ b/kernel/trace/trace_probe.h
-@@ -545,7 +545,8 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
-       C(NO_BTF_FIELD,         "This field is not found."),    \
-       C(BAD_BTF_TID,          "Failed to get BTF type info."),\
-       C(BAD_TYPE4STR,         "This type does not fit for string."),\
--      C(NEED_STRING_TYPE,     "$comm and immediate-string only accepts string type"),
-+      C(NEED_STRING_TYPE,     "$comm and immediate-string only accepts string type"),\
-+      C(TOO_MANY_EARGS,       "Too many entry arguments specified"),
- #undef C
- #define C(a, b)               TP_ERR_##a
--- 
-2.39.5
-