* [PATCH bpf-next v3 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
@ 2026-01-19 2:37 Menglong Dong
2026-01-19 2:37 ` [PATCH bpf-next v3 1/2] " Menglong Dong
2026-01-19 2:37 ` [PATCH bpf-next v3 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
0 siblings, 2 replies; 10+ messages in thread
From: Menglong Dong @ 2026-01-19 2:37 UTC (permalink / raw)
To: andrii, ast
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
Support bpf_get_func_arg() for BPF_TRACE_RAW_TP by getting the function
argument count from "prog->aux->attach_func_proto" during verifier inline.
Changes v3 -> v2:
* remove unnecessary NULL checking for prog->aux->attach_func_proto
* v2: https://lore.kernel.org/bpf/20260116071739.121182-1-dongml2@chinatelecom.cn/
Changes v2 -> v1:
* for nr_args, skip first 'void *__data' argument in btf_trace_##name
typedef
* check the result4 and result5 in the selftests
* v1: https://lore.kernel.org/bpf/20260116035024.98214-1-dongml2@chinatelecom.cn/
Menglong Dong (2):
bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
selftests/bpf: test bpf_get_func_arg() for tp_btf
kernel/bpf/verifier.c | 32 +++++++++++--
kernel/trace/bpf_trace.c | 4 +-
.../bpf/prog_tests/get_func_args_test.c | 3 ++
.../selftests/bpf/progs/get_func_args_test.c | 45 +++++++++++++++++++
.../bpf/test_kmods/bpf_testmod-events.h | 10 +++++
.../selftests/bpf/test_kmods/bpf_testmod.c | 4 ++
6 files changed, 92 insertions(+), 6 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 2:37 [PATCH bpf-next v3 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP Menglong Dong
@ 2026-01-19 2:37 ` Menglong Dong
2026-01-19 5:11 ` Yonghong Song
` (2 more replies)
2026-01-19 2:37 ` [PATCH bpf-next v3 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
1 sibling, 3 replies; 10+ messages in thread
From: Menglong Dong @ 2026-01-19 2:37 UTC (permalink / raw)
To: andrii, ast
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
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>
---
v3:
- remove unnecessary NULL checking for prog->aux->attach_func_proto
v2:
- for nr_args, skip first 'void *__data' argument in btf_trace_##name
typedef
---
kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
kernel/trace/bpf_trace.c | 4 ++--
2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index faa1ecc1fe9d..4f52342573f0 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
/* 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 first 'void *__data' argument in btf_trace_##name
+ * typedef
+ */
+ nr_args--;
+ /* Save nr_args to reg0 */
+ insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
+ } 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);
@@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
/* 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 first 'void *__data' argument in btf_trace_##name
+ * typedef
+ */
+ nr_args--;
+ /* Save nr_args to reg0 */
+ insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
+ } 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)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 6e076485bf70..9b1b56851d26 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1734,11 +1734,11 @@ 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;
+ return &bpf_get_func_arg_proto;
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;
+ return &bpf_get_func_arg_cnt_proto;
case BPF_FUNC_get_attach_cookie:
if (prog->type == BPF_PROG_TYPE_TRACING &&
prog->expected_attach_type == BPF_TRACE_RAW_TP)
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf-next v3 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf
2026-01-19 2:37 [PATCH bpf-next v3 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP Menglong Dong
2026-01-19 2:37 ` [PATCH bpf-next v3 1/2] " Menglong Dong
@ 2026-01-19 2:37 ` Menglong Dong
1 sibling, 0 replies; 10+ messages in thread
From: Menglong Dong @ 2026-01-19 2:37 UTC (permalink / raw)
To: andrii, ast
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
Test bpf_get_func_arg() and bpf_get_func_arg_cnt() for tp_btf. The code
is most copied from test1 and test2.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
.../bpf/prog_tests/get_func_args_test.c | 3 ++
.../selftests/bpf/progs/get_func_args_test.c | 44 +++++++++++++++++++
.../bpf/test_kmods/bpf_testmod-events.h | 10 +++++
.../selftests/bpf/test_kmods/bpf_testmod.c | 4 ++
4 files changed, 61 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c b/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
index 64a9c95d4acf..fadee95d3ae8 100644
--- a/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
@@ -33,11 +33,14 @@ void test_get_func_args_test(void)
ASSERT_EQ(topts.retval >> 16, 1, "test_run");
ASSERT_EQ(topts.retval & 0xffff, 1234 + 29, "test_run");
+ ASSERT_OK(trigger_module_test_read(1), "trigger_read");
ASSERT_EQ(skel->bss->test1_result, 1, "test1_result");
ASSERT_EQ(skel->bss->test2_result, 1, "test2_result");
ASSERT_EQ(skel->bss->test3_result, 1, "test3_result");
ASSERT_EQ(skel->bss->test4_result, 1, "test4_result");
+ ASSERT_EQ(skel->bss->test5_result, 1, "test5_result");
+ ASSERT_EQ(skel->bss->test6_result, 1, "test6_result");
cleanup:
get_func_args_test__destroy(skel);
diff --git a/tools/testing/selftests/bpf/progs/get_func_args_test.c b/tools/testing/selftests/bpf/progs/get_func_args_test.c
index e0f34a55e697..5b7233afef05 100644
--- a/tools/testing/selftests/bpf/progs/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/progs/get_func_args_test.c
@@ -121,3 +121,47 @@ int BPF_PROG(fexit_test, int _a, int *_b, int _ret)
test4_result &= err == 0 && ret == 1234;
return 0;
}
+
+__u64 test5_result = 0;
+SEC("tp_btf/bpf_testmod_fentry_test1_tp")
+int BPF_PROG(tp_test1)
+{
+ __u64 cnt = bpf_get_func_arg_cnt(ctx);
+ __u64 a = 0, z = 0;
+ __s64 err;
+
+ test5_result = cnt == 1;
+
+ err = bpf_get_func_arg(ctx, 0, &a);
+ test5_result &= err == 0 && ((int) a == 1);
+
+ /* not valid argument */
+ err = bpf_get_func_arg(ctx, 1, &z);
+ test5_result &= err == -EINVAL;
+
+ return 0;
+}
+
+__u64 test6_result = 0;
+SEC("tp_btf/bpf_testmod_fentry_test2_tp")
+int BPF_PROG(tp_test2)
+{
+ __u64 cnt = bpf_get_func_arg_cnt(ctx);
+ __u64 a = 0, b = 0, z = 0;
+ __s64 err;
+
+ test6_result = cnt == 2;
+
+ /* valid arguments */
+ err = bpf_get_func_arg(ctx, 0, &a);
+ test6_result &= err == 0 && (int) a == 2;
+
+ err = bpf_get_func_arg(ctx, 1, &b);
+ test6_result &= err == 0 && b == 3;
+
+ /* not valid argument */
+ err = bpf_get_func_arg(ctx, 2, &z);
+ test6_result &= err == -EINVAL;
+
+ return 0;
+}
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
index aeef86b3da74..45a5e41f3a92 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
@@ -63,6 +63,16 @@ BPF_TESTMOD_DECLARE_TRACE(bpf_testmod_test_writable_bare,
sizeof(struct bpf_testmod_test_writable_ctx)
);
+DECLARE_TRACE(bpf_testmod_fentry_test1,
+ TP_PROTO(int a),
+ TP_ARGS(a)
+);
+
+DECLARE_TRACE(bpf_testmod_fentry_test2,
+ TP_PROTO(int a, u64 b),
+ TP_ARGS(a, b)
+);
+
#endif /* _BPF_TESTMOD_EVENTS_H */
#undef TRACE_INCLUDE_PATH
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index bc07ce9d5477..f3698746f033 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -396,11 +396,15 @@ __weak noinline struct file *bpf_testmod_return_ptr(int arg)
noinline int bpf_testmod_fentry_test1(int a)
{
+ trace_bpf_testmod_fentry_test1_tp(a);
+
return a + 1;
}
noinline int bpf_testmod_fentry_test2(int a, u64 b)
{
+ trace_bpf_testmod_fentry_test2_tp(a, b);
+
return a + b;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 2:37 ` [PATCH bpf-next v3 1/2] " Menglong Dong
@ 2026-01-19 5:11 ` Yonghong Song
2026-01-19 5:59 ` Menglong Dong
2026-01-19 18:44 ` bot+bpf-ci
2026-01-19 23:37 ` Jiri Olsa
2 siblings, 1 reply; 10+ messages in thread
From: Yonghong Song @ 2026-01-19 5:11 UTC (permalink / raw)
To: Menglong Dong, andrii, ast
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
On 1/18/26 6:37 PM, Menglong Dong wrote:
> 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>
> ---
> v3:
> - remove unnecessary NULL checking for prog->aux->attach_func_proto
>
> v2:
> - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> typedef
> ---
> kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> kernel/trace/bpf_trace.c | 4 ++--
> 2 files changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index faa1ecc1fe9d..4f52342573f0 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* 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 first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> + } 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);
> @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* 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 first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> + } 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)
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 6e076485bf70..9b1b56851d26 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1734,11 +1734,11 @@ 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;
> + return &bpf_get_func_arg_proto;
BPF_TRACE_ITER is a tracing attach type. It should not support bpf_get_func_arg() or
bpf_get_func_arg_cnt().
> 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;
> + return &bpf_get_func_arg_cnt_proto;
> case BPF_FUNC_get_attach_cookie:
> if (prog->type == BPF_PROG_TYPE_TRACING &&
> prog->expected_attach_type == BPF_TRACE_RAW_TP)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 5:11 ` Yonghong Song
@ 2026-01-19 5:59 ` Menglong Dong
0 siblings, 0 replies; 10+ messages in thread
From: Menglong Dong @ 2026-01-19 5:59 UTC (permalink / raw)
To: Menglong Dong, Yonghong Song
Cc: andrii, ast, daniel, john.fastabend, martin.lau, eddyz87, song,
kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
On 2026/1/19 13:11 Yonghong Song <yonghong.song@linux.dev> write:
>
> On 1/18/26 6:37 PM, Menglong Dong wrote:
> > 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>
> > ---
> > v3:
> > - remove unnecessary NULL checking for prog->aux->attach_func_proto
> >
> > v2:
> > - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> > typedef
> > ---
> > kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> > kernel/trace/bpf_trace.c | 4 ++--
> > 2 files changed, 30 insertions(+), 6 deletions(-)
> >
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index faa1ecc1fe9d..4f52342573f0 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* 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 first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > + } 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);
> > @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* 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 first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > + } 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)
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index 6e076485bf70..9b1b56851d26 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> > @@ -1734,11 +1734,11 @@ 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;
> > + return &bpf_get_func_arg_proto;
>
> BPF_TRACE_ITER is a tracing attach type. It should not support bpf_get_func_arg() or
> bpf_get_func_arg_cnt().
Ah, my bad, I forgot BPF_TRACE_ITER. I'll fix it in the next version.
Thanks!
Menglong Dong
>
> > 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;
> > + return &bpf_get_func_arg_cnt_proto;
> > case BPF_FUNC_get_attach_cookie:
> > if (prog->type == BPF_PROG_TYPE_TRACING &&
> > prog->expected_attach_type == BPF_TRACE_RAW_TP)
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 2:37 ` [PATCH bpf-next v3 1/2] " Menglong Dong
2026-01-19 5:11 ` Yonghong Song
@ 2026-01-19 18:44 ` bot+bpf-ci
2026-01-20 3:37 ` Menglong Dong
2026-01-19 23:37 ` Jiri Olsa
2 siblings, 1 reply; 10+ messages in thread
From: bot+bpf-ci @ 2026-01-19 18:44 UTC (permalink / raw)
To: menglong8.dong, andrii, ast
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 3022 bytes --]
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index f73e08c223b5..64976009ba3c 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1734,11 +1734,11 @@ 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;
> + return &bpf_get_func_arg_proto;
Removing the bpf_prog_has_trampoline() check here allows all TRACING
program types to use bpf_get_func_arg(), not just RAW_TP and trampoline-
based types. In particular, BPF_TRACE_ITER programs can now use this
helper.
However, looking at do_misc_fixups() in verifier.c, the inline code
generation only handles BPF_TRACE_RAW_TP specially. For other non-
trampoline types like BPF_TRACE_ITER, the else branch generates:
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8)
This loads nr_args from ctx-8, but ITER programs use a different context
layout (e.g. struct bpf_iter__bpf_map_elem with meta, map, key, value
pointers). There is no nr_args at ctx-8 for ITER programs.
Would this cause ITER programs using bpf_get_func_arg() to read arbitrary
memory at ctx-8, potentially leaking kernel data or causing incorrect
bounds checks for subsequent argument access?
> 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;
> + return &bpf_get_func_arg_cnt_proto;
Same question applies here for bpf_get_func_arg_cnt() with ITER programs.
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 9de0ec0c3ed9..0b281b7c41eb 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -23323,8 +23323,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* Implement bpf_get_func_arg inline. */
> if (prog_type == BPF_PROG_TYPE_TRACING &&
> insn->imm == BPF_FUNC_get_func_arg) {
> + if (eatype == BPF_TRACE_RAW_TP) {
> + int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> +
> + /*
> + * skip first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> + } else {
> + /* Load nr_args from ctx - 8 */
> + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> + }
This else branch now applies to BPF_TRACE_ITER as well, since the
trampoline check was removed in tracing_prog_func_proto(). Should the
condition be extended to also handle ITER, or should ITER be explicitly
blocked from using these helpers?
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21147849826
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 2:37 ` [PATCH bpf-next v3 1/2] " Menglong Dong
2026-01-19 5:11 ` Yonghong Song
2026-01-19 18:44 ` bot+bpf-ci
@ 2026-01-19 23:37 ` Jiri Olsa
2026-01-20 1:24 ` Menglong Dong
2 siblings, 1 reply; 10+ messages in thread
From: Jiri Olsa @ 2026-01-19 23:37 UTC (permalink / raw)
To: Menglong Dong
Cc: andrii, ast, daniel, john.fastabend, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, mattbobrowski, rostedt,
mhiramat, mathieu.desnoyers, bpf, linux-kernel,
linux-trace-kernel
On Mon, Jan 19, 2026 at 10:37:31AM +0800, Menglong Dong wrote:
> 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>
> ---
> v3:
> - remove unnecessary NULL checking for prog->aux->attach_func_proto
>
> v2:
> - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> typedef
> ---
> kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> kernel/trace/bpf_trace.c | 4 ++--
> 2 files changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index faa1ecc1fe9d..4f52342573f0 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* 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 first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> + } 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);
> @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* 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 first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
I think we can attach single bpf program to multiple rawtp tracepoints,
in which case this would not work properly for such program links on
tracepoints with different nr_args, right?
jirka
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> + } 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)
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 6e076485bf70..9b1b56851d26 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1734,11 +1734,11 @@ 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;
> + return &bpf_get_func_arg_proto;
> 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;
> + return &bpf_get_func_arg_cnt_proto;
> case BPF_FUNC_get_attach_cookie:
> if (prog->type == BPF_PROG_TYPE_TRACING &&
> prog->expected_attach_type == BPF_TRACE_RAW_TP)
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 23:37 ` Jiri Olsa
@ 2026-01-20 1:24 ` Menglong Dong
2026-01-20 8:18 ` Jiri Olsa
0 siblings, 1 reply; 10+ messages in thread
From: Menglong Dong @ 2026-01-20 1:24 UTC (permalink / raw)
To: Menglong Dong, Jiri Olsa
Cc: andrii, ast, daniel, john.fastabend, martin.lau, eddyz87, song,
yonghong.song, kpsingh, sdf, haoluo, mattbobrowski, rostedt,
mhiramat, mathieu.desnoyers, bpf, linux-kernel,
linux-trace-kernel
On 2026/1/20 07:37, Jiri Olsa wrote:
> On Mon, Jan 19, 2026 at 10:37:31AM +0800, Menglong Dong wrote:
> > 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>
> > ---
> > v3:
> > - remove unnecessary NULL checking for prog->aux->attach_func_proto
> >
> > v2:
> > - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> > typedef
> > ---
> > kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> > kernel/trace/bpf_trace.c | 4 ++--
> > 2 files changed, 30 insertions(+), 6 deletions(-)
> >
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index faa1ecc1fe9d..4f52342573f0 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* 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 first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > + } 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);
> > @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* 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 first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
>
> I think we can attach single bpf program to multiple rawtp tracepoints,
> in which case this would not work properly for such program links on
> tracepoints with different nr_args, right?
Hi, Jiri. As for now, I think we can't do that when I look into
bpf_raw_tp_link_attach(). For the BPF_TRACE_RAW_TP, we specify
a target btf type id when loading the bpf prog. And during
attaching, it seems that we can only attach to that target, which
means that we can't attach to multiple rawtp tracepoint. And
we can't change the target btf id when reattach, too. Right?
Part of the implement of bpf_raw_tp_link_attach():
static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
const char __user *user_tp_name, u64 cookie,
enum bpf_attach_type attach_type)
{
struct bpf_link_primer link_primer;
struct bpf_raw_tp_link *link;
struct bpf_raw_event_map *btp;
const char *tp_name;
char buf[128];
int err;
switch (prog->type) {
case BPF_PROG_TYPE_TRACING:
case BPF_PROG_TYPE_EXT:
case BPF_PROG_TYPE_LSM:
if (user_tp_name)
/* The attach point for this category of programs
* should be specified via btf_id during program load.
*/
return -EINVAL;
if (prog->type == BPF_PROG_TYPE_TRACING &&
prog->expected_attach_type == BPF_TRACE_RAW_TP) {
tp_name = prog->aux->attach_func_name;
break;
}
[......]
}
[......]
}
Thanks!
Menglong Dong
>
> jirka
>
>
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > + } 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)
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index 6e076485bf70..9b1b56851d26 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> > @@ -1734,11 +1734,11 @@ 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;
> > + return &bpf_get_func_arg_proto;
> > 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;
> > + return &bpf_get_func_arg_cnt_proto;
> > case BPF_FUNC_get_attach_cookie:
> > if (prog->type == BPF_PROG_TYPE_TRACING &&
> > prog->expected_attach_type == BPF_TRACE_RAW_TP)
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-19 18:44 ` bot+bpf-ci
@ 2026-01-20 3:37 ` Menglong Dong
0 siblings, 0 replies; 10+ messages in thread
From: Menglong Dong @ 2026-01-20 3:37 UTC (permalink / raw)
To: menglong8.dong, andrii, ast, bot+bpf-ci
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, yonghong.song,
kpsingh, sdf, haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
On 2026/1/20 02:44, bot+bpf-ci@kernel.org wrote:
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index f73e08c223b5..64976009ba3c 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> > @@ -1734,11 +1734,11 @@ 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;
> > + return &bpf_get_func_arg_proto;
>
> Removing the bpf_prog_has_trampoline() check here allows all TRACING
> program types to use bpf_get_func_arg(), not just RAW_TP and trampoline-
> based types. In particular, BPF_TRACE_ITER programs can now use this
> helper.
>
> However, looking at do_misc_fixups() in verifier.c, the inline code
> generation only handles BPF_TRACE_RAW_TP specially. For other non-
> trampoline types like BPF_TRACE_ITER, the else branch generates:
>
> BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8)
>
> This loads nr_args from ctx-8, but ITER programs use a different context
> layout (e.g. struct bpf_iter__bpf_map_elem with meta, map, key, value
> pointers). There is no nr_args at ctx-8 for ITER programs.
>
> Would this cause ITER programs using bpf_get_func_arg() to read arbitrary
> memory at ctx-8, potentially leaking kernel data or causing incorrect
> bounds checks for subsequent argument access?
You are right. As Yonghong said, I missed the bpf_iter case, and it should
be skipped.
I'll fix it in the next version.
>
> > 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;
> > + return &bpf_get_func_arg_cnt_proto;
>
> Same question applies here for bpf_get_func_arg_cnt() with ITER programs.
>
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index 9de0ec0c3ed9..0b281b7c41eb 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -23323,8 +23323,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* Implement bpf_get_func_arg inline. */
> > if (prog_type == BPF_PROG_TYPE_TRACING &&
> > insn->imm == BPF_FUNC_get_func_arg) {
> > + if (eatype == BPF_TRACE_RAW_TP) {
> > + int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> > +
> > + /*
> > + * skip first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > + } else {
> > + /* Load nr_args from ctx - 8 */
> > + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > + }
>
> This else branch now applies to BPF_TRACE_ITER as well, since the
> trampoline check was removed in tracing_prog_func_proto(). Should the
> condition be extended to also handle ITER, or should ITER be explicitly
> blocked from using these helpers?
>
> [ ... ]
>
>
> ---
> AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
>
> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21147849826
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-20 1:24 ` Menglong Dong
@ 2026-01-20 8:18 ` Jiri Olsa
0 siblings, 0 replies; 10+ messages in thread
From: Jiri Olsa @ 2026-01-20 8:18 UTC (permalink / raw)
To: Menglong Dong
Cc: Menglong Dong, Jiri Olsa, andrii, ast, daniel, john.fastabend,
martin.lau, eddyz87, song, yonghong.song, kpsingh, sdf, haoluo,
mattbobrowski, rostedt, mhiramat, mathieu.desnoyers, bpf,
linux-kernel, linux-trace-kernel
On Tue, Jan 20, 2026 at 09:24:46AM +0800, Menglong Dong wrote:
> On 2026/1/20 07:37, Jiri Olsa wrote:
> > On Mon, Jan 19, 2026 at 10:37:31AM +0800, Menglong Dong wrote:
> > > 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>
> > > ---
> > > v3:
> > > - remove unnecessary NULL checking for prog->aux->attach_func_proto
> > >
> > > v2:
> > > - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> > > typedef
> > > ---
> > > kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> > > kernel/trace/bpf_trace.c | 4 ++--
> > > 2 files changed, 30 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > > index faa1ecc1fe9d..4f52342573f0 100644
> > > --- a/kernel/bpf/verifier.c
> > > +++ b/kernel/bpf/verifier.c
> > > @@ -23316,8 +23316,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > > /* 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 first 'void *__data' argument in btf_trace_##name
> > > + * typedef
> > > + */
> > > + nr_args--;
> > > + /* Save nr_args to reg0 */
> > > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > > + } 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);
> > > @@ -23369,8 +23381,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > > /* 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 first 'void *__data' argument in btf_trace_##name
> > > + * typedef
> > > + */
> > > + nr_args--;
> > > + /* Save nr_args to reg0 */
> >
> > I think we can attach single bpf program to multiple rawtp tracepoints,
> > in which case this would not work properly for such program links on
> > tracepoints with different nr_args, right?
>
> Hi, Jiri. As for now, I think we can't do that when I look into
> bpf_raw_tp_link_attach(). For the BPF_TRACE_RAW_TP, we specify
> a target btf type id when loading the bpf prog. And during
> attaching, it seems that we can only attach to that target, which
> means that we can't attach to multiple rawtp tracepoint. And
> we can't change the target btf id when reattach, too. Right?
>
> Part of the implement of bpf_raw_tp_link_attach():
>
> static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
> const char __user *user_tp_name, u64 cookie,
> enum bpf_attach_type attach_type)
> {
> struct bpf_link_primer link_primer;
> struct bpf_raw_tp_link *link;
> struct bpf_raw_event_map *btp;
> const char *tp_name;
> char buf[128];
> int err;
>
> switch (prog->type) {
> case BPF_PROG_TYPE_TRACING:
> case BPF_PROG_TYPE_EXT:
> case BPF_PROG_TYPE_LSM:
> if (user_tp_name)
> /* The attach point for this category of programs
> * should be specified via btf_id during program load.
> */
ah there's the name check, ok.. got confused by the max_ctx_offset
check in bpf_probe_register
thanks,
jirka
> return -EINVAL;
> if (prog->type == BPF_PROG_TYPE_TRACING &&
> prog->expected_attach_type == BPF_TRACE_RAW_TP) {
> tp_name = prog->aux->attach_func_name;
> break;
> }
> [......]
> }
> [......]
> }
>
> Thanks!
> Menglong Dong
>
> >
> > jirka
> >
> >
> > > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > > + } 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)
> > > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > > index 6e076485bf70..9b1b56851d26 100644
> > > --- a/kernel/trace/bpf_trace.c
> > > +++ b/kernel/trace/bpf_trace.c
> > > @@ -1734,11 +1734,11 @@ 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;
> > > + return &bpf_get_func_arg_proto;
> > > 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;
> > > + return &bpf_get_func_arg_cnt_proto;
> > > case BPF_FUNC_get_attach_cookie:
> > > if (prog->type == BPF_PROG_TYPE_TRACING &&
> > > prog->expected_attach_type == BPF_TRACE_RAW_TP)
> >
> >
>
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-01-20 8:18 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-19 2:37 [PATCH bpf-next v3 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP Menglong Dong
2026-01-19 2:37 ` [PATCH bpf-next v3 1/2] " Menglong Dong
2026-01-19 5:11 ` Yonghong Song
2026-01-19 5:59 ` Menglong Dong
2026-01-19 18:44 ` bot+bpf-ci
2026-01-20 3:37 ` Menglong Dong
2026-01-19 23:37 ` Jiri Olsa
2026-01-20 1:24 ` Menglong Dong
2026-01-20 8:18 ` Jiri Olsa
2026-01-19 2:37 ` [PATCH bpf-next v3 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox