]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
authorMenglong Dong <menglong8.dong@gmail.com>
Wed, 21 Jan 2026 04:43:47 +0000 (12:43 +0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 21 Jan 2026 17:31:35 +0000 (09:31 -0800)
For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
tracepoint, especially for the case that the position of the arguments in
a tracepoint can change.

The target tracepoint BTF type id is specified during loading time,
therefore we can get the function argument count from the function
prototype instead of the stack.

Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20260121044348.113201-2-dongml2@chinatelecom.cn
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c
kernel/trace/bpf_trace.c

index 9905ad40f4d365c4b393106f52c617b1e0d0fcf3..c7f5234d5fd220de456cf5808b623f7a3fca440f 100644 (file)
@@ -23741,8 +23741,15 @@ patch_map_ops_generic:
                /* Implement bpf_get_func_arg inline. */
                if (prog_type == BPF_PROG_TYPE_TRACING &&
                    insn->imm == BPF_FUNC_get_func_arg) {
-                       /* Load nr_args from ctx - 8 */
-                       insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+                       if (eatype == BPF_TRACE_RAW_TP) {
+                               int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
+
+                               /* skip 'void *__data' in btf_trace_##name() and save to reg0 */
+                               insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args - 1);
+                       } else {
+                               /* Load nr_args from ctx - 8 */
+                               insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+                       }
                        insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
                        insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
                        insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
@@ -23794,8 +23801,15 @@ patch_map_ops_generic:
                /* Implement get_func_arg_cnt inline. */
                if (prog_type == BPF_PROG_TYPE_TRACING &&
                    insn->imm == BPF_FUNC_get_func_arg_cnt) {
-                       /* Load nr_args from ctx - 8 */
-                       insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+                       if (eatype == BPF_TRACE_RAW_TP) {
+                               int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
+
+                               /* skip 'void *__data' in btf_trace_##name() and save to reg0 */
+                               insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args - 1);
+                       } else {
+                               /* Load nr_args from ctx - 8 */
+                               insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+                       }
 
                        new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
                        if (!new_prog)
index bd15ff62490b01eb20fc7e0f965c63361e30b18c..0e9635bcd783fcc0b7aa50be1334b2005a460359 100644 (file)
@@ -1734,11 +1734,17 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
        case BPF_FUNC_d_path:
                return &bpf_d_path_proto;
        case BPF_FUNC_get_func_arg:
-               return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
+               if (bpf_prog_has_trampoline(prog) ||
+                   prog->expected_attach_type == BPF_TRACE_RAW_TP)
+                       return &bpf_get_func_arg_proto;
+               return NULL;
        case BPF_FUNC_get_func_ret:
                return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
        case BPF_FUNC_get_func_arg_cnt:
-               return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
+               if (bpf_prog_has_trampoline(prog) ||
+                   prog->expected_attach_type == BPF_TRACE_RAW_TP)
+                       return &bpf_get_func_arg_cnt_proto;
+               return NULL;
        case BPF_FUNC_get_attach_cookie:
                if (prog->type == BPF_PROG_TYPE_TRACING &&
                    prog->expected_attach_type == BPF_TRACE_RAW_TP)