135f14dbdSKumar Kartikeya Dwivedi // SPDX-License-Identifier: GPL-2.0
235f14dbdSKumar Kartikeya Dwivedi #include <vmlinux.h>
335f14dbdSKumar Kartikeya Dwivedi #include <bpf/bpf_tracing.h>
435f14dbdSKumar Kartikeya Dwivedi #include <bpf/bpf_helpers.h>
58e9af821SJiri Olsa #include "../bpf_testmod/bpf_testmod_kfunc.h"
635f14dbdSKumar Kartikeya Dwivedi
735f14dbdSKumar Kartikeya Dwivedi struct map_value {
803b77e17SAlexei Starovoitov struct prog_test_ref_kfunc __kptr *ptr;
935f14dbdSKumar Kartikeya Dwivedi };
1035f14dbdSKumar Kartikeya Dwivedi
1135f14dbdSKumar Kartikeya Dwivedi struct {
1235f14dbdSKumar Kartikeya Dwivedi __uint(type, BPF_MAP_TYPE_ARRAY);
1335f14dbdSKumar Kartikeya Dwivedi __type(key, int);
1435f14dbdSKumar Kartikeya Dwivedi __type(value, struct map_value);
1535f14dbdSKumar Kartikeya Dwivedi __uint(max_entries, 16);
1635f14dbdSKumar Kartikeya Dwivedi } array_map SEC(".maps");
1735f14dbdSKumar Kartikeya Dwivedi
cb1(void * map,void * key,void * value,void * ctx)1835f14dbdSKumar Kartikeya Dwivedi static __noinline int cb1(void *map, void *key, void *value, void *ctx)
1935f14dbdSKumar Kartikeya Dwivedi {
2035f14dbdSKumar Kartikeya Dwivedi void *p = *(void **)ctx;
2135f14dbdSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p);
2235f14dbdSKumar Kartikeya Dwivedi /* Without the fix this would cause underflow */
2335f14dbdSKumar Kartikeya Dwivedi return 0;
2435f14dbdSKumar Kartikeya Dwivedi }
2535f14dbdSKumar Kartikeya Dwivedi
2635f14dbdSKumar Kartikeya Dwivedi SEC("?tc")
underflow_prog(void * ctx)2735f14dbdSKumar Kartikeya Dwivedi int underflow_prog(void *ctx)
2835f14dbdSKumar Kartikeya Dwivedi {
2935f14dbdSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p;
3035f14dbdSKumar Kartikeya Dwivedi unsigned long sl = 0;
3135f14dbdSKumar Kartikeya Dwivedi
3235f14dbdSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&sl);
3335f14dbdSKumar Kartikeya Dwivedi if (!p)
3435f14dbdSKumar Kartikeya Dwivedi return 0;
3535f14dbdSKumar Kartikeya Dwivedi bpf_for_each_map_elem(&array_map, cb1, &p, 0);
36*b43550d7SEduard Zingerman bpf_kfunc_call_test_release(p);
3735f14dbdSKumar Kartikeya Dwivedi return 0;
3835f14dbdSKumar Kartikeya Dwivedi }
3935f14dbdSKumar Kartikeya Dwivedi
cb2(void * map,void * key,void * value,void * ctx)4035f14dbdSKumar Kartikeya Dwivedi static __always_inline int cb2(void *map, void *key, void *value, void *ctx)
4135f14dbdSKumar Kartikeya Dwivedi {
4235f14dbdSKumar Kartikeya Dwivedi unsigned long sl = 0;
4335f14dbdSKumar Kartikeya Dwivedi
4435f14dbdSKumar Kartikeya Dwivedi *(void **)ctx = bpf_kfunc_call_test_acquire(&sl);
4535f14dbdSKumar Kartikeya Dwivedi /* Without the fix this would leak memory */
4635f14dbdSKumar Kartikeya Dwivedi return 0;
4735f14dbdSKumar Kartikeya Dwivedi }
4835f14dbdSKumar Kartikeya Dwivedi
4935f14dbdSKumar Kartikeya Dwivedi SEC("?tc")
leak_prog(void * ctx)5035f14dbdSKumar Kartikeya Dwivedi int leak_prog(void *ctx)
5135f14dbdSKumar Kartikeya Dwivedi {
5235f14dbdSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p;
5335f14dbdSKumar Kartikeya Dwivedi struct map_value *v;
5435f14dbdSKumar Kartikeya Dwivedi
5535f14dbdSKumar Kartikeya Dwivedi v = bpf_map_lookup_elem(&array_map, &(int){0});
5635f14dbdSKumar Kartikeya Dwivedi if (!v)
5735f14dbdSKumar Kartikeya Dwivedi return 0;
5835f14dbdSKumar Kartikeya Dwivedi
5935f14dbdSKumar Kartikeya Dwivedi p = NULL;
6035f14dbdSKumar Kartikeya Dwivedi bpf_for_each_map_elem(&array_map, cb2, &p, 0);
6135f14dbdSKumar Kartikeya Dwivedi p = bpf_kptr_xchg(&v->ptr, p);
6235f14dbdSKumar Kartikeya Dwivedi if (p)
6335f14dbdSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p);
6435f14dbdSKumar Kartikeya Dwivedi return 0;
6535f14dbdSKumar Kartikeya Dwivedi }
6635f14dbdSKumar Kartikeya Dwivedi
cb(void * map,void * key,void * value,void * ctx)6735f14dbdSKumar Kartikeya Dwivedi static __always_inline int cb(void *map, void *key, void *value, void *ctx)
6835f14dbdSKumar Kartikeya Dwivedi {
6935f14dbdSKumar Kartikeya Dwivedi return 0;
7035f14dbdSKumar Kartikeya Dwivedi }
7135f14dbdSKumar Kartikeya Dwivedi
cb3(void * map,void * key,void * value,void * ctx)7235f14dbdSKumar Kartikeya Dwivedi static __always_inline int cb3(void *map, void *key, void *value, void *ctx)
7335f14dbdSKumar Kartikeya Dwivedi {
7435f14dbdSKumar Kartikeya Dwivedi unsigned long sl = 0;
7535f14dbdSKumar Kartikeya Dwivedi void *p;
7635f14dbdSKumar Kartikeya Dwivedi
7735f14dbdSKumar Kartikeya Dwivedi bpf_kfunc_call_test_acquire(&sl);
7835f14dbdSKumar Kartikeya Dwivedi bpf_for_each_map_elem(&array_map, cb, &p, 0);
7935f14dbdSKumar Kartikeya Dwivedi /* It should only complain here, not in cb. This is why we need
8035f14dbdSKumar Kartikeya Dwivedi * callback_ref to be set to frameno.
8135f14dbdSKumar Kartikeya Dwivedi */
8235f14dbdSKumar Kartikeya Dwivedi return 0;
8335f14dbdSKumar Kartikeya Dwivedi }
8435f14dbdSKumar Kartikeya Dwivedi
8535f14dbdSKumar Kartikeya Dwivedi SEC("?tc")
nested_cb(void * ctx)8635f14dbdSKumar Kartikeya Dwivedi int nested_cb(void *ctx)
8735f14dbdSKumar Kartikeya Dwivedi {
8835f14dbdSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p;
8935f14dbdSKumar Kartikeya Dwivedi unsigned long sl = 0;
9035f14dbdSKumar Kartikeya Dwivedi int sp = 0;
9135f14dbdSKumar Kartikeya Dwivedi
9235f14dbdSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&sl);
9335f14dbdSKumar Kartikeya Dwivedi if (!p)
9435f14dbdSKumar Kartikeya Dwivedi return 0;
9535f14dbdSKumar Kartikeya Dwivedi bpf_for_each_map_elem(&array_map, cb3, &sp, 0);
9635f14dbdSKumar Kartikeya Dwivedi bpf_kfunc_call_test_release(p);
9735f14dbdSKumar Kartikeya Dwivedi return 0;
9835f14dbdSKumar Kartikeya Dwivedi }
9935f14dbdSKumar Kartikeya Dwivedi
10035f14dbdSKumar Kartikeya Dwivedi SEC("?tc")
non_cb_transfer_ref(void * ctx)10135f14dbdSKumar Kartikeya Dwivedi int non_cb_transfer_ref(void *ctx)
10235f14dbdSKumar Kartikeya Dwivedi {
10335f14dbdSKumar Kartikeya Dwivedi struct prog_test_ref_kfunc *p;
10435f14dbdSKumar Kartikeya Dwivedi unsigned long sl = 0;
10535f14dbdSKumar Kartikeya Dwivedi
10635f14dbdSKumar Kartikeya Dwivedi p = bpf_kfunc_call_test_acquire(&sl);
10735f14dbdSKumar Kartikeya Dwivedi if (!p)
10835f14dbdSKumar Kartikeya Dwivedi return 0;
10935f14dbdSKumar Kartikeya Dwivedi cb1(NULL, NULL, NULL, &p);
11035f14dbdSKumar Kartikeya Dwivedi bpf_kfunc_call_test_acquire(&sl);
11135f14dbdSKumar Kartikeya Dwivedi return 0;
11235f14dbdSKumar Kartikeya Dwivedi }
11335f14dbdSKumar Kartikeya Dwivedi
11435f14dbdSKumar Kartikeya Dwivedi char _license[] SEC("license") = "GPL";
115