Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bpf-support-bpf_get_func_arg-for-bpf_trace_raw_tp'

Menglong Dong says:

====================
bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP

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 v5 -> v4:
* some format adjustment in the 1st patch
* v4: https://lore.kernel.org/bpf/20260120073046.324342-1-dongml2@chinatelecom.cn/

Changes v4 -> v3:
* fix the error of using bpf_get_func_arg() for BPF_TRACE_ITER
* v3: https://lore.kernel.org/bpf/20260119023732.130642-1-dongml2@chinatelecom.cn/

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/
====================

Link: https://patch.msgid.link/20260121044348.113201-1-dongml2@chinatelecom.cn
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+87 -6
+18 -4
kernel/bpf/verifier.c
··· 23741 23741 /* Implement bpf_get_func_arg inline. */ 23742 23742 if (prog_type == BPF_PROG_TYPE_TRACING && 23743 23743 insn->imm == BPF_FUNC_get_func_arg) { 23744 - /* Load nr_args from ctx - 8 */ 23745 - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 23744 + if (eatype == BPF_TRACE_RAW_TP) { 23745 + int nr_args = btf_type_vlen(prog->aux->attach_func_proto); 23746 + 23747 + /* skip 'void *__data' in btf_trace_##name() and save to reg0 */ 23748 + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args - 1); 23749 + } else { 23750 + /* Load nr_args from ctx - 8 */ 23751 + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 23752 + } 23746 23753 insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6); 23747 23754 insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3); 23748 23755 insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1); ··· 23801 23794 /* Implement get_func_arg_cnt inline. */ 23802 23795 if (prog_type == BPF_PROG_TYPE_TRACING && 23803 23796 insn->imm == BPF_FUNC_get_func_arg_cnt) { 23804 - /* Load nr_args from ctx - 8 */ 23805 - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 23797 + if (eatype == BPF_TRACE_RAW_TP) { 23798 + int nr_args = btf_type_vlen(prog->aux->attach_func_proto); 23799 + 23800 + /* skip 'void *__data' in btf_trace_##name() and save to reg0 */ 23801 + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args - 1); 23802 + } else { 23803 + /* Load nr_args from ctx - 8 */ 23804 + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 23805 + } 23806 23806 23807 23807 new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1); 23808 23808 if (!new_prog)
+8 -2
kernel/trace/bpf_trace.c
··· 1734 1734 case BPF_FUNC_d_path: 1735 1735 return &bpf_d_path_proto; 1736 1736 case BPF_FUNC_get_func_arg: 1737 - return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL; 1737 + if (bpf_prog_has_trampoline(prog) || 1738 + prog->expected_attach_type == BPF_TRACE_RAW_TP) 1739 + return &bpf_get_func_arg_proto; 1740 + return NULL; 1738 1741 case BPF_FUNC_get_func_ret: 1739 1742 return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL; 1740 1743 case BPF_FUNC_get_func_arg_cnt: 1741 - return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL; 1744 + if (bpf_prog_has_trampoline(prog) || 1745 + prog->expected_attach_type == BPF_TRACE_RAW_TP) 1746 + return &bpf_get_func_arg_cnt_proto; 1747 + return NULL; 1742 1748 case BPF_FUNC_get_attach_cookie: 1743 1749 if (prog->type == BPF_PROG_TYPE_TRACING && 1744 1750 prog->expected_attach_type == BPF_TRACE_RAW_TP)
+3
tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
··· 33 33 34 34 ASSERT_EQ(topts.retval >> 16, 1, "test_run"); 35 35 ASSERT_EQ(topts.retval & 0xffff, 1234 + 29, "test_run"); 36 + ASSERT_OK(trigger_module_test_read(1), "trigger_read"); 36 37 37 38 ASSERT_EQ(skel->bss->test1_result, 1, "test1_result"); 38 39 ASSERT_EQ(skel->bss->test2_result, 1, "test2_result"); 39 40 ASSERT_EQ(skel->bss->test3_result, 1, "test3_result"); 40 41 ASSERT_EQ(skel->bss->test4_result, 1, "test4_result"); 42 + ASSERT_EQ(skel->bss->test5_result, 1, "test5_result"); 43 + ASSERT_EQ(skel->bss->test6_result, 1, "test6_result"); 41 44 42 45 cleanup: 43 46 get_func_args_test__destroy(skel);
+44
tools/testing/selftests/bpf/progs/get_func_args_test.c
··· 121 121 test4_result &= err == 0 && ret == 1234; 122 122 return 0; 123 123 } 124 + 125 + __u64 test5_result = 0; 126 + SEC("tp_btf/bpf_testmod_fentry_test1_tp") 127 + int BPF_PROG(tp_test1) 128 + { 129 + __u64 cnt = bpf_get_func_arg_cnt(ctx); 130 + __u64 a = 0, z = 0; 131 + __s64 err; 132 + 133 + test5_result = cnt == 1; 134 + 135 + err = bpf_get_func_arg(ctx, 0, &a); 136 + test5_result &= err == 0 && ((int) a == 1); 137 + 138 + /* not valid argument */ 139 + err = bpf_get_func_arg(ctx, 1, &z); 140 + test5_result &= err == -EINVAL; 141 + 142 + return 0; 143 + } 144 + 145 + __u64 test6_result = 0; 146 + SEC("tp_btf/bpf_testmod_fentry_test2_tp") 147 + int BPF_PROG(tp_test2) 148 + { 149 + __u64 cnt = bpf_get_func_arg_cnt(ctx); 150 + __u64 a = 0, b = 0, z = 0; 151 + __s64 err; 152 + 153 + test6_result = cnt == 2; 154 + 155 + /* valid arguments */ 156 + err = bpf_get_func_arg(ctx, 0, &a); 157 + test6_result &= err == 0 && (int) a == 2; 158 + 159 + err = bpf_get_func_arg(ctx, 1, &b); 160 + test6_result &= err == 0 && b == 3; 161 + 162 + /* not valid argument */ 163 + err = bpf_get_func_arg(ctx, 2, &z); 164 + test6_result &= err == -EINVAL; 165 + 166 + return 0; 167 + }
+10
tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
··· 63 63 sizeof(struct bpf_testmod_test_writable_ctx) 64 64 ); 65 65 66 + DECLARE_TRACE(bpf_testmod_fentry_test1, 67 + TP_PROTO(int a), 68 + TP_ARGS(a) 69 + ); 70 + 71 + DECLARE_TRACE(bpf_testmod_fentry_test2, 72 + TP_PROTO(int a, u64 b), 73 + TP_ARGS(a, b) 74 + ); 75 + 66 76 #endif /* _BPF_TESTMOD_EVENTS_H */ 67 77 68 78 #undef TRACE_INCLUDE_PATH
+4
tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
··· 412 412 413 413 noinline int bpf_testmod_fentry_test1(int a) 414 414 { 415 + trace_bpf_testmod_fentry_test1_tp(a); 416 + 415 417 return a + 1; 416 418 } 417 419 418 420 noinline int bpf_testmod_fentry_test2(int a, u64 b) 419 421 { 422 + trace_bpf_testmod_fentry_test2_tp(a, b); 423 + 420 424 return a + b; 421 425 } 422 426