On Tue, Dec 07, 2021 at 02:54:33PM -0800, Andrii Nakryiko wrote: SNIP > > > > +__u64 test1_result = 0; > > > > +SEC("fentry/bpf_fentry_test1") > > > > +int BPF_PROG(test1) > > > > +{ > > > > + __u64 cnt = bpf_get_func_arg_cnt(ctx); > > > > + __u64 a = 0, z = 0, ret = 0; > > > > + __s64 err; > > > > + > > > > + test1_result = cnt == 1; > > > > + > > > > + /* valid arguments */ > > > > + err = bpf_get_func_arg(ctx, 0, &a); > > > > + test1_result &= err == 0 && (int) a == 1; > > > > > > > > > int cast unnecessary? but some ()'s wouldn't hurt... > > > > it is, 'a' is int and trampoline saves it with 32-bit register like: > > > > mov %edi,-0x8(%rbp) > > > > so the upper 4 bytes are not zeroed > > oh, this is definitely worth a comment, it's quite a big gotcha we'll > need to remember ok, will add comment for that jirka > > > > > > > > > > > > > > + > > > > + /* not valid argument */ > > > > + err = bpf_get_func_arg(ctx, 1, &z); > > > > + test1_result &= err == -EINVAL; > > > > + > > > > + /* return value fails in fentry */ > > > > + err = bpf_get_func_ret(ctx, &ret); > > > > + test1_result &= err == -EINVAL; > > > > + return 0; > > > > +} > > > > + > > > > +__u64 test2_result = 0; > > > > +SEC("fexit/bpf_fentry_test2") > > > > +int BPF_PROG(test2) > > > > +{ > > > > + __u64 cnt = bpf_get_func_arg_cnt(ctx); > > > > + __u64 a = 0, b = 0, z = 0, ret = 0; > > > > + __s64 err; > > > > + > > > > + test2_result = cnt == 2; > > > > + > > > > + /* valid arguments */ > > > > + err = bpf_get_func_arg(ctx, 0, &a); > > > > + test2_result &= err == 0 && (int) a == 2; > > > > + > > > > + err = bpf_get_func_arg(ctx, 1, &b); > > > > + test2_result &= err == 0 && b == 3; > > > > + > > > > + /* not valid argument */ > > > > + err = bpf_get_func_arg(ctx, 2, &z); > > > > + test2_result &= err == -EINVAL; > > > > + > > > > + /* return value */ > > > > + err = bpf_get_func_ret(ctx, &ret); > > > > + test2_result &= err == 0 && ret == 5; > > > > + return 0; > > > > +} > > > > + > > > > +__u64 test3_result = 0; > > > > +SEC("fmod_ret/bpf_modify_return_test") > > > > +int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret) > > > > +{ > > > > + __u64 cnt = bpf_get_func_arg_cnt(ctx); > > > > + __u64 a = 0, b = 0, z = 0, ret = 0; > > > > + __s64 err; > > > > + > > > > + test3_result = cnt == 2; > > > > + > > > > + /* valid arguments */ > > > > + err = bpf_get_func_arg(ctx, 0, &a); > > > > + test3_result &= err == 0 && (int) a == 1; > > > > + > > > > + err = bpf_get_func_arg(ctx, 1, &b); > > > > + test3_result &= err == 0; > > > > > > > > > why no checking of b value here? > > > > right, ok > > > > > > > > > + > > > > + /* not valid argument */ > > > > + err = bpf_get_func_arg(ctx, 2, &z); > > > > + test3_result &= err == -EINVAL; > > > > + > > > > + /* return value */ > > > > + err = bpf_get_func_ret(ctx, &ret); > > > > + test3_result &= err == 0 && ret == 0; > > > > + return 1234; > > > > +} > > > > + > > > > +__u64 test4_result = 0; > > > > +SEC("fexit/bpf_modify_return_test") > > > > +int BPF_PROG(fexit_test, int _a, __u64 _b, int _ret) > > > > +{ > > > > + __u64 cnt = bpf_get_func_arg_cnt(ctx); > > > > + __u64 a = 0, b = 0, z = 0, ret = 0; > > > > + __s64 err; > > > > + > > > > + test4_result = cnt == 2; > > > > + > > > > + /* valid arguments */ > > > > + err = bpf_get_func_arg(ctx, 0, &a); > > > > + test4_result &= err == 0 && (int) a == 1; > > > > + > > > > + err = bpf_get_func_arg(ctx, 1, &b); > > > > + test4_result &= err == 0; > > > > > > > > > same, for consistency, b should have been checked, no? > > > > ok > > > > thanks, > > jirka > > >