1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */ |
3 | |
4 | #include <linux/bpf.h> |
5 | #include <bpf/bpf_helpers.h> |
6 | #include "bpf_misc.h" |
7 | |
8 | char _license[] SEC("license" ) = "GPL" ; |
9 | |
10 | struct sample { |
11 | int pid; |
12 | int seq; |
13 | long value; |
14 | char comm[16]; |
15 | }; |
16 | |
17 | struct { |
18 | __uint(type, BPF_MAP_TYPE_RINGBUF); |
19 | } ringbuf SEC(".maps" ); |
20 | |
21 | struct { |
22 | __uint(type, BPF_MAP_TYPE_HASH); |
23 | __uint(max_entries, 1000); |
24 | __type(key, struct sample); |
25 | __type(value, int); |
26 | } hash_map SEC(".maps" ); |
27 | |
28 | /* inputs */ |
29 | int pid = 0; |
30 | |
31 | /* inner state */ |
32 | long seq = 0; |
33 | |
34 | SEC("fentry/" SYS_PREFIX "sys_getpgid" ) |
35 | int test_ringbuf_mem_map_key(void *ctx) |
36 | { |
37 | int cur_pid = bpf_get_current_pid_tgid() >> 32; |
38 | struct sample *sample, sample_copy; |
39 | int *lookup_val; |
40 | |
41 | if (cur_pid != pid) |
42 | return 0; |
43 | |
44 | sample = bpf_ringbuf_reserve(&ringbuf, sizeof(*sample), 0); |
45 | if (!sample) |
46 | return 0; |
47 | |
48 | sample->pid = pid; |
49 | bpf_get_current_comm(sample->comm, sizeof(sample->comm)); |
50 | sample->seq = ++seq; |
51 | sample->value = 42; |
52 | |
53 | /* test using 'sample' (PTR_TO_MEM | MEM_ALLOC) as map key arg |
54 | */ |
55 | lookup_val = (int *)bpf_map_lookup_elem(&hash_map, sample); |
56 | __sink(lookup_val); |
57 | |
58 | /* workaround - memcpy is necessary so that verifier doesn't |
59 | * complain with: |
60 | * verifier internal error: more than one arg with ref_obj_id R3 |
61 | * when trying to do bpf_map_update_elem(&hash_map, sample, &sample->seq, BPF_ANY); |
62 | * |
63 | * Since bpf_map_lookup_elem above uses 'sample' as key, test using |
64 | * sample field as value below |
65 | */ |
66 | __builtin_memcpy(&sample_copy, sample, sizeof(struct sample)); |
67 | bpf_map_update_elem(&hash_map, &sample_copy, &sample->seq, BPF_ANY); |
68 | |
69 | bpf_ringbuf_submit(sample, 0); |
70 | return 0; |
71 | } |
72 | |