]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
fprobe: Use ftrace_regs in fprobe exit handler
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>
Thu, 26 Dec 2024 05:12:31 +0000 (14:12 +0900)
committerSteven Rostedt (Google) <rostedt@goodmis.org>
Thu, 26 Dec 2024 15:50:03 +0000 (10:50 -0500)
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>
arch/loongarch/Kconfig
arch/s390/Kconfig
arch/x86/Kconfig
include/linux/fprobe.h
include/linux/ftrace.h
kernel/trace/Kconfig
kernel/trace/bpf_trace.c
kernel/trace/fprobe.c
kernel/trace/trace_fprobe.c
lib/test_fprobe.c
samples/fprobe/fprobe_example.c

index 49f5bfc00e5a1ae289a57b981025f2072d315b0d..6396615ec035e6c648eb8d482efa09e0da9a4b73 100644 (file)
@@ -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
index 102029e56cf0c828b628cde297b02f7b2522d20a..d8eee56c10b61a6e57cbf5cedf7ee6ff70f2d655 100644 (file)
@@ -183,6 +183,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
index ff0d7e07c61146695c555395e2bb4b11eae949ee..6cb420783ef3c024ae256d2d9c39130a8425a91a 100644 (file)
@@ -225,6 +225,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
index ca64ee5e45d2c500383b47058c799a21e00fcf89..ef609bcca0f9221ad1bac5d0d04027198a7aaf45 100644 (file)
@@ -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);
 
 /**
index 9a1e768e47daa074f1ab53ec1bef62fc162faff2..bf8bb6c105533b0cff72d00d4ddc87ae4a1a83e1 100644 (file)
@@ -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)
index f10ca86fbfad2f3e7e526a2fe8ae19bed9fe3921..7f8165f2049a5533ed00f614fba48ef5129bae25 100644 (file)
@@ -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
index 7bb2e6ecd31f1ff67d2273b833b96fcc4181e39e..e469fcbed21053b461a2f8b7bbf0e31c68b438e1 100644 (file)
@@ -2830,10 +2830,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);
index 3d37892838739dc3a2319d3a419304ea0fb0a541..90a3c8e2bbdf1b85ff7a0735ed7e6ae68d27ab9c 100644 (file)
@@ -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);
 }
index 0f254685e26abf8c9ea76310cedefc290027b5f6..ed49d21269cf13ead5f565fff01ef6619c574eab 100644 (file)
@@ -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);
index ff607babba1890b974f8d11d7c814a1a29b519c7..271ce0caeec03672e90562386cdf74b20534ab88 100644 (file)
@@ -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);
index c234afae52d6f5966126e619e80618441ce6cb7a..bfe98ce826f3accf5c4bf5b7eaa493d58426a698 100644 (file)
@@ -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;