1*f7c14bbaSAndroid Build Coastguard Worker /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
2*f7c14bbaSAndroid Build Coastguard Worker /* Copyright (c) 2021 Facebook */
3*f7c14bbaSAndroid Build Coastguard Worker #ifndef __SKEL_INTERNAL_H
4*f7c14bbaSAndroid Build Coastguard Worker #define __SKEL_INTERNAL_H
5*f7c14bbaSAndroid Build Coastguard Worker
6*f7c14bbaSAndroid Build Coastguard Worker #ifdef __KERNEL__
7*f7c14bbaSAndroid Build Coastguard Worker #include <linux/fdtable.h>
8*f7c14bbaSAndroid Build Coastguard Worker #include <linux/mm.h>
9*f7c14bbaSAndroid Build Coastguard Worker #include <linux/mman.h>
10*f7c14bbaSAndroid Build Coastguard Worker #include <linux/slab.h>
11*f7c14bbaSAndroid Build Coastguard Worker #include <linux/bpf.h>
12*f7c14bbaSAndroid Build Coastguard Worker #else
13*f7c14bbaSAndroid Build Coastguard Worker #include <unistd.h>
14*f7c14bbaSAndroid Build Coastguard Worker #include <sys/syscall.h>
15*f7c14bbaSAndroid Build Coastguard Worker #include <sys/mman.h>
16*f7c14bbaSAndroid Build Coastguard Worker #include <stdlib.h>
17*f7c14bbaSAndroid Build Coastguard Worker #include "bpf.h"
18*f7c14bbaSAndroid Build Coastguard Worker #endif
19*f7c14bbaSAndroid Build Coastguard Worker
20*f7c14bbaSAndroid Build Coastguard Worker #ifndef __NR_bpf
21*f7c14bbaSAndroid Build Coastguard Worker # if defined(__mips__) && defined(_ABIO32)
22*f7c14bbaSAndroid Build Coastguard Worker # define __NR_bpf 4355
23*f7c14bbaSAndroid Build Coastguard Worker # elif defined(__mips__) && defined(_ABIN32)
24*f7c14bbaSAndroid Build Coastguard Worker # define __NR_bpf 6319
25*f7c14bbaSAndroid Build Coastguard Worker # elif defined(__mips__) && defined(_ABI64)
26*f7c14bbaSAndroid Build Coastguard Worker # define __NR_bpf 5315
27*f7c14bbaSAndroid Build Coastguard Worker # endif
28*f7c14bbaSAndroid Build Coastguard Worker #endif
29*f7c14bbaSAndroid Build Coastguard Worker
30*f7c14bbaSAndroid Build Coastguard Worker /* This file is a base header for auto-generated *.lskel.h files.
31*f7c14bbaSAndroid Build Coastguard Worker * Its contents will change and may become part of auto-generation in the future.
32*f7c14bbaSAndroid Build Coastguard Worker *
33*f7c14bbaSAndroid Build Coastguard Worker * The layout of bpf_[map|prog]_desc and bpf_loader_ctx is feature dependent
34*f7c14bbaSAndroid Build Coastguard Worker * and will change from one version of libbpf to another and features
35*f7c14bbaSAndroid Build Coastguard Worker * requested during loader program generation.
36*f7c14bbaSAndroid Build Coastguard Worker */
37*f7c14bbaSAndroid Build Coastguard Worker struct bpf_map_desc {
38*f7c14bbaSAndroid Build Coastguard Worker /* output of the loader prog */
39*f7c14bbaSAndroid Build Coastguard Worker int map_fd;
40*f7c14bbaSAndroid Build Coastguard Worker /* input for the loader prog */
41*f7c14bbaSAndroid Build Coastguard Worker __u32 max_entries;
42*f7c14bbaSAndroid Build Coastguard Worker __aligned_u64 initial_value;
43*f7c14bbaSAndroid Build Coastguard Worker };
44*f7c14bbaSAndroid Build Coastguard Worker struct bpf_prog_desc {
45*f7c14bbaSAndroid Build Coastguard Worker int prog_fd;
46*f7c14bbaSAndroid Build Coastguard Worker };
47*f7c14bbaSAndroid Build Coastguard Worker
48*f7c14bbaSAndroid Build Coastguard Worker enum {
49*f7c14bbaSAndroid Build Coastguard Worker BPF_SKEL_KERNEL = (1ULL << 0),
50*f7c14bbaSAndroid Build Coastguard Worker };
51*f7c14bbaSAndroid Build Coastguard Worker
52*f7c14bbaSAndroid Build Coastguard Worker struct bpf_loader_ctx {
53*f7c14bbaSAndroid Build Coastguard Worker __u32 sz;
54*f7c14bbaSAndroid Build Coastguard Worker __u32 flags;
55*f7c14bbaSAndroid Build Coastguard Worker __u32 log_level;
56*f7c14bbaSAndroid Build Coastguard Worker __u32 log_size;
57*f7c14bbaSAndroid Build Coastguard Worker __u64 log_buf;
58*f7c14bbaSAndroid Build Coastguard Worker };
59*f7c14bbaSAndroid Build Coastguard Worker
60*f7c14bbaSAndroid Build Coastguard Worker struct bpf_load_and_run_opts {
61*f7c14bbaSAndroid Build Coastguard Worker struct bpf_loader_ctx *ctx;
62*f7c14bbaSAndroid Build Coastguard Worker const void *data;
63*f7c14bbaSAndroid Build Coastguard Worker const void *insns;
64*f7c14bbaSAndroid Build Coastguard Worker __u32 data_sz;
65*f7c14bbaSAndroid Build Coastguard Worker __u32 insns_sz;
66*f7c14bbaSAndroid Build Coastguard Worker const char *errstr;
67*f7c14bbaSAndroid Build Coastguard Worker };
68*f7c14bbaSAndroid Build Coastguard Worker
69*f7c14bbaSAndroid Build Coastguard Worker long kern_sys_bpf(__u32 cmd, void *attr, __u32 attr_size);
70*f7c14bbaSAndroid Build Coastguard Worker
skel_sys_bpf(enum bpf_cmd cmd,union bpf_attr * attr,unsigned int size)71*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
72*f7c14bbaSAndroid Build Coastguard Worker unsigned int size)
73*f7c14bbaSAndroid Build Coastguard Worker {
74*f7c14bbaSAndroid Build Coastguard Worker #ifdef __KERNEL__
75*f7c14bbaSAndroid Build Coastguard Worker return kern_sys_bpf(cmd, attr, size);
76*f7c14bbaSAndroid Build Coastguard Worker #else
77*f7c14bbaSAndroid Build Coastguard Worker return syscall(__NR_bpf, cmd, attr, size);
78*f7c14bbaSAndroid Build Coastguard Worker #endif
79*f7c14bbaSAndroid Build Coastguard Worker }
80*f7c14bbaSAndroid Build Coastguard Worker
81*f7c14bbaSAndroid Build Coastguard Worker #ifdef __KERNEL__
close(int fd)82*f7c14bbaSAndroid Build Coastguard Worker static inline int close(int fd)
83*f7c14bbaSAndroid Build Coastguard Worker {
84*f7c14bbaSAndroid Build Coastguard Worker return close_fd(fd);
85*f7c14bbaSAndroid Build Coastguard Worker }
86*f7c14bbaSAndroid Build Coastguard Worker
skel_alloc(size_t size)87*f7c14bbaSAndroid Build Coastguard Worker static inline void *skel_alloc(size_t size)
88*f7c14bbaSAndroid Build Coastguard Worker {
89*f7c14bbaSAndroid Build Coastguard Worker struct bpf_loader_ctx *ctx = kzalloc(size, GFP_KERNEL);
90*f7c14bbaSAndroid Build Coastguard Worker
91*f7c14bbaSAndroid Build Coastguard Worker if (!ctx)
92*f7c14bbaSAndroid Build Coastguard Worker return NULL;
93*f7c14bbaSAndroid Build Coastguard Worker ctx->flags |= BPF_SKEL_KERNEL;
94*f7c14bbaSAndroid Build Coastguard Worker return ctx;
95*f7c14bbaSAndroid Build Coastguard Worker }
96*f7c14bbaSAndroid Build Coastguard Worker
skel_free(const void * p)97*f7c14bbaSAndroid Build Coastguard Worker static inline void skel_free(const void *p)
98*f7c14bbaSAndroid Build Coastguard Worker {
99*f7c14bbaSAndroid Build Coastguard Worker kfree(p);
100*f7c14bbaSAndroid Build Coastguard Worker }
101*f7c14bbaSAndroid Build Coastguard Worker
102*f7c14bbaSAndroid Build Coastguard Worker /* skel->bss/rodata maps are populated the following way:
103*f7c14bbaSAndroid Build Coastguard Worker *
104*f7c14bbaSAndroid Build Coastguard Worker * For kernel use:
105*f7c14bbaSAndroid Build Coastguard Worker * skel_prep_map_data() allocates kernel memory that kernel module can directly access.
106*f7c14bbaSAndroid Build Coastguard Worker * Generated lskel stores the pointer in skel->rodata and in skel->maps.rodata.initial_value.
107*f7c14bbaSAndroid Build Coastguard Worker * The loader program will perform probe_read_kernel() from maps.rodata.initial_value.
108*f7c14bbaSAndroid Build Coastguard Worker * skel_finalize_map_data() sets skel->rodata to point to actual value in a bpf map and
109*f7c14bbaSAndroid Build Coastguard Worker * does maps.rodata.initial_value = ~0ULL to signal skel_free_map_data() that kvfree
110*f7c14bbaSAndroid Build Coastguard Worker * is not nessary.
111*f7c14bbaSAndroid Build Coastguard Worker *
112*f7c14bbaSAndroid Build Coastguard Worker * For user space:
113*f7c14bbaSAndroid Build Coastguard Worker * skel_prep_map_data() mmaps anon memory into skel->rodata that can be accessed directly.
114*f7c14bbaSAndroid Build Coastguard Worker * Generated lskel stores the pointer in skel->rodata and in skel->maps.rodata.initial_value.
115*f7c14bbaSAndroid Build Coastguard Worker * The loader program will perform copy_from_user() from maps.rodata.initial_value.
116*f7c14bbaSAndroid Build Coastguard Worker * skel_finalize_map_data() remaps bpf array map value from the kernel memory into
117*f7c14bbaSAndroid Build Coastguard Worker * skel->rodata address.
118*f7c14bbaSAndroid Build Coastguard Worker *
119*f7c14bbaSAndroid Build Coastguard Worker * The "bpftool gen skeleton -L" command generates lskel.h that is suitable for
120*f7c14bbaSAndroid Build Coastguard Worker * both kernel and user space. The generated loader program does
121*f7c14bbaSAndroid Build Coastguard Worker * either bpf_probe_read_kernel() or bpf_copy_from_user() from initial_value
122*f7c14bbaSAndroid Build Coastguard Worker * depending on bpf_loader_ctx->flags.
123*f7c14bbaSAndroid Build Coastguard Worker */
skel_free_map_data(void * p,__u64 addr,size_t sz)124*f7c14bbaSAndroid Build Coastguard Worker static inline void skel_free_map_data(void *p, __u64 addr, size_t sz)
125*f7c14bbaSAndroid Build Coastguard Worker {
126*f7c14bbaSAndroid Build Coastguard Worker if (addr != ~0ULL)
127*f7c14bbaSAndroid Build Coastguard Worker kvfree(p);
128*f7c14bbaSAndroid Build Coastguard Worker /* When addr == ~0ULL the 'p' points to
129*f7c14bbaSAndroid Build Coastguard Worker * ((struct bpf_array *)map)->value. See skel_finalize_map_data.
130*f7c14bbaSAndroid Build Coastguard Worker */
131*f7c14bbaSAndroid Build Coastguard Worker }
132*f7c14bbaSAndroid Build Coastguard Worker
skel_prep_map_data(const void * val,size_t mmap_sz,size_t val_sz)133*f7c14bbaSAndroid Build Coastguard Worker static inline void *skel_prep_map_data(const void *val, size_t mmap_sz, size_t val_sz)
134*f7c14bbaSAndroid Build Coastguard Worker {
135*f7c14bbaSAndroid Build Coastguard Worker void *addr;
136*f7c14bbaSAndroid Build Coastguard Worker
137*f7c14bbaSAndroid Build Coastguard Worker addr = kvmalloc(val_sz, GFP_KERNEL);
138*f7c14bbaSAndroid Build Coastguard Worker if (!addr)
139*f7c14bbaSAndroid Build Coastguard Worker return NULL;
140*f7c14bbaSAndroid Build Coastguard Worker memcpy(addr, val, val_sz);
141*f7c14bbaSAndroid Build Coastguard Worker return addr;
142*f7c14bbaSAndroid Build Coastguard Worker }
143*f7c14bbaSAndroid Build Coastguard Worker
skel_finalize_map_data(__u64 * init_val,size_t mmap_sz,int flags,int fd)144*f7c14bbaSAndroid Build Coastguard Worker static inline void *skel_finalize_map_data(__u64 *init_val, size_t mmap_sz, int flags, int fd)
145*f7c14bbaSAndroid Build Coastguard Worker {
146*f7c14bbaSAndroid Build Coastguard Worker struct bpf_map *map;
147*f7c14bbaSAndroid Build Coastguard Worker void *addr = NULL;
148*f7c14bbaSAndroid Build Coastguard Worker
149*f7c14bbaSAndroid Build Coastguard Worker kvfree((void *) (long) *init_val);
150*f7c14bbaSAndroid Build Coastguard Worker *init_val = ~0ULL;
151*f7c14bbaSAndroid Build Coastguard Worker
152*f7c14bbaSAndroid Build Coastguard Worker /* At this point bpf_load_and_run() finished without error and
153*f7c14bbaSAndroid Build Coastguard Worker * 'fd' is a valid bpf map FD. All sanity checks below should succeed.
154*f7c14bbaSAndroid Build Coastguard Worker */
155*f7c14bbaSAndroid Build Coastguard Worker map = bpf_map_get(fd);
156*f7c14bbaSAndroid Build Coastguard Worker if (IS_ERR(map))
157*f7c14bbaSAndroid Build Coastguard Worker return NULL;
158*f7c14bbaSAndroid Build Coastguard Worker if (map->map_type != BPF_MAP_TYPE_ARRAY)
159*f7c14bbaSAndroid Build Coastguard Worker goto out;
160*f7c14bbaSAndroid Build Coastguard Worker addr = ((struct bpf_array *)map)->value;
161*f7c14bbaSAndroid Build Coastguard Worker /* the addr stays valid, since FD is not closed */
162*f7c14bbaSAndroid Build Coastguard Worker out:
163*f7c14bbaSAndroid Build Coastguard Worker bpf_map_put(map);
164*f7c14bbaSAndroid Build Coastguard Worker return addr;
165*f7c14bbaSAndroid Build Coastguard Worker }
166*f7c14bbaSAndroid Build Coastguard Worker
167*f7c14bbaSAndroid Build Coastguard Worker #else
168*f7c14bbaSAndroid Build Coastguard Worker
skel_alloc(size_t size)169*f7c14bbaSAndroid Build Coastguard Worker static inline void *skel_alloc(size_t size)
170*f7c14bbaSAndroid Build Coastguard Worker {
171*f7c14bbaSAndroid Build Coastguard Worker return calloc(1, size);
172*f7c14bbaSAndroid Build Coastguard Worker }
173*f7c14bbaSAndroid Build Coastguard Worker
skel_free(void * p)174*f7c14bbaSAndroid Build Coastguard Worker static inline void skel_free(void *p)
175*f7c14bbaSAndroid Build Coastguard Worker {
176*f7c14bbaSAndroid Build Coastguard Worker free(p);
177*f7c14bbaSAndroid Build Coastguard Worker }
178*f7c14bbaSAndroid Build Coastguard Worker
skel_free_map_data(void * p,__u64 addr,size_t sz)179*f7c14bbaSAndroid Build Coastguard Worker static inline void skel_free_map_data(void *p, __u64 addr, size_t sz)
180*f7c14bbaSAndroid Build Coastguard Worker {
181*f7c14bbaSAndroid Build Coastguard Worker munmap(p, sz);
182*f7c14bbaSAndroid Build Coastguard Worker }
183*f7c14bbaSAndroid Build Coastguard Worker
skel_prep_map_data(const void * val,size_t mmap_sz,size_t val_sz)184*f7c14bbaSAndroid Build Coastguard Worker static inline void *skel_prep_map_data(const void *val, size_t mmap_sz, size_t val_sz)
185*f7c14bbaSAndroid Build Coastguard Worker {
186*f7c14bbaSAndroid Build Coastguard Worker void *addr;
187*f7c14bbaSAndroid Build Coastguard Worker
188*f7c14bbaSAndroid Build Coastguard Worker addr = mmap(NULL, mmap_sz, PROT_READ | PROT_WRITE,
189*f7c14bbaSAndroid Build Coastguard Worker MAP_SHARED | MAP_ANONYMOUS, -1, 0);
190*f7c14bbaSAndroid Build Coastguard Worker if (addr == (void *) -1)
191*f7c14bbaSAndroid Build Coastguard Worker return NULL;
192*f7c14bbaSAndroid Build Coastguard Worker memcpy(addr, val, val_sz);
193*f7c14bbaSAndroid Build Coastguard Worker return addr;
194*f7c14bbaSAndroid Build Coastguard Worker }
195*f7c14bbaSAndroid Build Coastguard Worker
skel_finalize_map_data(__u64 * init_val,size_t mmap_sz,int flags,int fd)196*f7c14bbaSAndroid Build Coastguard Worker static inline void *skel_finalize_map_data(__u64 *init_val, size_t mmap_sz, int flags, int fd)
197*f7c14bbaSAndroid Build Coastguard Worker {
198*f7c14bbaSAndroid Build Coastguard Worker void *addr;
199*f7c14bbaSAndroid Build Coastguard Worker
200*f7c14bbaSAndroid Build Coastguard Worker addr = mmap((void *) (long) *init_val, mmap_sz, flags, MAP_SHARED | MAP_FIXED, fd, 0);
201*f7c14bbaSAndroid Build Coastguard Worker if (addr == (void *) -1)
202*f7c14bbaSAndroid Build Coastguard Worker return NULL;
203*f7c14bbaSAndroid Build Coastguard Worker return addr;
204*f7c14bbaSAndroid Build Coastguard Worker }
205*f7c14bbaSAndroid Build Coastguard Worker #endif
206*f7c14bbaSAndroid Build Coastguard Worker
skel_closenz(int fd)207*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_closenz(int fd)
208*f7c14bbaSAndroid Build Coastguard Worker {
209*f7c14bbaSAndroid Build Coastguard Worker if (fd > 0)
210*f7c14bbaSAndroid Build Coastguard Worker return close(fd);
211*f7c14bbaSAndroid Build Coastguard Worker return -EINVAL;
212*f7c14bbaSAndroid Build Coastguard Worker }
213*f7c14bbaSAndroid Build Coastguard Worker
214*f7c14bbaSAndroid Build Coastguard Worker #ifndef offsetofend
215*f7c14bbaSAndroid Build Coastguard Worker #define offsetofend(TYPE, MEMBER) \
216*f7c14bbaSAndroid Build Coastguard Worker (offsetof(TYPE, MEMBER) + sizeof((((TYPE *)0)->MEMBER)))
217*f7c14bbaSAndroid Build Coastguard Worker #endif
218*f7c14bbaSAndroid Build Coastguard Worker
skel_map_create(enum bpf_map_type map_type,const char * map_name,__u32 key_size,__u32 value_size,__u32 max_entries)219*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_map_create(enum bpf_map_type map_type,
220*f7c14bbaSAndroid Build Coastguard Worker const char *map_name,
221*f7c14bbaSAndroid Build Coastguard Worker __u32 key_size,
222*f7c14bbaSAndroid Build Coastguard Worker __u32 value_size,
223*f7c14bbaSAndroid Build Coastguard Worker __u32 max_entries)
224*f7c14bbaSAndroid Build Coastguard Worker {
225*f7c14bbaSAndroid Build Coastguard Worker const size_t attr_sz = offsetofend(union bpf_attr, map_extra);
226*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
227*f7c14bbaSAndroid Build Coastguard Worker
228*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, attr_sz);
229*f7c14bbaSAndroid Build Coastguard Worker
230*f7c14bbaSAndroid Build Coastguard Worker attr.map_type = map_type;
231*f7c14bbaSAndroid Build Coastguard Worker strncpy(attr.map_name, map_name, sizeof(attr.map_name));
232*f7c14bbaSAndroid Build Coastguard Worker attr.key_size = key_size;
233*f7c14bbaSAndroid Build Coastguard Worker attr.value_size = value_size;
234*f7c14bbaSAndroid Build Coastguard Worker attr.max_entries = max_entries;
235*f7c14bbaSAndroid Build Coastguard Worker
236*f7c14bbaSAndroid Build Coastguard Worker return skel_sys_bpf(BPF_MAP_CREATE, &attr, attr_sz);
237*f7c14bbaSAndroid Build Coastguard Worker }
238*f7c14bbaSAndroid Build Coastguard Worker
skel_map_update_elem(int fd,const void * key,const void * value,__u64 flags)239*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_map_update_elem(int fd, const void *key,
240*f7c14bbaSAndroid Build Coastguard Worker const void *value, __u64 flags)
241*f7c14bbaSAndroid Build Coastguard Worker {
242*f7c14bbaSAndroid Build Coastguard Worker const size_t attr_sz = offsetofend(union bpf_attr, flags);
243*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
244*f7c14bbaSAndroid Build Coastguard Worker
245*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, attr_sz);
246*f7c14bbaSAndroid Build Coastguard Worker attr.map_fd = fd;
247*f7c14bbaSAndroid Build Coastguard Worker attr.key = (long) key;
248*f7c14bbaSAndroid Build Coastguard Worker attr.value = (long) value;
249*f7c14bbaSAndroid Build Coastguard Worker attr.flags = flags;
250*f7c14bbaSAndroid Build Coastguard Worker
251*f7c14bbaSAndroid Build Coastguard Worker return skel_sys_bpf(BPF_MAP_UPDATE_ELEM, &attr, attr_sz);
252*f7c14bbaSAndroid Build Coastguard Worker }
253*f7c14bbaSAndroid Build Coastguard Worker
skel_map_delete_elem(int fd,const void * key)254*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_map_delete_elem(int fd, const void *key)
255*f7c14bbaSAndroid Build Coastguard Worker {
256*f7c14bbaSAndroid Build Coastguard Worker const size_t attr_sz = offsetofend(union bpf_attr, flags);
257*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
258*f7c14bbaSAndroid Build Coastguard Worker
259*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, attr_sz);
260*f7c14bbaSAndroid Build Coastguard Worker attr.map_fd = fd;
261*f7c14bbaSAndroid Build Coastguard Worker attr.key = (long)key;
262*f7c14bbaSAndroid Build Coastguard Worker
263*f7c14bbaSAndroid Build Coastguard Worker return skel_sys_bpf(BPF_MAP_DELETE_ELEM, &attr, attr_sz);
264*f7c14bbaSAndroid Build Coastguard Worker }
265*f7c14bbaSAndroid Build Coastguard Worker
skel_map_get_fd_by_id(__u32 id)266*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_map_get_fd_by_id(__u32 id)
267*f7c14bbaSAndroid Build Coastguard Worker {
268*f7c14bbaSAndroid Build Coastguard Worker const size_t attr_sz = offsetofend(union bpf_attr, flags);
269*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
270*f7c14bbaSAndroid Build Coastguard Worker
271*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, attr_sz);
272*f7c14bbaSAndroid Build Coastguard Worker attr.map_id = id;
273*f7c14bbaSAndroid Build Coastguard Worker
274*f7c14bbaSAndroid Build Coastguard Worker return skel_sys_bpf(BPF_MAP_GET_FD_BY_ID, &attr, attr_sz);
275*f7c14bbaSAndroid Build Coastguard Worker }
276*f7c14bbaSAndroid Build Coastguard Worker
skel_raw_tracepoint_open(const char * name,int prog_fd)277*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_raw_tracepoint_open(const char *name, int prog_fd)
278*f7c14bbaSAndroid Build Coastguard Worker {
279*f7c14bbaSAndroid Build Coastguard Worker const size_t attr_sz = offsetofend(union bpf_attr, raw_tracepoint.prog_fd);
280*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
281*f7c14bbaSAndroid Build Coastguard Worker
282*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, attr_sz);
283*f7c14bbaSAndroid Build Coastguard Worker attr.raw_tracepoint.name = (long) name;
284*f7c14bbaSAndroid Build Coastguard Worker attr.raw_tracepoint.prog_fd = prog_fd;
285*f7c14bbaSAndroid Build Coastguard Worker
286*f7c14bbaSAndroid Build Coastguard Worker return skel_sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, attr_sz);
287*f7c14bbaSAndroid Build Coastguard Worker }
288*f7c14bbaSAndroid Build Coastguard Worker
skel_link_create(int prog_fd,int target_fd,enum bpf_attach_type attach_type)289*f7c14bbaSAndroid Build Coastguard Worker static inline int skel_link_create(int prog_fd, int target_fd,
290*f7c14bbaSAndroid Build Coastguard Worker enum bpf_attach_type attach_type)
291*f7c14bbaSAndroid Build Coastguard Worker {
292*f7c14bbaSAndroid Build Coastguard Worker const size_t attr_sz = offsetofend(union bpf_attr, link_create.iter_info_len);
293*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
294*f7c14bbaSAndroid Build Coastguard Worker
295*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, attr_sz);
296*f7c14bbaSAndroid Build Coastguard Worker attr.link_create.prog_fd = prog_fd;
297*f7c14bbaSAndroid Build Coastguard Worker attr.link_create.target_fd = target_fd;
298*f7c14bbaSAndroid Build Coastguard Worker attr.link_create.attach_type = attach_type;
299*f7c14bbaSAndroid Build Coastguard Worker
300*f7c14bbaSAndroid Build Coastguard Worker return skel_sys_bpf(BPF_LINK_CREATE, &attr, attr_sz);
301*f7c14bbaSAndroid Build Coastguard Worker }
302*f7c14bbaSAndroid Build Coastguard Worker
303*f7c14bbaSAndroid Build Coastguard Worker #ifdef __KERNEL__
304*f7c14bbaSAndroid Build Coastguard Worker #define set_err
305*f7c14bbaSAndroid Build Coastguard Worker #else
306*f7c14bbaSAndroid Build Coastguard Worker #define set_err err = -errno
307*f7c14bbaSAndroid Build Coastguard Worker #endif
308*f7c14bbaSAndroid Build Coastguard Worker
bpf_load_and_run(struct bpf_load_and_run_opts * opts)309*f7c14bbaSAndroid Build Coastguard Worker static inline int bpf_load_and_run(struct bpf_load_and_run_opts *opts)
310*f7c14bbaSAndroid Build Coastguard Worker {
311*f7c14bbaSAndroid Build Coastguard Worker const size_t prog_load_attr_sz = offsetofend(union bpf_attr, fd_array);
312*f7c14bbaSAndroid Build Coastguard Worker const size_t test_run_attr_sz = offsetofend(union bpf_attr, test);
313*f7c14bbaSAndroid Build Coastguard Worker int map_fd = -1, prog_fd = -1, key = 0, err;
314*f7c14bbaSAndroid Build Coastguard Worker union bpf_attr attr;
315*f7c14bbaSAndroid Build Coastguard Worker
316*f7c14bbaSAndroid Build Coastguard Worker err = map_fd = skel_map_create(BPF_MAP_TYPE_ARRAY, "__loader.map", 4, opts->data_sz, 1);
317*f7c14bbaSAndroid Build Coastguard Worker if (map_fd < 0) {
318*f7c14bbaSAndroid Build Coastguard Worker opts->errstr = "failed to create loader map";
319*f7c14bbaSAndroid Build Coastguard Worker set_err;
320*f7c14bbaSAndroid Build Coastguard Worker goto out;
321*f7c14bbaSAndroid Build Coastguard Worker }
322*f7c14bbaSAndroid Build Coastguard Worker
323*f7c14bbaSAndroid Build Coastguard Worker err = skel_map_update_elem(map_fd, &key, opts->data, 0);
324*f7c14bbaSAndroid Build Coastguard Worker if (err < 0) {
325*f7c14bbaSAndroid Build Coastguard Worker opts->errstr = "failed to update loader map";
326*f7c14bbaSAndroid Build Coastguard Worker set_err;
327*f7c14bbaSAndroid Build Coastguard Worker goto out;
328*f7c14bbaSAndroid Build Coastguard Worker }
329*f7c14bbaSAndroid Build Coastguard Worker
330*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, prog_load_attr_sz);
331*f7c14bbaSAndroid Build Coastguard Worker attr.prog_type = BPF_PROG_TYPE_SYSCALL;
332*f7c14bbaSAndroid Build Coastguard Worker attr.insns = (long) opts->insns;
333*f7c14bbaSAndroid Build Coastguard Worker attr.insn_cnt = opts->insns_sz / sizeof(struct bpf_insn);
334*f7c14bbaSAndroid Build Coastguard Worker attr.license = (long) "Dual BSD/GPL";
335*f7c14bbaSAndroid Build Coastguard Worker memcpy(attr.prog_name, "__loader.prog", sizeof("__loader.prog"));
336*f7c14bbaSAndroid Build Coastguard Worker attr.fd_array = (long) &map_fd;
337*f7c14bbaSAndroid Build Coastguard Worker attr.log_level = opts->ctx->log_level;
338*f7c14bbaSAndroid Build Coastguard Worker attr.log_size = opts->ctx->log_size;
339*f7c14bbaSAndroid Build Coastguard Worker attr.log_buf = opts->ctx->log_buf;
340*f7c14bbaSAndroid Build Coastguard Worker attr.prog_flags = BPF_F_SLEEPABLE;
341*f7c14bbaSAndroid Build Coastguard Worker err = prog_fd = skel_sys_bpf(BPF_PROG_LOAD, &attr, prog_load_attr_sz);
342*f7c14bbaSAndroid Build Coastguard Worker if (prog_fd < 0) {
343*f7c14bbaSAndroid Build Coastguard Worker opts->errstr = "failed to load loader prog";
344*f7c14bbaSAndroid Build Coastguard Worker set_err;
345*f7c14bbaSAndroid Build Coastguard Worker goto out;
346*f7c14bbaSAndroid Build Coastguard Worker }
347*f7c14bbaSAndroid Build Coastguard Worker
348*f7c14bbaSAndroid Build Coastguard Worker memset(&attr, 0, test_run_attr_sz);
349*f7c14bbaSAndroid Build Coastguard Worker attr.test.prog_fd = prog_fd;
350*f7c14bbaSAndroid Build Coastguard Worker attr.test.ctx_in = (long) opts->ctx;
351*f7c14bbaSAndroid Build Coastguard Worker attr.test.ctx_size_in = opts->ctx->sz;
352*f7c14bbaSAndroid Build Coastguard Worker err = skel_sys_bpf(BPF_PROG_RUN, &attr, test_run_attr_sz);
353*f7c14bbaSAndroid Build Coastguard Worker if (err < 0 || (int)attr.test.retval < 0) {
354*f7c14bbaSAndroid Build Coastguard Worker opts->errstr = "failed to execute loader prog";
355*f7c14bbaSAndroid Build Coastguard Worker if (err < 0) {
356*f7c14bbaSAndroid Build Coastguard Worker set_err;
357*f7c14bbaSAndroid Build Coastguard Worker } else {
358*f7c14bbaSAndroid Build Coastguard Worker err = (int)attr.test.retval;
359*f7c14bbaSAndroid Build Coastguard Worker #ifndef __KERNEL__
360*f7c14bbaSAndroid Build Coastguard Worker errno = -err;
361*f7c14bbaSAndroid Build Coastguard Worker #endif
362*f7c14bbaSAndroid Build Coastguard Worker }
363*f7c14bbaSAndroid Build Coastguard Worker goto out;
364*f7c14bbaSAndroid Build Coastguard Worker }
365*f7c14bbaSAndroid Build Coastguard Worker err = 0;
366*f7c14bbaSAndroid Build Coastguard Worker out:
367*f7c14bbaSAndroid Build Coastguard Worker if (map_fd >= 0)
368*f7c14bbaSAndroid Build Coastguard Worker close(map_fd);
369*f7c14bbaSAndroid Build Coastguard Worker if (prog_fd >= 0)
370*f7c14bbaSAndroid Build Coastguard Worker close(prog_fd);
371*f7c14bbaSAndroid Build Coastguard Worker return err;
372*f7c14bbaSAndroid Build Coastguard Worker }
373*f7c14bbaSAndroid Build Coastguard Worker
374*f7c14bbaSAndroid Build Coastguard Worker #endif
375