| // SPDX-License-Identifier: GPL-2.0 | |
| /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ | |
| #include "vmlinux.h" | |
| #include <bpf/bpf_helpers.h> | |
| #include "bpf_misc.h" | |
| struct bpf_iter_testmod_seq { | |
| u64 :64; | |
| u64 :64; | |
| }; | |
| extern int bpf_iter_testmod_seq_new(struct bpf_iter_testmod_seq *it, s64 value, int cnt) __ksym; | |
| extern s64 *bpf_iter_testmod_seq_next(struct bpf_iter_testmod_seq *it) __ksym; | |
| extern s64 bpf_iter_testmod_seq_value(int blah, struct bpf_iter_testmod_seq *it) __ksym; | |
| extern void bpf_iter_testmod_seq_destroy(struct bpf_iter_testmod_seq *it) __ksym; | |
| const volatile __s64 exp_empty = 0 + 1; | |
| __s64 res_empty; | |
| SEC("raw_tp/sys_enter") | |
| __success __log_level(2) | |
| __msg("fp-16=iter_testmod_seq(id=1,state=active,depth=0)") | |
| __msg("fp-16=iter_testmod_seq(id=1,state=drained,depth=0)") | |
| __msg("call bpf_iter_testmod_seq_destroy") | |
| int testmod_seq_empty(const void *ctx) | |
| { | |
| __s64 sum = 0, *i; | |
| bpf_for_each(testmod_seq, i, 1000, 0) sum += *i; | |
| res_empty = 1 + sum; | |
| return 0; | |
| } | |
| const volatile __s64 exp_full = 1000000; | |
| __s64 res_full; | |
| SEC("raw_tp/sys_enter") | |
| __success __log_level(2) | |
| __msg("fp-16=iter_testmod_seq(id=1,state=active,depth=0)") | |
| __msg("fp-16=iter_testmod_seq(id=1,state=drained,depth=0)") | |
| __msg("call bpf_iter_testmod_seq_destroy") | |
| int testmod_seq_full(const void *ctx) | |
| { | |
| __s64 sum = 0, *i; | |
| bpf_for_each(testmod_seq, i, 1000, 1000) sum += *i; | |
| res_full = sum; | |
| return 0; | |
| } | |
| const volatile __s64 exp_truncated = 10 * 1000000; | |
| __s64 res_truncated; | |
| static volatile int zero = 0; | |
| SEC("raw_tp/sys_enter") | |
| __success __log_level(2) | |
| __msg("fp-16=iter_testmod_seq(id=1,state=active,depth=0)") | |
| __msg("fp-16=iter_testmod_seq(id=1,state=drained,depth=0)") | |
| __msg("call bpf_iter_testmod_seq_destroy") | |
| int testmod_seq_truncated(const void *ctx) | |
| { | |
| __s64 sum = 0, *i; | |
| int cnt = zero; | |
| bpf_for_each(testmod_seq, i, 10, 2000000) { | |
| sum += *i; | |
| cnt++; | |
| if (cnt >= 1000000) | |
| break; | |
| } | |
| res_truncated = sum; | |
| return 0; | |
| } | |
| SEC("?raw_tp") | |
| __failure | |
| __msg("expected an initialized iter_testmod_seq as R2") | |
| int testmod_seq_getter_before_bad(const void *ctx) | |
| { | |
| struct bpf_iter_testmod_seq it; | |
| return bpf_iter_testmod_seq_value(0, &it); | |
| } | |
| SEC("?raw_tp") | |
| __failure | |
| __msg("expected an initialized iter_testmod_seq as R2") | |
| int testmod_seq_getter_after_bad(const void *ctx) | |
| { | |
| struct bpf_iter_testmod_seq it; | |
| s64 sum = 0, *v; | |
| bpf_iter_testmod_seq_new(&it, 100, 100); | |
| while ((v = bpf_iter_testmod_seq_next(&it))) { | |
| sum += *v; | |
| } | |
| bpf_iter_testmod_seq_destroy(&it); | |
| return sum + bpf_iter_testmod_seq_value(0, &it); | |
| } | |
| SEC("?socket") | |
| __success __retval(1000000) | |
| int testmod_seq_getter_good(const void *ctx) | |
| { | |
| struct bpf_iter_testmod_seq it; | |
| s64 sum = 0, *v; | |
| bpf_iter_testmod_seq_new(&it, 100, 100); | |
| while ((v = bpf_iter_testmod_seq_next(&it))) { | |
| sum += *v; | |
| } | |
| sum *= bpf_iter_testmod_seq_value(0, &it); | |
| bpf_iter_testmod_seq_destroy(&it); | |
| return sum; | |
| } | |
| char _license[] SEC("license") = "GPL"; |