summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-12-20 20:31:36 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-20 20:31:36 -0500
commit339bbff2d6e005a5586adeffc3d69a0eea50a764 (patch)
treea5bedd1933215aa69acdb5dbbfcbafb29561fe3c /tools
parente770454fabde2e0f8fb3e5039a2b6df8f128bc9b (diff)
parent1cf4a0ccc506b5c027afc5eaf3fddc83f96f31e7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Daniel Borkmann says: ==================== pull-request: bpf-next 2018-12-21 The following pull-request contains BPF updates for your *net-next* tree. There is a merge conflict in test_verifier.c. Result looks as follows: [...] }, { "calls: cross frame pruning", .insns = { [...] .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .errstr_unpriv = "function calls to other bpf functions are allowed for root only", .result_unpriv = REJECT, .errstr = "!read_ok", .result = REJECT, }, { "jset: functional", .insns = { [...] { "jset: unknown const compare not taken", .insns = { BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1), BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0), BPF_EXIT_INSN(), }, .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .errstr_unpriv = "!read_ok", .result_unpriv = REJECT, .errstr = "!read_ok", .result = REJECT, }, [...] { "jset: range", .insns = { [...] }, .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .result_unpriv = ACCEPT, .result = ACCEPT, }, The main changes are: 1) Various BTF related improvements in order to get line info working. Meaning, verifier will now annotate the corresponding BPF C code to the error log, from Martin and Yonghong. 2) Implement support for raw BPF tracepoints in modules, from Matt. 3) Add several improvements to verifier state logic, namely speeding up stacksafe check, optimizations for stack state equivalence test and safety checks for liveness analysis, from Alexei. 4) Teach verifier to make use of BPF_JSET instruction, add several test cases to kselftests and remove nfp specific JSET optimization now that verifier has awareness, from Jakub. 5) Improve BPF verifier's slot_type marking logic in order to allow more stack slot sharing, from Jiong. 6) Add sk_msg->size member for context access and add set of fixes and improvements to make sock_map with kTLS usable with openssl based applications, from John. 7) Several cleanups and documentation updates in bpftool as well as auto-mount of tracefs for "bpftool prog tracelog" command, from Quentin. 8) Include sub-program tags from now on in bpf_prog_info in order to have a reliable way for user space to get all tags of the program e.g. needed for kallsyms correlation, from Song. 9) Add BTF annotations for cgroup_local_storage BPF maps and implement bpf fs pretty print support, from Roman. 10) Fix bpftool in order to allow for cross-compilation, from Ivan. 11) Update of bpftool license to GPLv2-only + BSD-2-Clause in order to be compatible with libbfd and allow for Debian packaging, from Jakub. 12) Remove an obsolete prog->aux sanitation in dump and get rid of version check for prog load, from Daniel. 13) Fix a memory leak in libbpf's line info handling, from Prashant. 14) Fix cpumap's frame alignment for build_skb() so that skb_shared_info does not get unaligned, from Jesper. 15) Fix test_progs kselftest to work with older compilers which are less smart in optimizing (and thus throwing build error), from Stanislav. 16) Cleanup and simplify AF_XDP socket teardown, from Björn. 17) Fix sk lookup in BPF kselftest's test_sock_addr with regards to netns_id argument, from Andrey. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools')
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-map.rst59
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool-prog.rst105
-rw-r--r--tools/bpf/bpftool/Documentation/bpftool.rst4
-rw-r--r--tools/bpf/bpftool/Makefile2
-rw-r--r--tools/bpf/bpftool/bash-completion/bpftool31
-rw-r--r--tools/bpf/bpftool/btf_dumper.c63
-rw-r--r--tools/bpf/bpftool/cfg.c36
-rw-r--r--tools/bpf/bpftool/cfg.h38
-rw-r--r--tools/bpf/bpftool/cgroup.c2
-rw-r--r--tools/bpf/bpftool/common.c69
-rw-r--r--tools/bpf/bpftool/jit_disasm.c1
-rw-r--r--tools/bpf/bpftool/json_writer.c7
-rw-r--r--tools/bpf/bpftool/json_writer.h1
-rw-r--r--tools/bpf/bpftool/main.c42
-rw-r--r--tools/bpf/bpftool/main.h42
-rw-r--r--tools/bpf/bpftool/map.c34
-rw-r--r--tools/bpf/bpftool/map_perf_ring.c2
-rw-r--r--tools/bpf/bpftool/net.c2
-rw-r--r--tools/bpf/bpftool/netlink_dumper.c2
-rw-r--r--tools/bpf/bpftool/netlink_dumper.h2
-rw-r--r--tools/bpf/bpftool/perf.c2
-rw-r--r--tools/bpf/bpftool/prog.c45
-rw-r--r--tools/bpf/bpftool/tracelog.c23
-rw-r--r--tools/bpf/bpftool/xlated_dumper.c43
-rw-r--r--tools/bpf/bpftool/xlated_dumper.h38
-rw-r--r--tools/include/uapi/linux/bpf.h13
-rw-r--r--tools/include/uapi/linux/btf.h20
-rw-r--r--tools/lib/bpf/bpf_prog_linfo.c6
-rw-r--r--tools/lib/bpf/libbpf.c1
-rw-r--r--tools/testing/selftests/bpf/.gitignore1
-rw-r--r--tools/testing/selftests/bpf/connect4_prog.c6
-rw-r--r--tools/testing/selftests/bpf/connect6_prog.c6
-rw-r--r--tools/testing/selftests/bpf/netcnt_prog.c6
-rw-r--r--tools/testing/selftests/bpf/test_btf.c708
-rw-r--r--tools/testing/selftests/bpf/test_progs.c8
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c391
36 files changed, 1348 insertions, 513 deletions
diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst
index 5318dcb2085e..64b001b4f777 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-map.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst
@@ -128,6 +128,10 @@ OPTIONS
128 -f, --bpffs 128 -f, --bpffs
129 Show file names of pinned maps. 129 Show file names of pinned maps.
130 130
131 -n, --nomount
132 Do not automatically attempt to mount any virtual file system
133 (such as tracefs or BPF virtual file system) when necessary.
134
131EXAMPLES 135EXAMPLES
132======== 136========
133**# bpftool map show** 137**# bpftool map show**
@@ -170,6 +174,61 @@ The following three commands are equivalent:
170| **# bpftool map pin id 10 /sys/fs/bpf/map** 174| **# bpftool map pin id 10 /sys/fs/bpf/map**
171| **# bpftool map del pinned /sys/fs/bpf/map key 13 00 07 00** 175| **# bpftool map del pinned /sys/fs/bpf/map key 13 00 07 00**
172 176
177Note that map update can also be used in order to change the program references
178hold by a program array map. This can be used, for example, to change the
179programs used for tail-call jumps at runtime, without having to reload the
180entry-point program. Below is an example for this use case: we load a program
181defining a prog array map, and with a main function that contains a tail call
182to other programs that can be used either to "process" packets or to "debug"
183processing. Note that the prog array map MUST be pinned into the BPF virtual
184file system for the map update to work successfully, as kernel flushes prog
185array maps when they have no more references from user space (and the update
186would be lost as soon as bpftool exits).
187
188|
189| **# bpftool prog loadall tail_calls.o /sys/fs/bpf/foo type xdp**
190| **# bpftool prog --bpffs**
191
192::
193
194 545: xdp name main_func tag 674b4b5597193dc3 gpl
195 loaded_at 2018-12-12T15:02:58+0000 uid 0
196 xlated 240B jited 257B memlock 4096B map_ids 294
197 pinned /sys/fs/bpf/foo/xdp
198 546: xdp name bpf_func_process tag e369a529024751fc gpl
199 loaded_at 2018-12-12T15:02:58+0000 uid 0
200 xlated 200B jited 164B memlock 4096B
201 pinned /sys/fs/bpf/foo/process
202 547: xdp name bpf_func_debug tag 0b597868bc7f0976 gpl
203 loaded_at 2018-12-12T15:02:58+0000 uid 0
204 xlated 200B jited 164B memlock 4096B
205 pinned /sys/fs/bpf/foo/debug
206
207**# bpftool map**
208
209::
210
211 294: prog_array name jmp_table flags 0x0
212 key 4B value 4B max_entries 1 memlock 4096B
213 owner_prog_type xdp owner jited
214
215|
216| **# bpftool map pin id 294 /sys/fs/bpf/bar**
217| **# bpftool map dump pinned /sys/fs/bpf/bar**
218
219::
220
221 Found 0 elements
222
223|
224| **# bpftool map update pinned /sys/fs/bpf/bar key 0 0 0 0 value pinned /sys/fs/bpf/foo/debug**
225| **# bpftool map dump pinned /sys/fs/bpf/bar**
226
227::
228
229 key: 00 00 00 00 value: 22 02 00 00
230 Found 1 element
231
173SEE ALSO 232SEE ALSO
174======== 233========
175 **bpf**\ (2), 234 **bpf**\ (2),
diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
index bb1aeb98b6da..58c8369b77dd 100644
--- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
@@ -158,83 +158,98 @@ OPTIONS
158 When showing BPF programs, show file names of pinned 158 When showing BPF programs, show file names of pinned
159 programs. 159 programs.
160 160
161 -m, --mapcompat
162 Allow loading maps with unknown map definitions.
163
164 -n, --nomount
165 Do not automatically attempt to mount any virtual file system
166 (such as tracefs or BPF virtual file system) when necessary.
167
161EXAMPLES 168EXAMPLES
162======== 169========
163**# bpftool prog show** 170**# bpftool prog show**
171
164:: 172::
165 173
166 10: xdp name some_prog tag 005a3d2123620c8b gpl 174 10: xdp name some_prog tag 005a3d2123620c8b gpl
167 loaded_at Sep 29/20:11 uid 0 175 loaded_at 2017-09-29T20:11:00+0000 uid 0
168 xlated 528B jited 370B memlock 4096B map_ids 10 176 xlated 528B jited 370B memlock 4096B map_ids 10
169 177
170**# bpftool --json --pretty prog show** 178**# bpftool --json --pretty prog show**
171 179
172:: 180::
173 181
174 { 182 [{
175 "programs": [{ 183 "id": 10,
176 "id": 10, 184 "type": "xdp",
177 "type": "xdp", 185 "tag": "005a3d2123620c8b",
178 "tag": "005a3d2123620c8b", 186 "gpl_compatible": true,
179 "gpl_compatible": true, 187 "loaded_at": 1506715860,
180 "loaded_at": "Sep 29/20:11", 188 "uid": 0,
181 "uid": 0, 189 "bytes_xlated": 528,
182 "bytes_xlated": 528, 190 "jited": true,
183 "jited": true, 191 "bytes_jited": 370,
184 "bytes_jited": 370, 192 "bytes_memlock": 4096,
185 "bytes_memlock": 4096, 193 "map_ids": [10
186 "map_ids": [10 194 ]
187 ] 195 }
188 } 196 ]
189 ]
190 }
191 197
192| 198|
193| **# bpftool prog dump xlated id 10 file /tmp/t** 199| **# bpftool prog dump xlated id 10 file /tmp/t**
194| **# ls -l /tmp/t** 200| **# ls -l /tmp/t**
195| -rw------- 1 root root 560 Jul 22 01:42 /tmp/t
196 201
197**# bpftool prog dum jited tag 005a3d2123620c8b** 202::
203
204 -rw------- 1 root root 560 Jul 22 01:42 /tmp/t
205
206**# bpftool prog dump jited tag 005a3d2123620c8b**
198 207
199:: 208::
200 209
201 push %rbp 210 0: push %rbp
202 mov %rsp,%rbp 211 1: mov %rsp,%rbp
203 sub $0x228,%rsp 212 2: sub $0x228,%rsp
204 sub $0x28,%rbp 213 3: sub $0x28,%rbp
205 mov %rbx,0x0(%rbp) 214 4: mov %rbx,0x0(%rbp)
206 215
207| 216|
208| **# mount -t bpf none /sys/fs/bpf/** 217| **# mount -t bpf none /sys/fs/bpf/**
209| **# bpftool prog pin id 10 /sys/fs/bpf/prog** 218| **# bpftool prog pin id 10 /sys/fs/bpf/prog**
210| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2** 219| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2**
211| **# ls -l /sys/fs/bpf/** 220| **# ls -l /sys/fs/bpf/**
212| -rw------- 1 root root 0 Jul 22 01:43 prog
213| -rw------- 1 root root 0 Jul 22 01:44 prog2
214 221
215**# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes** 222::
223
224 -rw------- 1 root root 0 Jul 22 01:43 prog
225 -rw------- 1 root root 0 Jul 22 01:44 prog2
226
227**# bpftool prog dump jited pinned /sys/fs/bpf/prog opcodes**
216 228
217:: 229::
218 230
219 push %rbp 231 0: push %rbp
220 55 232 55
221 mov %rsp,%rbp 233 1: mov %rsp,%rbp
222 48 89 e5 234 48 89 e5
223 sub $0x228,%rsp 235 4: sub $0x228,%rsp
224 48 81 ec 28 02 00 00 236 48 81 ec 28 02 00 00
225 sub $0x28,%rbp 237 b: sub $0x28,%rbp
226 48 83 ed 28 238 48 83 ed 28
227 mov %rbx,0x0(%rbp) 239 f: mov %rbx,0x0(%rbp)
228 48 89 5d 00 240 48 89 5d 00
229 241
230| 242|
231| **# bpftool prog load xdp1_kern.o /sys/fs/bpf/xdp1 type xdp map name rxcnt id 7** 243| **# bpftool prog load xdp1_kern.o /sys/fs/bpf/xdp1 type xdp map name rxcnt id 7**
232| **# bpftool prog show pinned /sys/fs/bpf/xdp1** 244| **# bpftool prog show pinned /sys/fs/bpf/xdp1**
233| 9: xdp name xdp_prog1 tag 539ec6ce11b52f98 gpl 245
234| loaded_at 2018-06-25T16:17:31-0700 uid 0 246::
235| xlated 488B jited 336B memlock 4096B map_ids 7 247
236| **# rm /sys/fs/bpf/xdp1** 248 9: xdp name xdp_prog1 tag 539ec6ce11b52f98 gpl
237| 249 loaded_at 2018-06-25T16:17:31-0700 uid 0
250 xlated 488B jited 336B memlock 4096B map_ids 7
251
252**# rm /sys/fs/bpf/xdp1**
238 253
239SEE ALSO 254SEE ALSO
240======== 255========
diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst
index 129b7a9c0f9b..e1677e81ed59 100644
--- a/tools/bpf/bpftool/Documentation/bpftool.rst
+++ b/tools/bpf/bpftool/Documentation/bpftool.rst
@@ -60,6 +60,10 @@ OPTIONS
60 -m, --mapcompat 60 -m, --mapcompat
61 Allow loading maps with unknown map definitions. 61 Allow loading maps with unknown map definitions.
62 62
63 -n, --nomount
64 Do not automatically attempt to mount any virtual file system
65 (such as tracefs or BPF virtual file system) when necessary.
66
63 67
64SEE ALSO 68SEE ALSO
65======== 69========
diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile
index 1bea6b979082..492f0f24e2d3 100644
--- a/tools/bpf/bpftool/Makefile
+++ b/tools/bpf/bpftool/Makefile
@@ -35,8 +35,6 @@ $(LIBBPF)-clean:
35prefix ?= /usr/local 35prefix ?= /usr/local
36bash_compdir ?= /usr/share/bash-completion/completions 36bash_compdir ?= /usr/share/bash-completion/completions
37 37
38CC = gcc
39
40CFLAGS += -O2 38CFLAGS += -O2
41CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers 39CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers
42CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \ 40CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \
diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool
index a57febd6abb1..e4e4fab1b8c7 100644
--- a/tools/bpf/bpftool/bash-completion/bpftool
+++ b/tools/bpf/bpftool/bash-completion/bpftool
@@ -1,37 +1,8 @@
1# bpftool(8) bash completion -*- shell-script -*- 1# bpftool(8) bash completion -*- shell-script -*-
2# 2#
3# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
3# Copyright (C) 2017-2018 Netronome Systems, Inc. 4# Copyright (C) 2017-2018 Netronome Systems, Inc.
4# 5#
5# This software is dual licensed under the GNU General License
6# Version 2, June 1991 as shown in the file COPYING in the top-level
7# directory of this source tree or the BSD 2-Clause License provided
8# below. You have the option to license this software under the
9# complete terms of either license.
10#
11# The BSD 2-Clause License:
12#
13# Redistribution and use in source and binary forms, with or
14# without modification, are permitted provided that the following
15# conditions are met:
16#
17# 1. Redistributions of source code must retain the above
18# copyright notice, this list of conditions and the following
19# disclaimer.
20#
21# 2. Redistributions in binary form must reproduce the above
22# copyright notice, this list of conditions and the following
23# disclaimer in the documentation and/or other materials
24# provided with the distribution.
25#
26# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33# SOFTWARE.
34#
35# Author: Quentin Monnet <quentin.monnet@netronome.com> 6# Author: Quentin Monnet <quentin.monnet@netronome.com>
36 7
37# Takes a list of words in argument; each one of them is added to COMPREPLY if 8# Takes a list of words in argument; each one of them is added to COMPREPLY if
diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
index 2392ccdc918f..3f0629edbca5 100644
--- a/tools/bpf/bpftool/btf_dumper.c
+++ b/tools/bpf/bpftool/btf_dumper.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/* Copyright (c) 2018 Facebook */ 2/* Copyright (c) 2018 Facebook */
3 3
4#include <ctype.h> 4#include <ctype.h>
@@ -73,20 +73,17 @@ static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id,
73 return ret; 73 return ret;
74} 74}
75 75
76static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset, 76static void btf_dumper_bitfield(__u32 nr_bits, __u8 bit_offset,
77 const void *data, json_writer_t *jw, 77 const void *data, json_writer_t *jw,
78 bool is_plain_text) 78 bool is_plain_text)
79{ 79{
80 int left_shift_bits, right_shift_bits; 80 int left_shift_bits, right_shift_bits;
81 int nr_bits = BTF_INT_BITS(int_type);
82 int total_bits_offset;
83 int bytes_to_copy; 81 int bytes_to_copy;
84 int bits_to_copy; 82 int bits_to_copy;
85 __u64 print_num; 83 __u64 print_num;
86 84
87 total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type); 85 data += BITS_ROUNDDOWN_BYTES(bit_offset);
88 data += BITS_ROUNDDOWN_BYTES(total_bits_offset); 86 bit_offset = BITS_PER_BYTE_MASKED(bit_offset);
89 bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
90 bits_to_copy = bit_offset + nr_bits; 87 bits_to_copy = bit_offset + nr_bits;
91 bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy); 88 bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy);
92 89
@@ -109,6 +106,22 @@ static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
109 jsonw_printf(jw, "%llu", print_num); 106 jsonw_printf(jw, "%llu", print_num);
110} 107}
111 108
109
110static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
111 const void *data, json_writer_t *jw,
112 bool is_plain_text)
113{
114 int nr_bits = BTF_INT_BITS(int_type);
115 int total_bits_offset;
116
117 /* bits_offset is at most 7.
118 * BTF_INT_OFFSET() cannot exceed 64 bits.
119 */
120 total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
121 btf_dumper_bitfield(nr_bits, total_bits_offset, data, jw,
122 is_plain_text);
123}
124
112static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset, 125static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
113 const void *data, json_writer_t *jw, 126 const void *data, json_writer_t *jw,
114 bool is_plain_text) 127 bool is_plain_text)
@@ -180,6 +193,7 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
180 const struct btf_type *t; 193 const struct btf_type *t;
181 struct btf_member *m; 194 struct btf_member *m;
182 const void *data_off; 195 const void *data_off;
196 int kind_flag;
183 int ret = 0; 197 int ret = 0;
184 int i, vlen; 198 int i, vlen;
185 199
@@ -187,18 +201,32 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
187 if (!t) 201 if (!t)
188 return -EINVAL; 202 return -EINVAL;
189 203
204 kind_flag = BTF_INFO_KFLAG(t->info);
190 vlen = BTF_INFO_VLEN(t->info); 205 vlen = BTF_INFO_VLEN(t->info);
191 jsonw_start_object(d->jw); 206 jsonw_start_object(d->jw);
192 m = (struct btf_member *)(t + 1); 207 m = (struct btf_member *)(t + 1);
193 208
194 for (i = 0; i < vlen; i++) { 209 for (i = 0; i < vlen; i++) {
195 data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset); 210 __u32 bit_offset = m[i].offset;
211 __u32 bitfield_size = 0;
212
213 if (kind_flag) {
214 bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
215 bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
216 }
217
196 jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off)); 218 jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
197 ret = btf_dumper_do_type(d, m[i].type, 219 if (bitfield_size) {
198 BITS_PER_BYTE_MASKED(m[i].offset), 220 btf_dumper_bitfield(bitfield_size, bit_offset,
199 data_off); 221 data, d->jw, d->is_plain_text);
200 if (ret) 222 } else {
201 break; 223 data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
224 ret = btf_dumper_do_type(d, m[i].type,
225 BITS_PER_BYTE_MASKED(bit_offset),
226 data_off);
227 if (ret)
228 break;
229 }
202 } 230 }
203 231
204 jsonw_end_object(d->jw); 232 jsonw_end_object(d->jw);
@@ -285,6 +313,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
285 313
286 switch (BTF_INFO_KIND(t->info)) { 314 switch (BTF_INFO_KIND(t->info)) {
287 case BTF_KIND_INT: 315 case BTF_KIND_INT:
316 case BTF_KIND_TYPEDEF:
288 BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off)); 317 BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
289 break; 318 break;
290 case BTF_KIND_STRUCT: 319 case BTF_KIND_STRUCT:
@@ -308,10 +337,11 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
308 BTF_PRINT_TYPE(t->type); 337 BTF_PRINT_TYPE(t->type);
309 BTF_PRINT_ARG("* "); 338 BTF_PRINT_ARG("* ");
310 break; 339 break;
311 case BTF_KIND_UNKN:
312 case BTF_KIND_FWD: 340 case BTF_KIND_FWD:
313 case BTF_KIND_TYPEDEF: 341 BTF_PRINT_ARG("%s %s ",
314 return -1; 342 BTF_INFO_KFLAG(t->info) ? "union" : "struct",
343 btf__name_by_offset(btf, t->name_off));
344 break;
315 case BTF_KIND_VOLATILE: 345 case BTF_KIND_VOLATILE:
316 BTF_PRINT_ARG("volatile "); 346 BTF_PRINT_ARG("volatile ");
317 BTF_PRINT_TYPE(t->type); 347 BTF_PRINT_TYPE(t->type);
@@ -335,6 +365,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
335 if (pos == -1) 365 if (pos == -1)
336 return -1; 366 return -1;
337 break; 367 break;
368 case BTF_KIND_UNKN:
338 default: 369 default:
339 return -1; 370 return -1;
340 } 371 }
diff --git a/tools/bpf/bpftool/cfg.c b/tools/bpf/bpftool/cfg.c
index f30b3a4a840b..31f0db41513f 100644
--- a/tools/bpf/bpftool/cfg.c
+++ b/tools/bpf/bpftool/cfg.c
@@ -1,39 +1,5 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/* 2/* Copyright (C) 2018 Netronome Systems, Inc. */
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37 3
38#include <linux/list.h> 4#include <linux/list.h>
39#include <stdlib.h> 5#include <stdlib.h>
diff --git a/tools/bpf/bpftool/cfg.h b/tools/bpf/bpftool/cfg.h
index 2cc9bd990b13..e144257ea6d2 100644
--- a/tools/bpf/bpftool/cfg.h
+++ b/tools/bpf/bpftool/cfg.h
@@ -1,39 +1,5 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2/* 2/* Copyright (C) 2018 Netronome Systems, Inc. */
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37 3
38#ifndef __BPF_TOOL_CFG_H 4#ifndef __BPF_TOOL_CFG_H
39#define __BPF_TOOL_CFG_H 5#define __BPF_TOOL_CFG_H
diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
index ee7a9765c6b3..4b5c8da2a7c0 100644
--- a/tools/bpf/bpftool/cgroup.c
+++ b/tools/bpf/bpftool/cgroup.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2// Copyright (C) 2017 Facebook 2// Copyright (C) 2017 Facebook
3// Author: Roman Gushchin <guro@fb.com> 3// Author: Roman Gushchin <guro@fb.com>
4 4
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index 172d3761d9ab..897483457bf0 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -1,35 +1,5 @@
1/* 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 * Copyright (C) 2017-2018 Netronome Systems, Inc. 2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33 3
34#include <ctype.h> 4#include <ctype.h>
35#include <errno.h> 5#include <errno.h>
@@ -58,7 +28,7 @@
58#define BPF_FS_MAGIC 0xcafe4a11 28#define BPF_FS_MAGIC 0xcafe4a11
59#endif 29#endif
60 30
61void p_err(const char *fmt, ...) 31void __printf(1, 2) p_err(const char *fmt, ...)
62{ 32{
63 va_list ap; 33 va_list ap;
64 34
@@ -76,7 +46,7 @@ void p_err(const char *fmt, ...)
76 va_end(ap); 46 va_end(ap);
77} 47}
78 48
79void p_info(const char *fmt, ...) 49void __printf(1, 2) p_info(const char *fmt, ...)
80{ 50{
81 va_list ap; 51 va_list ap;
82 52
@@ -106,7 +76,8 @@ void set_max_rlimit(void)
106 setrlimit(RLIMIT_MEMLOCK, &rinf); 76 setrlimit(RLIMIT_MEMLOCK, &rinf);
107} 77}
108 78
109static int mnt_bpffs(const char *target, char *buff, size_t bufflen) 79static int
80mnt_fs(const char *target, const char *type, char *buff, size_t bufflen)
110{ 81{
111 bool bind_done = false; 82 bool bind_done = false;
112 83
@@ -128,15 +99,29 @@ static int mnt_bpffs(const char *target, char *buff, size_t bufflen)
128 bind_done = true; 99 bind_done = true;
129 } 100 }
130 101
131 if (mount("bpf", target, "bpf", 0, "mode=0700")) { 102 if (mount(type, target, type, 0, "mode=0700")) {
132 snprintf(buff, bufflen, "mount -t bpf bpf %s failed: %s", 103 snprintf(buff, bufflen, "mount -t %s %s %s failed: %s",
133 target, strerror(errno)); 104 type, type, target, strerror(errno));
134 return -1; 105 return -1;
135 } 106 }
136 107
137 return 0; 108 return 0;
138} 109}
139 110
111int mount_tracefs(const char *target)
112{
113 char err_str[ERR_MAX_LEN];
114 int err;
115
116 err = mnt_fs(target, "tracefs", err_str, ERR_MAX_LEN);
117 if (err) {
118 err_str[ERR_MAX_LEN - 1] = '\0';
119 p_err("can't mount tracefs: %s", err_str);
120 }
121
122 return err;
123}
124
140int open_obj_pinned(char *path, bool quiet) 125int open_obj_pinned(char *path, bool quiet)
141{ 126{
142 int fd; 127 int fd;
@@ -192,7 +177,13 @@ int mount_bpffs_for_pin(const char *name)
192 /* nothing to do if already mounted */ 177 /* nothing to do if already mounted */
193 goto out_free; 178 goto out_free;
194 179
195 err = mnt_bpffs(dir, err_str, ERR_MAX_LEN); 180 if (block_mount) {
181 p_err("no BPF file system found, not mounting it due to --nomount option");
182 err = -1;
183 goto out_free;
184 }
185
186 err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN);
196 if (err) { 187 if (err) {
197 err_str[ERR_MAX_LEN - 1] = '\0'; 188 err_str[ERR_MAX_LEN - 1] = '\0';
198 p_err("can't mount BPF file system to pin the object (%s): %s", 189 p_err("can't mount BPF file system to pin the object (%s): %s",
diff --git a/tools/bpf/bpftool/jit_disasm.c b/tools/bpf/bpftool/jit_disasm.c
index f381f8628ce9..3ef3093560ba 100644
--- a/tools/bpf/bpftool/jit_disasm.c
+++ b/tools/bpf/bpftool/jit_disasm.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
1/* 2/*
2 * Based on: 3 * Based on:
3 * 4 *
diff --git a/tools/bpf/bpftool/json_writer.c b/tools/bpf/bpftool/json_writer.c
index c6eef76322ae..bff7ee026680 100644
--- a/tools/bpf/bpftool/json_writer.c
+++ b/tools/bpf/bpftool/json_writer.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
1/* 2/*
2 * Simple streaming JSON writer 3 * Simple streaming JSON writer
3 * 4 *
@@ -19,6 +20,7 @@
19#include <malloc.h> 20#include <malloc.h>
20#include <inttypes.h> 21#include <inttypes.h>
21#include <stdint.h> 22#include <stdint.h>
23#include <linux/compiler.h>
22 24
23#include "json_writer.h" 25#include "json_writer.h"
24 26
@@ -156,7 +158,8 @@ void jsonw_name(json_writer_t *self, const char *name)
156 putc(' ', self->out); 158 putc(' ', self->out);
157} 159}
158 160
159void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) 161void __printf(2, 0)
162jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap)
160{ 163{
161 jsonw_eor(self); 164 jsonw_eor(self);
162 putc('"', self->out); 165 putc('"', self->out);
@@ -164,7 +167,7 @@ void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap)
164 putc('"', self->out); 167 putc('"', self->out);
165} 168}
166 169
167void jsonw_printf(json_writer_t *self, const char *fmt, ...) 170void __printf(2, 3) jsonw_printf(json_writer_t *self, const char *fmt, ...)
168{ 171{
169 va_list ap; 172 va_list ap;
170 173
diff --git a/tools/bpf/bpftool/json_writer.h b/tools/bpf/bpftool/json_writer.h
index 0fa2fb1b6351..c1ab51aed99c 100644
--- a/tools/bpf/bpftool/json_writer.h
+++ b/tools/bpf/bpftool/json_writer.h
@@ -1,3 +1,4 @@
1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
1/* 2/*
2 * Simple streaming JSON writer 3 * Simple streaming JSON writer
3 * 4 *
diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c
index 5c4c1cd5a7ba..f44a1c2c4ea0 100644
--- a/tools/bpf/bpftool/main.c
+++ b/tools/bpf/bpftool/main.c
@@ -1,35 +1,5 @@
1/* 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 * Copyright (C) 2017-2018 Netronome Systems, Inc. 2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33 3
34#include <ctype.h> 4#include <ctype.h>
35#include <errno.h> 5#include <errno.h>
@@ -54,6 +24,7 @@ json_writer_t *json_wtr;
54bool pretty_output; 24bool pretty_output;
55bool json_output; 25bool json_output;
56bool show_pinned; 26bool show_pinned;
27bool block_mount;
57int bpf_flags; 28int bpf_flags;
58struct pinned_obj_table prog_table; 29struct pinned_obj_table prog_table;
59struct pinned_obj_table map_table; 30struct pinned_obj_table map_table;
@@ -343,6 +314,7 @@ int main(int argc, char **argv)
343 { "version", no_argument, NULL, 'V' }, 314 { "version", no_argument, NULL, 'V' },
344 { "bpffs", no_argument, NULL, 'f' }, 315 { "bpffs", no_argument, NULL, 'f' },
345 { "mapcompat", no_argument, NULL, 'm' }, 316 { "mapcompat", no_argument, NULL, 'm' },
317 { "nomount", no_argument, NULL, 'n' },
346 { 0 } 318 { 0 }
347 }; 319 };
348 int opt, ret; 320 int opt, ret;
@@ -351,13 +323,14 @@ int main(int argc, char **argv)
351 pretty_output = false; 323 pretty_output = false;
352 json_output = false; 324 json_output = false;
353 show_pinned = false; 325 show_pinned = false;
326 block_mount = false;
354 bin_name = argv[0]; 327 bin_name = argv[0];
355 328
356 hash_init(prog_table.table); 329 hash_init(prog_table.table);
357 hash_init(map_table.table); 330 hash_init(map_table.table);
358 331
359 opterr = 0; 332 opterr = 0;
360 while ((opt = getopt_long(argc, argv, "Vhpjfm", 333 while ((opt = getopt_long(argc, argv, "Vhpjfmn",
361 options, NULL)) >= 0) { 334 options, NULL)) >= 0) {
362 switch (opt) { 335 switch (opt) {
363 case 'V': 336 case 'V':
@@ -384,6 +357,9 @@ int main(int argc, char **argv)
384 case 'm': 357 case 'm':
385 bpf_flags = MAPS_RELAX_COMPAT; 358 bpf_flags = MAPS_RELAX_COMPAT;
386 break; 359 break;
360 case 'n':
361 block_mount = true;
362 break;
387 default: 363 default:
388 p_err("unrecognized option '%s'", argv[optind - 1]); 364 p_err("unrecognized option '%s'", argv[optind - 1]);
389 if (json_output) 365 if (json_output)
diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
index 0b37599f8cda..052c91d4dc55 100644
--- a/tools/bpf/bpftool/main.h
+++ b/tools/bpf/bpftool/main.h
@@ -1,35 +1,5 @@
1/* 1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2 * Copyright (C) 2017-2018 Netronome Systems, Inc. 2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33 3
34#ifndef __BPF_TOOL_H 4#ifndef __BPF_TOOL_H
35#define __BPF_TOOL_H 5#define __BPF_TOOL_H
@@ -74,7 +44,8 @@
74#define HELP_SPEC_PROGRAM \ 44#define HELP_SPEC_PROGRAM \
75 "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }" 45 "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }"
76#define HELP_SPEC_OPTIONS \ 46#define HELP_SPEC_OPTIONS \
77 "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} | {-m|--mapcompat}" 47 "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n" \
48 "\t {-m|--mapcompat} | {-n|--nomount} }"
78#define HELP_SPEC_MAP \ 49#define HELP_SPEC_MAP \
79 "MAP := { id MAP_ID | pinned FILE }" 50 "MAP := { id MAP_ID | pinned FILE }"
80 51
@@ -115,6 +86,7 @@ extern const char *bin_name;
115extern json_writer_t *json_wtr; 86extern json_writer_t *json_wtr;
116extern bool json_output; 87extern bool json_output;
117extern bool show_pinned; 88extern bool show_pinned;
89extern bool block_mount;
118extern int bpf_flags; 90extern int bpf_flags;
119extern struct pinned_obj_table prog_table; 91extern struct pinned_obj_table prog_table;
120extern struct pinned_obj_table map_table; 92extern struct pinned_obj_table map_table;
@@ -128,6 +100,8 @@ void usage(void) __noreturn;
128 100
129void set_max_rlimit(void); 101void set_max_rlimit(void);
130 102
103int mount_tracefs(const char *target);
104
131struct pinned_obj_table { 105struct pinned_obj_table {
132 DECLARE_HASHTABLE(table, 16); 106 DECLARE_HASHTABLE(table, 16);
133}; 107};
@@ -177,8 +151,8 @@ int prog_parse_fd(int *argc, char ***argv);
177int map_parse_fd(int *argc, char ***argv); 151int map_parse_fd(int *argc, char ***argv);
178int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len); 152int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
179 153
180#ifdef HAVE_LIBBFD_SUPPORT
181struct bpf_prog_linfo; 154struct bpf_prog_linfo;
155#ifdef HAVE_LIBBFD_SUPPORT
182void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes, 156void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
183 const char *arch, const char *disassembler_options, 157 const char *arch, const char *disassembler_options,
184 const struct btf *btf, 158 const struct btf *btf,
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index 8469ea6cf1c8..2037e3dc864b 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -1,35 +1,5 @@
1/* 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 * Copyright (C) 2017-2018 Netronome Systems, Inc. 2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33 3
34#include <assert.h> 4#include <assert.h>
35#include <errno.h> 5#include <errno.h>
diff --git a/tools/bpf/bpftool/map_perf_ring.c b/tools/bpf/bpftool/map_perf_ring.c
index bdaf4062e26e..0507dfaf7a8f 100644
--- a/tools/bpf/bpftool/map_perf_ring.c
+++ b/tools/bpf/bpftool/map_perf_ring.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0-only 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/* Copyright (C) 2018 Netronome Systems, Inc. */ 2/* Copyright (C) 2018 Netronome Systems, Inc. */
3/* This program is free software; you can redistribute it and/or 3/* This program is free software; you can redistribute it and/or
4 * modify it under the terms of version 2 of the GNU General Public 4 * modify it under the terms of version 2 of the GNU General Public
diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c
index d441bb7035ca..db0e7de49d49 100644
--- a/tools/bpf/bpftool/net.c
+++ b/tools/bpf/bpftool/net.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2// Copyright (C) 2018 Facebook 2// Copyright (C) 2018 Facebook
3 3
4#define _GNU_SOURCE 4#define _GNU_SOURCE
diff --git a/tools/bpf/bpftool/netlink_dumper.c b/tools/bpf/bpftool/netlink_dumper.c
index 4e9f4531269f..550a0f537eed 100644
--- a/tools/bpf/bpftool/netlink_dumper.c
+++ b/tools/bpf/bpftool/netlink_dumper.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2// Copyright (C) 2018 Facebook 2// Copyright (C) 2018 Facebook
3 3
4#include <stdlib.h> 4#include <stdlib.h>
diff --git a/tools/bpf/bpftool/netlink_dumper.h b/tools/bpf/bpftool/netlink_dumper.h
index e3516b586a34..774af6c62ef5 100644
--- a/tools/bpf/bpftool/netlink_dumper.h
+++ b/tools/bpf/bpftool/netlink_dumper.h
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2// Copyright (C) 2018 Facebook 2// Copyright (C) 2018 Facebook
3 3
4#ifndef _NETLINK_DUMPER_H_ 4#ifndef _NETLINK_DUMPER_H_
diff --git a/tools/bpf/bpftool/perf.c b/tools/bpf/bpftool/perf.c
index b76b77dcfd1f..f2a545e667c4 100644
--- a/tools/bpf/bpftool/perf.c
+++ b/tools/bpf/bpftool/perf.c
@@ -1,4 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0+ 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2// Copyright (C) 2018 Facebook 2// Copyright (C) 2018 Facebook
3// Author: Yonghong Song <yhs@fb.com> 3// Author: Yonghong Song <yhs@fb.com>
4 4
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index b73b4e473948..2d1bb7d6ff51 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -1,35 +1,5 @@
1/* 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 * Copyright (C) 2017-2018 Netronome Systems, Inc. 2/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33 3
34#define _GNU_SOURCE 4#define _GNU_SOURCE
35#include <errno.h> 5#include <errno.h>
@@ -62,7 +32,7 @@ static const char * const attach_type_strings[] = {
62 [__MAX_BPF_ATTACH_TYPE] = NULL, 32 [__MAX_BPF_ATTACH_TYPE] = NULL,
63}; 33};
64 34
65enum bpf_attach_type parse_attach_type(const char *str) 35static enum bpf_attach_type parse_attach_type(const char *str)
66{ 36{
67 enum bpf_attach_type type; 37 enum bpf_attach_type type;
68 38
@@ -626,13 +596,6 @@ static int do_dump(int argc, char **argv)
626 goto err_free; 596 goto err_free;
627 } 597 }
628 598
629 if (func_info && !info.func_info) {
630 /* kernel.kptr_restrict is set. No func_info available. */
631 free(func_info);
632 func_info = NULL;
633 nr_finfo = 0;
634 }
635
636 if (linfo && info.nr_line_info != nr_linfo) { 599 if (linfo && info.nr_line_info != nr_linfo) {
637 p_err("incorrect nr_line_info %u vs. expected %u", 600 p_err("incorrect nr_line_info %u vs. expected %u",
638 info.nr_line_info, nr_linfo); 601 info.nr_line_info, nr_linfo);
@@ -835,7 +798,7 @@ struct map_replace {
835 char *name; 798 char *name;
836}; 799};
837 800
838int map_replace_compar(const void *p1, const void *p2) 801static int map_replace_compar(const void *p1, const void *p2)
839{ 802{
840 const struct map_replace *a = p1, *b = p2; 803 const struct map_replace *a = p1, *b = p2;
841 804
diff --git a/tools/bpf/bpftool/tracelog.c b/tools/bpf/bpftool/tracelog.c
index 1fa8e513f590..e80a5c79b38f 100644
--- a/tools/bpf/bpftool/tracelog.c
+++ b/tools/bpf/bpftool/tracelog.c
@@ -54,7 +54,7 @@ find_tracefs_mnt_single(unsigned long magic, char *mnt, const char *mntpt)
54 return true; 54 return true;
55} 55}
56 56
57static bool find_tracefs_pipe(char *mnt) 57static bool get_tracefs_pipe(char *mnt)
58{ 58{
59 static const char * const known_mnts[] = { 59 static const char * const known_mnts[] = {
60 "/sys/kernel/debug/tracing", 60 "/sys/kernel/debug/tracing",
@@ -88,7 +88,20 @@ static bool find_tracefs_pipe(char *mnt)
88 fclose(fp); 88 fclose(fp);
89 89
90 /* The string from fscanf() might be truncated, check mnt is valid */ 90 /* The string from fscanf() might be truncated, check mnt is valid */
91 if (!found || validate_tracefs_mnt(mnt, TRACEFS_MAGIC)) 91 if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
92 goto exit_found;
93
94 if (block_mount)
95 return false;
96
97 p_info("could not find tracefs, attempting to mount it now");
98 /* Most of the time, tracefs is automatically mounted by debugfs at
99 * /sys/kernel/debug/tracing when we try to access it. If we could not
100 * find it, it is likely that debugfs is not mounted. Let's give one
101 * attempt at mounting just tracefs at /sys/kernel/tracing.
102 */
103 strcpy(mnt, known_mnts[1]);
104 if (mount_tracefs(mnt))
92 return false; 105 return false;
93 106
94exit_found: 107exit_found:
@@ -115,17 +128,13 @@ int do_tracelog(int argc, char **argv)
115 .sa_handler = exit_tracelog 128 .sa_handler = exit_tracelog
116 }; 129 };
117 char trace_pipe[PATH_MAX]; 130 char trace_pipe[PATH_MAX];
118 bool found_trace_pipe;
119 size_t buff_len = 0; 131 size_t buff_len = 0;
120 132
121 if (json_output) 133 if (json_output)
122 jsonw_start_array(json_wtr); 134 jsonw_start_array(json_wtr);
123 135
124 found_trace_pipe = find_tracefs_pipe(trace_pipe); 136 if (!get_tracefs_pipe(trace_pipe))
125 if (!found_trace_pipe) {
126 p_err("could not find trace pipe, tracefs not mounted?");
127 return -1; 137 return -1;
128 }
129 138
130 trace_pipe_fd = fopen(trace_pipe, "r"); 139 trace_pipe_fd = fopen(trace_pipe, "r");
131 if (!trace_pipe_fd) { 140 if (!trace_pipe_fd) {
diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c
index aef628dcccb6..7073dbe1ff27 100644
--- a/tools/bpf/bpftool/xlated_dumper.c
+++ b/tools/bpf/bpftool/xlated_dumper.c
@@ -1,39 +1,5 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2/* 2/* Copyright (C) 2018 Netronome Systems, Inc. */
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37 3
38#define _GNU_SOURCE 4#define _GNU_SOURCE
39#include <stdarg.h> 5#include <stdarg.h>
@@ -115,7 +81,7 @@ struct kernel_sym *kernel_syms_search(struct dump_data *dd,
115 sizeof(*dd->sym_mapping), kernel_syms_cmp) : NULL; 81 sizeof(*dd->sym_mapping), kernel_syms_cmp) : NULL;
116} 82}
117 83
118static void print_insn(void *private_data, const char *fmt, ...) 84static void __printf(2, 3) print_insn(void *private_data, const char *fmt, ...)
119{ 85{
120 va_list args; 86 va_list args;
121 87
@@ -124,7 +90,7 @@ static void print_insn(void *private_data, const char *fmt, ...)
124 va_end(args); 90 va_end(args);
125} 91}
126 92
127static void 93static void __printf(2, 3)
128print_insn_for_graph(void *private_data, const char *fmt, ...) 94print_insn_for_graph(void *private_data, const char *fmt, ...)
129{ 95{
130 char buf[64], *p; 96 char buf[64], *p;
@@ -155,7 +121,8 @@ print_insn_for_graph(void *private_data, const char *fmt, ...)
155 printf("%s", buf); 121 printf("%s", buf);
156} 122}
157 123
158static void print_insn_json(void *private_data, const char *fmt, ...) 124static void __printf(2, 3)
125print_insn_json(void *private_data, const char *fmt, ...)
159{ 126{
160 unsigned int l = strlen(fmt); 127 unsigned int l = strlen(fmt);
161 char chomped_fmt[l]; 128 char chomped_fmt[l];
diff --git a/tools/bpf/bpftool/xlated_dumper.h b/tools/bpf/bpftool/xlated_dumper.h
index a24f89df8cb2..54847e174273 100644
--- a/tools/bpf/bpftool/xlated_dumper.h
+++ b/tools/bpf/bpftool/xlated_dumper.h
@@ -1,39 +1,5 @@
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2/* 2/* Copyright (C) 2018 Netronome Systems, Inc. */
3 * Copyright (C) 2018 Netronome Systems, Inc.
4 *
5 * This software is dual licensed under the GNU General License Version 2,
6 * June 1991 as shown in the file COPYING in the top-level directory of this
7 * source tree or the BSD 2-Clause License provided below. You have the
8 * option to license this software under the complete terms of either license.
9 *
10 * The BSD 2-Clause License:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37 3
38#ifndef __BPF_TOOL_XLATED_DUMPER_H 4#ifndef __BPF_TOOL_XLATED_DUMPER_H
39#define __BPF_TOOL_XLATED_DUMPER_H 5#define __BPF_TOOL_XLATED_DUMPER_H
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index aa582cd5bfcf..91c43884f295 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -133,6 +133,14 @@ enum bpf_map_type {
133 BPF_MAP_TYPE_STACK, 133 BPF_MAP_TYPE_STACK,
134}; 134};
135 135
136/* Note that tracing related programs such as
137 * BPF_PROG_TYPE_{KPROBE,TRACEPOINT,PERF_EVENT,RAW_TRACEPOINT}
138 * are not subject to a stable API since kernel internal data
139 * structures can change from release to release and may
140 * therefore break existing tracing BPF programs. Tracing BPF
141 * programs correspond to /a/ specific kernel which is to be
142 * analyzed, and not /a/ specific kernel /and/ all future ones.
143 */
136enum bpf_prog_type { 144enum bpf_prog_type {
137 BPF_PROG_TYPE_UNSPEC, 145 BPF_PROG_TYPE_UNSPEC,
138 BPF_PROG_TYPE_SOCKET_FILTER, 146 BPF_PROG_TYPE_SOCKET_FILTER,
@@ -343,7 +351,7 @@ union bpf_attr {
343 __u32 log_level; /* verbosity level of verifier */ 351 __u32 log_level; /* verbosity level of verifier */
344 __u32 log_size; /* size of user buffer */ 352 __u32 log_size; /* size of user buffer */
345 __aligned_u64 log_buf; /* user supplied buffer */ 353 __aligned_u64 log_buf; /* user supplied buffer */
346 __u32 kern_version; /* checked when prog_type=kprobe */ 354 __u32 kern_version; /* not used */
347 __u32 prog_flags; 355 __u32 prog_flags;
348 char prog_name[BPF_OBJ_NAME_LEN]; 356 char prog_name[BPF_OBJ_NAME_LEN];
349 __u32 prog_ifindex; /* ifindex of netdev to prep for */ 357 __u32 prog_ifindex; /* ifindex of netdev to prep for */
@@ -2657,6 +2665,7 @@ struct sk_msg_md {
2657 __u32 local_ip6[4]; /* Stored in network byte order */ 2665 __u32 local_ip6[4]; /* Stored in network byte order */
2658 __u32 remote_port; /* Stored in network byte order */ 2666 __u32 remote_port; /* Stored in network byte order */
2659 __u32 local_port; /* stored in host byte order */ 2667 __u32 local_port; /* stored in host byte order */
2668 __u32 size; /* Total size of sk_msg */
2660}; 2669};
2661 2670
2662struct sk_reuseport_md { 2671struct sk_reuseport_md {
@@ -2717,6 +2726,8 @@ struct bpf_prog_info {
2717 __u32 nr_jited_line_info; 2726 __u32 nr_jited_line_info;
2718 __u32 line_info_rec_size; 2727 __u32 line_info_rec_size;
2719 __u32 jited_line_info_rec_size; 2728 __u32 jited_line_info_rec_size;
2729 __u32 nr_prog_tags;
2730 __aligned_u64 prog_tags;
2720} __attribute__((aligned(8))); 2731} __attribute__((aligned(8)));
2721 2732
2722struct bpf_map_info { 2733struct bpf_map_info {
diff --git a/tools/include/uapi/linux/btf.h b/tools/include/uapi/linux/btf.h
index 14f66948fc95..7b7475ef2f17 100644
--- a/tools/include/uapi/linux/btf.h
+++ b/tools/include/uapi/linux/btf.h
@@ -34,7 +34,9 @@ struct btf_type {
34 * bits 0-15: vlen (e.g. # of struct's members) 34 * bits 0-15: vlen (e.g. # of struct's members)
35 * bits 16-23: unused 35 * bits 16-23: unused
36 * bits 24-27: kind (e.g. int, ptr, array...etc) 36 * bits 24-27: kind (e.g. int, ptr, array...etc)
37 * bits 28-31: unused 37 * bits 28-30: unused
38 * bit 31: kind_flag, currently used by
39 * struct, union and fwd
38 */ 40 */
39 __u32 info; 41 __u32 info;
40 /* "size" is used by INT, ENUM, STRUCT and UNION. 42 /* "size" is used by INT, ENUM, STRUCT and UNION.
@@ -52,6 +54,7 @@ struct btf_type {
52 54
53#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f) 55#define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
54#define BTF_INFO_VLEN(info) ((info) & 0xffff) 56#define BTF_INFO_VLEN(info) ((info) & 0xffff)
57#define BTF_INFO_KFLAG(info) ((info) >> 31)
55 58
56#define BTF_KIND_UNKN 0 /* Unknown */ 59#define BTF_KIND_UNKN 0 /* Unknown */
57#define BTF_KIND_INT 1 /* Integer */ 60#define BTF_KIND_INT 1 /* Integer */
@@ -110,9 +113,22 @@ struct btf_array {
110struct btf_member { 113struct btf_member {
111 __u32 name_off; 114 __u32 name_off;
112 __u32 type; 115 __u32 type;
113 __u32 offset; /* offset in bits */ 116 /* If the type info kind_flag is set, the btf_member offset
117 * contains both member bitfield size and bit offset. The
118 * bitfield size is set for bitfield members. If the type
119 * info kind_flag is not set, the offset contains only bit
120 * offset.
121 */
122 __u32 offset;
114}; 123};
115 124
125/* If the struct/union type info kind_flag is set, the
126 * following two macros are used to access bitfield_size
127 * and bit_offset from btf_member.offset.
128 */
129#define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24)
130#define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff)
131
116/* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param". 132/* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param".
117 * The exact number of btf_param is stored in the vlen (of the 133 * The exact number of btf_param is stored in the vlen (of the
118 * info in "struct btf_type"). 134 * info in "struct btf_type").
diff --git a/tools/lib/bpf/bpf_prog_linfo.c b/tools/lib/bpf/bpf_prog_linfo.c
index addd6e9971cc..6978314ea7f6 100644
--- a/tools/lib/bpf/bpf_prog_linfo.c
+++ b/tools/lib/bpf/bpf_prog_linfo.c
@@ -107,11 +107,7 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info)
107 107
108 nr_linfo = info->nr_line_info; 108 nr_linfo = info->nr_line_info;
109 109
110 /* 110 if (!nr_linfo)
111 * Test !info->line_info because the kernel may NULL
112 * the ptr if kernel.kptr_restrict is set.
113 */
114 if (!nr_linfo || !info->line_info)
115 return NULL; 111 return NULL;
116 112
117 /* 113 /*
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index e2bc75ee1614..169e347c76f6 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -266,6 +266,7 @@ void bpf_program__unload(struct bpf_program *prog)
266 266
267 zclose(prog->btf_fd); 267 zclose(prog->btf_fd);
268 zfree(&prog->func_info); 268 zfree(&prog->func_info);
269 zfree(&prog->line_info);
269} 270}
270 271
271static void bpf_program__exit(struct bpf_program *prog) 272static void bpf_program__exit(struct bpf_program *prog)
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 1b799e30c06d..4a9785043a39 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -27,3 +27,4 @@ test_flow_dissector
27flow_dissector_load 27flow_dissector_load
28test_netcnt 28test_netcnt
29test_section_names 29test_section_names
30test_tcpnotify_user
diff --git a/tools/testing/selftests/bpf/connect4_prog.c b/tools/testing/selftests/bpf/connect4_prog.c
index b8395f3c43e9..1fd244d35ba9 100644
--- a/tools/testing/selftests/bpf/connect4_prog.c
+++ b/tools/testing/selftests/bpf/connect4_prog.c
@@ -35,9 +35,11 @@ int connect_v4_prog(struct bpf_sock_addr *ctx)
35 if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM) 35 if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
36 return 0; 36 return 0;
37 else if (ctx->type == SOCK_STREAM) 37 else if (ctx->type == SOCK_STREAM)
38 sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv4), 0, 0); 38 sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv4),
39 BPF_F_CURRENT_NETNS, 0);
39 else 40 else
40 sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv4), 0, 0); 41 sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv4),
42 BPF_F_CURRENT_NETNS, 0);
41 43
42 if (!sk) 44 if (!sk)
43 return 0; 45 return 0;
diff --git a/tools/testing/selftests/bpf/connect6_prog.c b/tools/testing/selftests/bpf/connect6_prog.c
index 25f5dc7b7aa0..26397ab7b3c7 100644
--- a/tools/testing/selftests/bpf/connect6_prog.c
+++ b/tools/testing/selftests/bpf/connect6_prog.c
@@ -47,9 +47,11 @@ int connect_v6_prog(struct bpf_sock_addr *ctx)
47 if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM) 47 if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
48 return 0; 48 return 0;
49 else if (ctx->type == SOCK_STREAM) 49 else if (ctx->type == SOCK_STREAM)
50 sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv6), 0, 0); 50 sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv6),
51 BPF_F_CURRENT_NETNS, 0);
51 else 52 else
52 sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv6), 0, 0); 53 sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv6),
54 BPF_F_CURRENT_NETNS, 0);
53 55
54 if (!sk) 56 if (!sk)
55 return 0; 57 return 0;
diff --git a/tools/testing/selftests/bpf/netcnt_prog.c b/tools/testing/selftests/bpf/netcnt_prog.c
index 1198abca1360..9f741e69cebe 100644
--- a/tools/testing/selftests/bpf/netcnt_prog.c
+++ b/tools/testing/selftests/bpf/netcnt_prog.c
@@ -16,12 +16,18 @@ struct bpf_map_def SEC("maps") percpu_netcnt = {
16 .value_size = sizeof(struct percpu_net_cnt), 16 .value_size = sizeof(struct percpu_net_cnt),
17}; 17};
18 18
19BPF_ANNOTATE_KV_PAIR(percpu_netcnt, struct bpf_cgroup_storage_key,
20 struct percpu_net_cnt);
21
19struct bpf_map_def SEC("maps") netcnt = { 22struct bpf_map_def SEC("maps") netcnt = {
20 .type = BPF_MAP_TYPE_CGROUP_STORAGE, 23 .type = BPF_MAP_TYPE_CGROUP_STORAGE,
21 .key_size = sizeof(struct bpf_cgroup_storage_key), 24 .key_size = sizeof(struct bpf_cgroup_storage_key),
22 .value_size = sizeof(struct net_cnt), 25 .value_size = sizeof(struct net_cnt),
23}; 26};
24 27
28BPF_ANNOTATE_KV_PAIR(netcnt, struct bpf_cgroup_storage_key,
29 struct net_cnt);
30
25SEC("cgroup/skb") 31SEC("cgroup/skb")
26int bpf_nextcnt(struct __sk_buff *skb) 32int bpf_nextcnt(struct __sk_buff *skb)
27{ 33{
diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
index f570e0a39959..8bcd38010582 100644
--- a/tools/testing/selftests/bpf/test_btf.c
+++ b/tools/testing/selftests/bpf/test_btf.c
@@ -65,8 +65,8 @@ static int __base_pr(const char *format, ...)
65 return err; 65 return err;
66} 66}
67 67
68#define BTF_INFO_ENC(kind, root, vlen) \ 68#define BTF_INFO_ENC(kind, kind_flag, vlen) \
69 ((!!(root) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN)) 69 ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
70 70
71#define BTF_TYPE_ENC(name, info, size_or_type) \ 71#define BTF_TYPE_ENC(name, info, size_or_type) \
72 (name), (info), (size_or_type) 72 (name), (info), (size_or_type)
@@ -86,6 +86,8 @@ static int __base_pr(const char *format, ...)
86#define BTF_MEMBER_ENC(name, type, bits_offset) \ 86#define BTF_MEMBER_ENC(name, type, bits_offset) \
87 (name), (type), (bits_offset) 87 (name), (type), (bits_offset)
88#define BTF_ENUM_ENC(name, val) (name), (val) 88#define BTF_ENUM_ENC(name, val) (name), (val)
89#define BTF_MEMBER_OFFSET(bitfield_size, bits_offset) \
90 ((bitfield_size) << 24 | (bits_offset))
89 91
90#define BTF_TYPEDEF_ENC(name, type) \ 92#define BTF_TYPEDEF_ENC(name, type) \
91 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type) 93 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
@@ -2215,6 +2217,496 @@ static struct btf_raw_test raw_tests[] = {
2215 .err_str = "Invalid type_id", 2217 .err_str = "Invalid type_id",
2216}, 2218},
2217 2219
2220{
2221 .descr = "invalid int kind_flag",
2222 .raw_types = {
2223 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2224 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4), /* [2] */
2225 BTF_INT_ENC(0, 0, 32),
2226 BTF_END_RAW,
2227 },
2228 BTF_STR_SEC(""),
2229 .map_type = BPF_MAP_TYPE_ARRAY,
2230 .map_name = "int_type_check_btf",
2231 .key_size = sizeof(int),
2232 .value_size = sizeof(int),
2233 .key_type_id = 1,
2234 .value_type_id = 1,
2235 .max_entries = 4,
2236 .btf_load_err = true,
2237 .err_str = "Invalid btf_info kind_flag",
2238},
2239
2240{
2241 .descr = "invalid ptr kind_flag",
2242 .raw_types = {
2243 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2244 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1), /* [2] */
2245 BTF_END_RAW,
2246 },
2247 BTF_STR_SEC(""),
2248 .map_type = BPF_MAP_TYPE_ARRAY,
2249 .map_name = "ptr_type_check_btf",
2250 .key_size = sizeof(int),
2251 .value_size = sizeof(int),
2252 .key_type_id = 1,
2253 .value_type_id = 1,
2254 .max_entries = 4,
2255 .btf_load_err = true,
2256 .err_str = "Invalid btf_info kind_flag",
2257},
2258
2259{
2260 .descr = "invalid array kind_flag",
2261 .raw_types = {
2262 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2263 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2264 BTF_ARRAY_ENC(1, 1, 1),
2265 BTF_END_RAW,
2266 },
2267 BTF_STR_SEC(""),
2268 .map_type = BPF_MAP_TYPE_ARRAY,
2269 .map_name = "array_type_check_btf",
2270 .key_size = sizeof(int),
2271 .value_size = sizeof(int),
2272 .key_type_id = 1,
2273 .value_type_id = 1,
2274 .max_entries = 4,
2275 .btf_load_err = true,
2276 .err_str = "Invalid btf_info kind_flag",
2277},
2278
2279{
2280 .descr = "invalid enum kind_flag",
2281 .raw_types = {
2282 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2283 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4), /* [2] */
2284 BTF_ENUM_ENC(NAME_TBD, 0),
2285 BTF_END_RAW,
2286 },
2287 BTF_STR_SEC("\0A"),
2288 .map_type = BPF_MAP_TYPE_ARRAY,
2289 .map_name = "enum_type_check_btf",
2290 .key_size = sizeof(int),
2291 .value_size = sizeof(int),
2292 .key_type_id = 1,
2293 .value_type_id = 1,
2294 .max_entries = 4,
2295 .btf_load_err = true,
2296 .err_str = "Invalid btf_info kind_flag",
2297},
2298
2299{
2300 .descr = "valid fwd kind_flag",
2301 .raw_types = {
2302 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2303 BTF_TYPE_ENC(NAME_TBD,
2304 BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [2] */
2305 BTF_END_RAW,
2306 },
2307 BTF_STR_SEC("\0A"),
2308 .map_type = BPF_MAP_TYPE_ARRAY,
2309 .map_name = "fwd_type_check_btf",
2310 .key_size = sizeof(int),
2311 .value_size = sizeof(int),
2312 .key_type_id = 1,
2313 .value_type_id = 1,
2314 .max_entries = 4,
2315},
2316
2317{
2318 .descr = "invalid typedef kind_flag",
2319 .raw_types = {
2320 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2321 BTF_TYPE_ENC(NAME_TBD,
2322 BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1), /* [2] */
2323 BTF_END_RAW,
2324 },
2325 BTF_STR_SEC("\0A"),
2326 .map_type = BPF_MAP_TYPE_ARRAY,
2327 .map_name = "typedef_type_check_btf",
2328 .key_size = sizeof(int),
2329 .value_size = sizeof(int),
2330 .key_type_id = 1,
2331 .value_type_id = 1,
2332 .max_entries = 4,
2333 .btf_load_err = true,
2334 .err_str = "Invalid btf_info kind_flag",
2335},
2336
2337{
2338 .descr = "invalid volatile kind_flag",
2339 .raw_types = {
2340 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2341 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1), /* [2] */
2342 BTF_END_RAW,
2343 },
2344 BTF_STR_SEC(""),
2345 .map_type = BPF_MAP_TYPE_ARRAY,
2346 .map_name = "volatile_type_check_btf",
2347 .key_size = sizeof(int),
2348 .value_size = sizeof(int),
2349 .key_type_id = 1,
2350 .value_type_id = 1,
2351 .max_entries = 4,
2352 .btf_load_err = true,
2353 .err_str = "Invalid btf_info kind_flag",
2354},
2355
2356{
2357 .descr = "invalid const kind_flag",
2358 .raw_types = {
2359 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2360 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */
2361 BTF_END_RAW,
2362 },
2363 BTF_STR_SEC(""),
2364 .map_type = BPF_MAP_TYPE_ARRAY,
2365 .map_name = "const_type_check_btf",
2366 .key_size = sizeof(int),
2367 .value_size = sizeof(int),
2368 .key_type_id = 1,
2369 .value_type_id = 1,
2370 .max_entries = 4,
2371 .btf_load_err = true,
2372 .err_str = "Invalid btf_info kind_flag",
2373},
2374
2375{
2376 .descr = "invalid restrict kind_flag",
2377 .raw_types = {
2378 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2379 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1), /* [2] */
2380 BTF_END_RAW,
2381 },
2382 BTF_STR_SEC(""),
2383 .map_type = BPF_MAP_TYPE_ARRAY,
2384 .map_name = "restrict_type_check_btf",
2385 .key_size = sizeof(int),
2386 .value_size = sizeof(int),
2387 .key_type_id = 1,
2388 .value_type_id = 1,
2389 .max_entries = 4,
2390 .btf_load_err = true,
2391 .err_str = "Invalid btf_info kind_flag",
2392},
2393
2394{
2395 .descr = "invalid func kind_flag",
2396 .raw_types = {
2397 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2398 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0), /* [2] */
2399 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2), /* [3] */
2400 BTF_END_RAW,
2401 },
2402 BTF_STR_SEC("\0A"),
2403 .map_type = BPF_MAP_TYPE_ARRAY,
2404 .map_name = "func_type_check_btf",
2405 .key_size = sizeof(int),
2406 .value_size = sizeof(int),
2407 .key_type_id = 1,
2408 .value_type_id = 1,
2409 .max_entries = 4,
2410 .btf_load_err = true,
2411 .err_str = "Invalid btf_info kind_flag",
2412},
2413
2414{
2415 .descr = "invalid func_proto kind_flag",
2416 .raw_types = {
2417 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2418 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0), /* [2] */
2419 BTF_END_RAW,
2420 },
2421 BTF_STR_SEC(""),
2422 .map_type = BPF_MAP_TYPE_ARRAY,
2423 .map_name = "func_proto_type_check_btf",
2424 .key_size = sizeof(int),
2425 .value_size = sizeof(int),
2426 .key_type_id = 1,
2427 .value_type_id = 1,
2428 .max_entries = 4,
2429 .btf_load_err = true,
2430 .err_str = "Invalid btf_info kind_flag",
2431},
2432
2433{
2434 .descr = "valid struct, kind_flag, bitfield_size = 0",
2435 .raw_types = {
2436 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2437 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8), /* [2] */
2438 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
2439 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
2440 BTF_END_RAW,
2441 },
2442 BTF_STR_SEC("\0A\0B"),
2443 .map_type = BPF_MAP_TYPE_ARRAY,
2444 .map_name = "struct_type_check_btf",
2445 .key_size = sizeof(int),
2446 .value_size = sizeof(int),
2447 .key_type_id = 1,
2448 .value_type_id = 1,
2449 .max_entries = 4,
2450},
2451
2452{
2453 .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
2454 .raw_types = {
2455 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2456 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
2457 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2458 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
2459 BTF_END_RAW,
2460 },
2461 BTF_STR_SEC("\0A\0B"),
2462 .map_type = BPF_MAP_TYPE_ARRAY,
2463 .map_name = "struct_type_check_btf",
2464 .key_size = sizeof(int),
2465 .value_size = sizeof(int),
2466 .key_type_id = 1,
2467 .value_type_id = 1,
2468 .max_entries = 4,
2469},
2470
2471{
2472 .descr = "valid union, kind_flag, int member, bitfield_size != 0",
2473 .raw_types = {
2474 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2475 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */
2476 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2477 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2478 BTF_END_RAW,
2479 },
2480 BTF_STR_SEC("\0A\0B"),
2481 .map_type = BPF_MAP_TYPE_ARRAY,
2482 .map_name = "union_type_check_btf",
2483 .key_size = sizeof(int),
2484 .value_size = sizeof(int),
2485 .key_type_id = 1,
2486 .value_type_id = 1,
2487 .max_entries = 4,
2488},
2489
2490{
2491 .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
2492 .raw_types = {
2493 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2494 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2495 BTF_ENUM_ENC(NAME_TBD, 0),
2496 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2497 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2498 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
2499 BTF_END_RAW,
2500 },
2501 BTF_STR_SEC("\0A\0B\0C"),
2502 .map_type = BPF_MAP_TYPE_ARRAY,
2503 .map_name = "struct_type_check_btf",
2504 .key_size = sizeof(int),
2505 .value_size = sizeof(int),
2506 .key_type_id = 1,
2507 .value_type_id = 1,
2508 .max_entries = 4,
2509},
2510
2511{
2512 .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
2513 .raw_types = {
2514 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2515 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2516 BTF_ENUM_ENC(NAME_TBD, 0),
2517 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2518 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2519 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2520 BTF_END_RAW,
2521 },
2522 BTF_STR_SEC("\0A\0B\0C"),
2523 .map_type = BPF_MAP_TYPE_ARRAY,
2524 .map_name = "union_type_check_btf",
2525 .key_size = sizeof(int),
2526 .value_size = sizeof(int),
2527 .key_type_id = 1,
2528 .value_type_id = 1,
2529 .max_entries = 4,
2530},
2531
2532{
2533 .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
2534 .raw_types = {
2535 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2536 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2537 BTF_ENUM_ENC(NAME_TBD, 0),
2538 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2539 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2540 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
2541 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
2542 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
2543 BTF_END_RAW,
2544 },
2545 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2546 .map_type = BPF_MAP_TYPE_ARRAY,
2547 .map_name = "struct_type_check_btf",
2548 .key_size = sizeof(int),
2549 .value_size = sizeof(int),
2550 .key_type_id = 1,
2551 .value_type_id = 1,
2552 .max_entries = 4,
2553},
2554
2555{
2556 .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
2557 .raw_types = {
2558 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2559 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2560 BTF_ENUM_ENC(NAME_TBD, 0),
2561 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2562 BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2563 BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
2564 BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
2565 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
2566 BTF_END_RAW,
2567 },
2568 BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2569 .map_type = BPF_MAP_TYPE_ARRAY,
2570 .map_name = "union_type_check_btf",
2571 .key_size = sizeof(int),
2572 .value_size = sizeof(int),
2573 .key_type_id = 1,
2574 .value_type_id = 1,
2575 .max_entries = 4,
2576},
2577
2578{
2579 .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
2580 .raw_types = {
2581 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2582 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
2583 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2584 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
2585 BTF_END_RAW,
2586 },
2587 BTF_STR_SEC("\0A\0B"),
2588 .map_type = BPF_MAP_TYPE_ARRAY,
2589 .map_name = "struct_type_check_btf",
2590 .key_size = sizeof(int),
2591 .value_size = sizeof(int),
2592 .key_type_id = 1,
2593 .value_type_id = 1,
2594 .max_entries = 4,
2595 .btf_load_err = true,
2596 .err_str = "Member exceeds struct_size",
2597},
2598
2599{
2600 .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
2601 .raw_types = {
2602 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2603 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4), /* [2] */
2604 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
2605 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
2606 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
2607 BTF_END_RAW,
2608 },
2609 BTF_STR_SEC("\0A\0B"),
2610 .map_type = BPF_MAP_TYPE_ARRAY,
2611 .map_name = "struct_type_check_btf",
2612 .key_size = sizeof(int),
2613 .value_size = sizeof(int),
2614 .key_type_id = 1,
2615 .value_type_id = 1,
2616 .max_entries = 4,
2617 .btf_load_err = true,
2618 .err_str = "Invalid member base type",
2619},
2620
2621{
2622 .descr = "invalid struct, kind_flag, base_type int not regular",
2623 .raw_types = {
2624 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2625 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4), /* [2] */
2626 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
2627 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
2628 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
2629 BTF_END_RAW,
2630 },
2631 BTF_STR_SEC("\0A\0B"),
2632 .map_type = BPF_MAP_TYPE_ARRAY,
2633 .map_name = "struct_type_check_btf",
2634 .key_size = sizeof(int),
2635 .value_size = sizeof(int),
2636 .key_type_id = 1,
2637 .value_type_id = 1,
2638 .max_entries = 4,
2639 .btf_load_err = true,
2640 .err_str = "Invalid member base type",
2641},
2642
2643{
2644 .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
2645 .raw_types = {
2646 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2647 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
2648 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
2649 BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2650 BTF_END_RAW,
2651 },
2652 BTF_STR_SEC("\0A\0B"),
2653 .map_type = BPF_MAP_TYPE_ARRAY,
2654 .map_name = "union_type_check_btf",
2655 .key_size = sizeof(int),
2656 .value_size = sizeof(int),
2657 .key_type_id = 1,
2658 .value_type_id = 1,
2659 .max_entries = 4,
2660 .btf_load_err = true,
2661 .err_str = "Member exceeds struct_size",
2662},
2663
2664{
2665 .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
2666 .raw_types = {
2667 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2668 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
2669 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
2670 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2671 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2672 BTF_END_RAW,
2673 },
2674 BTF_STR_SEC("\0A\0B"),
2675 .map_type = BPF_MAP_TYPE_ARRAY,
2676 .map_name = "struct_type_check_btf",
2677 .key_size = sizeof(int),
2678 .value_size = sizeof(int),
2679 .key_type_id = 1,
2680 .value_type_id = 1,
2681 .max_entries = 4,
2682 .btf_load_err = true,
2683 .err_str = "Invalid member offset",
2684},
2685
2686{
2687 .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
2688 .raw_types = {
2689 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2690 BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
2691 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2692 BTF_ENUM_ENC(NAME_TBD, 0),
2693 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
2694 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2695 BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2696 BTF_END_RAW,
2697 },
2698 BTF_STR_SEC("\0A\0B\0C"),
2699 .map_type = BPF_MAP_TYPE_ARRAY,
2700 .map_name = "struct_type_check_btf",
2701 .key_size = sizeof(int),
2702 .value_size = sizeof(int),
2703 .key_type_id = 1,
2704 .value_type_id = 1,
2705 .max_entries = 4,
2706 .btf_load_err = true,
2707 .err_str = "Invalid member offset",
2708},
2709
2218}; /* struct btf_raw_test raw_tests[] */ 2710}; /* struct btf_raw_test raw_tests[] */
2219 2711
2220static const char *get_next_str(const char *start, const char *end) 2712static const char *get_next_str(const char *start, const char *end)
@@ -2916,7 +3408,7 @@ static int do_test_file(unsigned int test_num)
2916 goto done; 3408 goto done;
2917 } 3409 }
2918 rec_size = info.func_info_rec_size; 3410 rec_size = info.func_info_rec_size;
2919 if (CHECK(rec_size < 4, 3411 if (CHECK(rec_size != sizeof(struct bpf_func_info),
2920 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) { 3412 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
2921 err = -1; 3413 err = -1;
2922 goto done; 3414 goto done;
@@ -3036,7 +3528,8 @@ struct pprint_mapv {
3036 } aenum; 3528 } aenum;
3037}; 3529};
3038 3530
3039static struct btf_raw_test pprint_test_template = { 3531static struct btf_raw_test pprint_test_template[] = {
3532{
3040 .raw_types = { 3533 .raw_types = {
3041 /* unsighed char */ /* [1] */ 3534 /* unsighed char */ /* [1] */
3042 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1), 3535 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
@@ -3086,13 +3579,140 @@ static struct btf_raw_test pprint_test_template = {
3086 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */ 3579 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */
3087 BTF_END_RAW, 3580 BTF_END_RAW,
3088 }, 3581 },
3089 .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum", 3582 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
3090 .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"), 3583 .key_size = sizeof(unsigned int),
3584 .value_size = sizeof(struct pprint_mapv),
3585 .key_type_id = 3, /* unsigned int */
3586 .value_type_id = 16, /* struct pprint_mapv */
3587 .max_entries = 128 * 1024,
3588},
3589
3590{
3591 /* this type will have the same type as the
3592 * first .raw_types definition, but struct type will
3593 * be encoded with kind_flag set.
3594 */
3595 .raw_types = {
3596 /* unsighed char */ /* [1] */
3597 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3598 /* unsigned short */ /* [2] */
3599 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3600 /* unsigned int */ /* [3] */
3601 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3602 /* int */ /* [4] */
3603 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3604 /* unsigned long long */ /* [5] */
3605 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3606 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
3607 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
3608 /* uint8_t[8] */ /* [8] */
3609 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3610 /* typedef unsigned char uint8_t */ /* [9] */
3611 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3612 /* typedef unsigned short uint16_t */ /* [10] */
3613 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3614 /* typedef unsigned int uint32_t */ /* [11] */
3615 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3616 /* typedef int int32_t */ /* [12] */
3617 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3618 /* typedef unsigned long long uint64_t *//* [13] */
3619 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3620 /* union (anon) */ /* [14] */
3621 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3622 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3623 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3624 /* enum (anon) */ /* [15] */
3625 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3626 BTF_ENUM_ENC(NAME_TBD, 0),
3627 BTF_ENUM_ENC(NAME_TBD, 1),
3628 BTF_ENUM_ENC(NAME_TBD, 2),
3629 BTF_ENUM_ENC(NAME_TBD, 3),
3630 /* struct pprint_mapv */ /* [16] */
3631 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 8), 32),
3632 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
3633 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3634 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3635 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3636 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3637 BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
3638 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
3639 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
3640 BTF_END_RAW,
3641 },
3642 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
3643 .key_size = sizeof(unsigned int),
3644 .value_size = sizeof(struct pprint_mapv),
3645 .key_type_id = 3, /* unsigned int */
3646 .value_type_id = 16, /* struct pprint_mapv */
3647 .max_entries = 128 * 1024,
3648},
3649
3650{
3651 /* this type will have the same layout as the
3652 * first .raw_types definition. The struct type will
3653 * be encoded with kind_flag set, bitfield members
3654 * are added typedef/const/volatile, and bitfield members
3655 * will have both int and enum types.
3656 */
3657 .raw_types = {
3658 /* unsighed char */ /* [1] */
3659 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3660 /* unsigned short */ /* [2] */
3661 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3662 /* unsigned int */ /* [3] */
3663 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3664 /* int */ /* [4] */
3665 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3666 /* unsigned long long */ /* [5] */
3667 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3668 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
3669 BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
3670 /* uint8_t[8] */ /* [8] */
3671 BTF_TYPE_ARRAY_ENC(9, 1, 8),
3672 /* typedef unsigned char uint8_t */ /* [9] */
3673 BTF_TYPEDEF_ENC(NAME_TBD, 1),
3674 /* typedef unsigned short uint16_t */ /* [10] */
3675 BTF_TYPEDEF_ENC(NAME_TBD, 2),
3676 /* typedef unsigned int uint32_t */ /* [11] */
3677 BTF_TYPEDEF_ENC(NAME_TBD, 3),
3678 /* typedef int int32_t */ /* [12] */
3679 BTF_TYPEDEF_ENC(NAME_TBD, 4),
3680 /* typedef unsigned long long uint64_t *//* [13] */
3681 BTF_TYPEDEF_ENC(NAME_TBD, 5),
3682 /* union (anon) */ /* [14] */
3683 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3684 BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3685 BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3686 /* enum (anon) */ /* [15] */
3687 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3688 BTF_ENUM_ENC(NAME_TBD, 0),
3689 BTF_ENUM_ENC(NAME_TBD, 1),
3690 BTF_ENUM_ENC(NAME_TBD, 2),
3691 BTF_ENUM_ENC(NAME_TBD, 3),
3692 /* struct pprint_mapv */ /* [16] */
3693 BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 8), 32),
3694 BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
3695 BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3696 BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3697 BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3698 BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3699 BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
3700 BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
3701 BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
3702 /* typedef unsigned int ___int */ /* [17] */
3703 BTF_TYPEDEF_ENC(NAME_TBD, 18),
3704 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6), /* [18] */
3705 BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15), /* [19] */
3706 BTF_END_RAW,
3707 },
3708 BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0___int"),
3091 .key_size = sizeof(unsigned int), 3709 .key_size = sizeof(unsigned int),
3092 .value_size = sizeof(struct pprint_mapv), 3710 .value_size = sizeof(struct pprint_mapv),
3093 .key_type_id = 3, /* unsigned int */ 3711 .key_type_id = 3, /* unsigned int */
3094 .value_type_id = 16, /* struct pprint_mapv */ 3712 .value_type_id = 16, /* struct pprint_mapv */
3095 .max_entries = 128 * 1024, 3713 .max_entries = 128 * 1024,
3714},
3715
3096}; 3716};
3097 3717
3098static struct btf_pprint_test_meta { 3718static struct btf_pprint_test_meta {
@@ -3195,9 +3815,9 @@ static int check_line(const char *expected_line, int nexpected_line,
3195} 3815}
3196 3816
3197 3817
3198static int do_test_pprint(void) 3818static int do_test_pprint(int test_num)
3199{ 3819{
3200 const struct btf_raw_test *test = &pprint_test_template; 3820 const struct btf_raw_test *test = &pprint_test_template[test_num];
3201 struct bpf_create_map_attr create_attr = {}; 3821 struct bpf_create_map_attr create_attr = {};
3202 bool ordered_map, lossless_map, percpu_map; 3822 bool ordered_map, lossless_map, percpu_map;
3203 int err, ret, num_cpus, rounded_value_size; 3823 int err, ret, num_cpus, rounded_value_size;
@@ -3213,7 +3833,7 @@ static int do_test_pprint(void)
3213 uint8_t *raw_btf; 3833 uint8_t *raw_btf;
3214 ssize_t nread; 3834 ssize_t nread;
3215 3835
3216 fprintf(stderr, "%s......", test->descr); 3836 fprintf(stderr, "%s(#%d)......", test->descr, test_num);
3217 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types, 3837 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
3218 test->str_sec, test->str_sec_size, 3838 test->str_sec, test->str_sec_size,
3219 &raw_btf_size, NULL); 3839 &raw_btf_size, NULL);
@@ -3406,15 +4026,27 @@ static int test_pprint(void)
3406 unsigned int i; 4026 unsigned int i;
3407 int err = 0; 4027 int err = 0;
3408 4028
4029 /* test various maps with the first test template */
3409 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) { 4030 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
3410 pprint_test_template.descr = pprint_tests_meta[i].descr; 4031 pprint_test_template[0].descr = pprint_tests_meta[i].descr;
3411 pprint_test_template.map_type = pprint_tests_meta[i].map_type; 4032 pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
3412 pprint_test_template.map_name = pprint_tests_meta[i].map_name; 4033 pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
3413 pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map; 4034 pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
3414 pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map; 4035 pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
3415 pprint_test_template.percpu_map = pprint_tests_meta[i].percpu_map; 4036 pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
3416 4037
3417 err |= count_result(do_test_pprint()); 4038 err |= count_result(do_test_pprint(0));
4039 }
4040
4041 /* test rest test templates with the first map */
4042 for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4043 pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4044 pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4045 pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4046 pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4047 pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4048 pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4049 err |= count_result(do_test_pprint(i));
3418 } 4050 }
3419 4051
3420 return err; 4052 return err;
@@ -3622,6 +4254,33 @@ static struct prog_info_raw_test {
3622}, 4254},
3623 4255
3624{ 4256{
4257 .descr = "line_info (Zero bpf insn code)",
4258 .raw_types = {
4259 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4260 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), /* [2] */
4261 BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [3] */
4262 BTF_END_RAW,
4263 },
4264 BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
4265 .insns = {
4266 BPF_LD_IMM64(BPF_REG_0, 1),
4267 BPF_EXIT_INSN(),
4268 },
4269 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4270 .func_info_cnt = 0,
4271 .line_info = {
4272 BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4273 BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
4274 BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4275 BTF_END_RAW,
4276 },
4277 .line_info_rec_size = sizeof(struct bpf_line_info),
4278 .nr_jited_ksyms = 1,
4279 .err_str = "Invalid insn code at line_info[1]",
4280 .expected_prog_load_failure = true,
4281},
4282
4283{
3625 .descr = "line_info (No subprog. zero tailing line_info", 4284 .descr = "line_info (No subprog. zero tailing line_info",
3626 .raw_types = { 4285 .raw_types = {
3627 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 4286 BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
@@ -3912,7 +4571,7 @@ static int test_get_finfo(const struct prog_info_raw_test *test,
3912 } 4571 }
3913 4572
3914 rec_size = info.func_info_rec_size; 4573 rec_size = info.func_info_rec_size;
3915 if (CHECK(rec_size < 8, 4574 if (CHECK(rec_size != sizeof(struct bpf_func_info),
3916 "incorrect info.func_info_rec_size (1st) %d", rec_size)) { 4575 "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
3917 return -1; 4576 return -1;
3918 } 4577 }
@@ -3941,19 +4600,13 @@ static int test_get_finfo(const struct prog_info_raw_test *test,
3941 err = -1; 4600 err = -1;
3942 goto done; 4601 goto done;
3943 } 4602 }
3944 if (CHECK(info.func_info_rec_size < 8, 4603 if (CHECK(info.func_info_rec_size != rec_size,
3945 "incorrect info.func_info_rec_size (2nd) %d", 4604 "incorrect info.func_info_rec_size (2nd) %d",
3946 info.func_info_rec_size)) { 4605 info.func_info_rec_size)) {
3947 err = -1; 4606 err = -1;
3948 goto done; 4607 goto done;
3949 } 4608 }
3950 4609
3951 if (CHECK(!info.func_info,
3952 "info.func_info == 0. kernel.kptr_restrict is set?")) {
3953 err = -1;
3954 goto done;
3955 }
3956
3957 finfo = func_info; 4610 finfo = func_info;
3958 for (i = 0; i < test->func_info_cnt; i++) { 4611 for (i = 0; i < test->func_info_cnt; i++) {
3959 if (CHECK(finfo->type_id != test->func_info[i][1], 4612 if (CHECK(finfo->type_id != test->func_info[i][1],
@@ -4023,8 +4676,8 @@ static int test_get_linfo(const struct prog_info_raw_test *test,
4023 goto done; 4676 goto done;
4024 } 4677 }
4025 4678
4026 if (CHECK(info.line_info_rec_size < 16 || 4679 if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
4027 info.jited_line_info_rec_size < 8, 4680 info.jited_line_info_rec_size != sizeof(__u64),
4028 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)", 4681 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
4029 info.line_info_rec_size, rec_size, 4682 info.line_info_rec_size, rec_size,
4030 info.jited_line_info_rec_size, jited_rec_size)) { 4683 info.jited_line_info_rec_size, jited_rec_size)) {
@@ -4077,7 +4730,6 @@ static int test_get_linfo(const struct prog_info_raw_test *test,
4077 * Other fields are not the concern of this test. 4730 * Other fields are not the concern of this test.
4078 */ 4731 */
4079 if (CHECK(err == -1 || 4732 if (CHECK(err == -1 ||
4080 !info.line_info ||
4081 info.nr_line_info != cnt || 4733 info.nr_line_info != cnt ||
4082 (jited_cnt && !info.jited_line_info) || 4734 (jited_cnt && !info.jited_line_info) ||
4083 info.nr_jited_line_info != jited_cnt || 4735 info.nr_jited_line_info != jited_cnt ||
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index 26f1fdf3e2bf..126fc624290d 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c
@@ -51,10 +51,10 @@ static struct {
51 struct iphdr iph; 51 struct iphdr iph;
52 struct tcphdr tcp; 52 struct tcphdr tcp;
53} __packed pkt_v4 = { 53} __packed pkt_v4 = {
54 .eth.h_proto = bpf_htons(ETH_P_IP), 54 .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
55 .iph.ihl = 5, 55 .iph.ihl = 5,
56 .iph.protocol = 6, 56 .iph.protocol = 6,
57 .iph.tot_len = bpf_htons(MAGIC_BYTES), 57 .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
58 .tcp.urg_ptr = 123, 58 .tcp.urg_ptr = 123,
59}; 59};
60 60
@@ -64,9 +64,9 @@ static struct {
64 struct ipv6hdr iph; 64 struct ipv6hdr iph;
65 struct tcphdr tcp; 65 struct tcphdr tcp;
66} __packed pkt_v6 = { 66} __packed pkt_v6 = {
67 .eth.h_proto = bpf_htons(ETH_P_IPV6), 67 .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
68 .iph.nexthdr = 6, 68 .iph.nexthdr = 6,
69 .iph.payload_len = bpf_htons(MAGIC_BYTES), 69 .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
70 .tcp.urg_ptr = 123, 70 .tcp.urg_ptr = 123,
71}; 71};
72 72
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index c3b799c1ee97..baafe5c76aca 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -49,6 +49,7 @@
49#define MAX_INSNS BPF_MAXINSNS 49#define MAX_INSNS BPF_MAXINSNS
50#define MAX_FIXUPS 8 50#define MAX_FIXUPS 8
51#define MAX_NR_MAPS 13 51#define MAX_NR_MAPS 13
52#define MAX_TEST_RUNS 8
52#define POINTER_VALUE 0xcafe4all 53#define POINTER_VALUE 0xcafe4all
53#define TEST_DATA_LEN 64 54#define TEST_DATA_LEN 64
54 55
@@ -76,7 +77,7 @@ struct bpf_test {
76 int fixup_percpu_cgroup_storage[MAX_FIXUPS]; 77 int fixup_percpu_cgroup_storage[MAX_FIXUPS];
77 const char *errstr; 78 const char *errstr;
78 const char *errstr_unpriv; 79 const char *errstr_unpriv;
79 uint32_t retval, retval_unpriv; 80 uint32_t retval, retval_unpriv, insn_processed;
80 enum { 81 enum {
81 UNDEF, 82 UNDEF,
82 ACCEPT, 83 ACCEPT,
@@ -86,6 +87,14 @@ struct bpf_test {
86 uint8_t flags; 87 uint8_t flags;
87 __u8 data[TEST_DATA_LEN]; 88 __u8 data[TEST_DATA_LEN];
88 void (*fill_helper)(struct bpf_test *self); 89 void (*fill_helper)(struct bpf_test *self);
90 uint8_t runs;
91 struct {
92 uint32_t retval, retval_unpriv;
93 union {
94 __u8 data[TEST_DATA_LEN];
95 __u64 data64[TEST_DATA_LEN / 8];
96 };
97 } retvals[MAX_TEST_RUNS];
89}; 98};
90 99
91/* Note we want this to be 64 bit aligned so that the end of our array is 100/* Note we want this to be 64 bit aligned so that the end of our array is
@@ -1001,15 +1010,45 @@ static struct bpf_test tests[] = {
1001 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8), 1010 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
1002 /* mess up with R1 pointer on stack */ 1011 /* mess up with R1 pointer on stack */
1003 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23), 1012 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
1004 /* fill back into R0 should fail */ 1013 /* fill back into R0 is fine for priv.
1014 * R0 now becomes SCALAR_VALUE.
1015 */
1005 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8), 1016 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1017 /* Load from R0 should fail. */
1018 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
1006 BPF_EXIT_INSN(), 1019 BPF_EXIT_INSN(),
1007 }, 1020 },
1008 .errstr_unpriv = "attempt to corrupt spilled", 1021 .errstr_unpriv = "attempt to corrupt spilled",
1009 .errstr = "corrupted spill", 1022 .errstr = "R0 invalid mem access 'inv",
1010 .result = REJECT, 1023 .result = REJECT,
1011 }, 1024 },
1012 { 1025 {
1026 "check corrupted spill/fill, LSB",
1027 .insns = {
1028 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
1029 BPF_ST_MEM(BPF_H, BPF_REG_10, -8, 0xcafe),
1030 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1031 BPF_EXIT_INSN(),
1032 },
1033 .errstr_unpriv = "attempt to corrupt spilled",
1034 .result_unpriv = REJECT,
1035 .result = ACCEPT,
1036 .retval = POINTER_VALUE,
1037 },
1038 {
1039 "check corrupted spill/fill, MSB",
1040 .insns = {
1041 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
1042 BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0x12345678),
1043 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1044 BPF_EXIT_INSN(),
1045 },
1046 .errstr_unpriv = "attempt to corrupt spilled",
1047 .result_unpriv = REJECT,
1048 .result = ACCEPT,
1049 .retval = POINTER_VALUE,
1050 },
1051 {
1013 "invalid src register in STX", 1052 "invalid src register in STX",
1014 .insns = { 1053 .insns = {
1015 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1), 1054 BPF_STX_MEM(BPF_B, BPF_REG_10, -1, -1),
@@ -1813,10 +1852,20 @@ static struct bpf_test tests[] = {
1813 .prog_type = BPF_PROG_TYPE_SK_SKB, 1852 .prog_type = BPF_PROG_TYPE_SK_SKB,
1814 }, 1853 },
1815 { 1854 {
1816 "invalid 64B read of family in SK_MSG", 1855 "valid access size in SK_MSG",
1856 .insns = {
1857 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1858 offsetof(struct sk_msg_md, size)),
1859 BPF_EXIT_INSN(),
1860 },
1861 .result = ACCEPT,
1862 .prog_type = BPF_PROG_TYPE_SK_MSG,
1863 },
1864 {
1865 "invalid 64B read of size in SK_MSG",
1817 .insns = { 1866 .insns = {
1818 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 1867 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1819 offsetof(struct sk_msg_md, family)), 1868 offsetof(struct sk_msg_md, size)),
1820 BPF_EXIT_INSN(), 1869 BPF_EXIT_INSN(),
1821 }, 1870 },
1822 .errstr = "invalid bpf_context access", 1871 .errstr = "invalid bpf_context access",
@@ -1827,10 +1876,10 @@ static struct bpf_test tests[] = {
1827 "invalid read past end of SK_MSG", 1876 "invalid read past end of SK_MSG",
1828 .insns = { 1877 .insns = {
1829 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 1878 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1830 offsetof(struct sk_msg_md, local_port) + 4), 1879 offsetof(struct sk_msg_md, size) + 4),
1831 BPF_EXIT_INSN(), 1880 BPF_EXIT_INSN(),
1832 }, 1881 },
1833 .errstr = "R0 !read_ok", 1882 .errstr = "invalid bpf_context access",
1834 .result = REJECT, 1883 .result = REJECT,
1835 .prog_type = BPF_PROG_TYPE_SK_MSG, 1884 .prog_type = BPF_PROG_TYPE_SK_MSG,
1836 }, 1885 },
@@ -13648,6 +13697,28 @@ static struct bpf_test tests[] = {
13648 .result = ACCEPT, 13697 .result = ACCEPT,
13649 }, 13698 },
13650 { 13699 {
13700 "allocated_stack",
13701 .insns = {
13702 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
13703 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
13704 BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
13705 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
13706 BPF_MOV64_IMM(BPF_REG_0, 0),
13707 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
13708 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, -8),
13709 BPF_STX_MEM(BPF_B, BPF_REG_10, BPF_REG_7, -9),
13710 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_10, -9),
13711 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13712 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13713 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13714 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13715 BPF_EXIT_INSN(),
13716 },
13717 .result = ACCEPT,
13718 .result_unpriv = ACCEPT,
13719 .insn_processed = 15,
13720 },
13721 {
13651 "reference tracking in call: free reference in subprog and outside", 13722 "reference tracking in call: free reference in subprog and outside",
13652 .insns = { 13723 .insns = {
13653 BPF_SK_LOOKUP, 13724 BPF_SK_LOOKUP,
@@ -14099,6 +14170,7 @@ static struct bpf_test tests[] = {
14099 .errstr_unpriv = "R1 leaks addr", 14170 .errstr_unpriv = "R1 leaks addr",
14100 .result = REJECT, 14171 .result = REJECT,
14101 }, 14172 },
14173 {
14102 "calls: cross frame pruning", 14174 "calls: cross frame pruning",
14103 .insns = { 14175 .insns = {
14104 /* r8 = !!random(); 14176 /* r8 = !!random();
@@ -14122,10 +14194,199 @@ static struct bpf_test tests[] = {
14122 }, 14194 },
14123 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, 14195 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14124 .errstr_unpriv = "function calls to other bpf functions are allowed for root only", 14196 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
14197 .result = REJECT,
14198 },
14199 {
14200 "jset: functional",
14201 .insns = {
14202 /* r0 = 0 */
14203 BPF_MOV64_IMM(BPF_REG_0, 0),
14204 /* prep for direct packet access via r2 */
14205 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
14206 offsetof(struct __sk_buff, data)),
14207 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
14208 offsetof(struct __sk_buff, data_end)),
14209 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
14210 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
14211 BPF_JMP_REG(BPF_JLE, BPF_REG_4, BPF_REG_3, 1),
14212 BPF_EXIT_INSN(),
14213
14214 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_2, 0),
14215
14216 /* reg, bit 63 or bit 0 set, taken */
14217 BPF_LD_IMM64(BPF_REG_8, 0x8000000000000001),
14218 BPF_JMP_REG(BPF_JSET, BPF_REG_7, BPF_REG_8, 1),
14219 BPF_EXIT_INSN(),
14220
14221 /* reg, bit 62, not taken */
14222 BPF_LD_IMM64(BPF_REG_8, 0x4000000000000000),
14223 BPF_JMP_REG(BPF_JSET, BPF_REG_7, BPF_REG_8, 1),
14224 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
14225 BPF_EXIT_INSN(),
14226
14227 /* imm, any bit set, taken */
14228 BPF_JMP_IMM(BPF_JSET, BPF_REG_7, -1, 1),
14229 BPF_EXIT_INSN(),
14230
14231 /* imm, bit 31 set, taken */
14232 BPF_JMP_IMM(BPF_JSET, BPF_REG_7, 0x80000000, 1),
14233 BPF_EXIT_INSN(),
14234
14235 /* all good - return r0 == 2 */
14236 BPF_MOV64_IMM(BPF_REG_0, 2),
14237 BPF_EXIT_INSN(),
14238 },
14239 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
14240 .result = ACCEPT,
14241 .runs = 7,
14242 .retvals = {
14243 { .retval = 2,
14244 .data64 = { (1ULL << 63) | (1U << 31) | (1U << 0), }
14245 },
14246 { .retval = 2,
14247 .data64 = { (1ULL << 63) | (1U << 31), }
14248 },
14249 { .retval = 2,
14250 .data64 = { (1ULL << 31) | (1U << 0), }
14251 },
14252 { .retval = 2,
14253 .data64 = { (__u32)-1, }
14254 },
14255 { .retval = 2,
14256 .data64 = { ~0x4000000000000000ULL, }
14257 },
14258 { .retval = 0,
14259 .data64 = { 0, }
14260 },
14261 { .retval = 0,
14262 .data64 = { ~0ULL, }
14263 },
14264 },
14265 },
14266 {
14267 "jset: sign-extend",
14268 .insns = {
14269 /* r0 = 0 */
14270 BPF_MOV64_IMM(BPF_REG_0, 0),
14271 /* prep for direct packet access via r2 */
14272 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
14273 offsetof(struct __sk_buff, data)),
14274 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
14275 offsetof(struct __sk_buff, data_end)),
14276 BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
14277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
14278 BPF_JMP_REG(BPF_JLE, BPF_REG_4, BPF_REG_3, 1),
14279 BPF_EXIT_INSN(),
14280
14281 BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_2, 0),
14282
14283 BPF_JMP_IMM(BPF_JSET, BPF_REG_7, 0x80000000, 1),
14284 BPF_EXIT_INSN(),
14285
14286 BPF_MOV64_IMM(BPF_REG_0, 2),
14287 BPF_EXIT_INSN(),
14288 },
14289 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
14290 .result = ACCEPT,
14291 .retval = 2,
14292 .data = { 1, 0, 0, 0, 0, 0, 0, 1, },
14293 },
14294 {
14295 "jset: known const compare",
14296 .insns = {
14297 BPF_MOV64_IMM(BPF_REG_0, 1),
14298 BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14299 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14300 BPF_EXIT_INSN(),
14301 },
14302 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14303 .retval_unpriv = 1,
14304 .result_unpriv = ACCEPT,
14305 .retval = 1,
14306 .result = ACCEPT,
14307 },
14308 {
14309 "jset: known const compare bad",
14310 .insns = {
14311 BPF_MOV64_IMM(BPF_REG_0, 0),
14312 BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14313 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14314 BPF_EXIT_INSN(),
14315 },
14316 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14317 .errstr_unpriv = "!read_ok",
14125 .result_unpriv = REJECT, 14318 .result_unpriv = REJECT,
14126 .errstr = "!read_ok", 14319 .errstr = "!read_ok",
14127 .result = REJECT, 14320 .result = REJECT,
14128 }, 14321 },
14322 {
14323 "jset: unknown const compare taken",
14324 .insns = {
14325 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14326 BPF_FUNC_get_prandom_u32),
14327 BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14328 BPF_JMP_IMM(BPF_JA, 0, 0, 1),
14329 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14330 BPF_EXIT_INSN(),
14331 },
14332 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14333 .errstr_unpriv = "!read_ok",
14334 .result_unpriv = REJECT,
14335 .errstr = "!read_ok",
14336 .result = REJECT,
14337 },
14338 {
14339 "jset: unknown const compare not taken",
14340 .insns = {
14341 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14342 BPF_FUNC_get_prandom_u32),
14343 BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14344 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14345 BPF_EXIT_INSN(),
14346 },
14347 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14348 .errstr_unpriv = "!read_ok",
14349 .result_unpriv = REJECT,
14350 .errstr = "!read_ok",
14351 .result = REJECT,
14352 },
14353 {
14354 "jset: half-known const compare",
14355 .insns = {
14356 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14357 BPF_FUNC_get_prandom_u32),
14358 BPF_ALU64_IMM(BPF_OR, BPF_REG_0, 2),
14359 BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 3, 1),
14360 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14361 BPF_MOV64_IMM(BPF_REG_0, 0),
14362 BPF_EXIT_INSN(),
14363 },
14364 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14365 .result_unpriv = ACCEPT,
14366 .result = ACCEPT,
14367 },
14368 {
14369 "jset: range",
14370 .insns = {
14371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14372 BPF_FUNC_get_prandom_u32),
14373 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
14374 BPF_MOV64_IMM(BPF_REG_0, 0),
14375 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xff),
14376 BPF_JMP_IMM(BPF_JSET, BPF_REG_1, 0xf0, 3),
14377 BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 0x10, 1),
14378 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14379 BPF_EXIT_INSN(),
14380 BPF_JMP_IMM(BPF_JSET, BPF_REG_1, 0x10, 1),
14381 BPF_EXIT_INSN(),
14382 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0x10, 1),
14383 BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14384 BPF_EXIT_INSN(),
14385 },
14386 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14387 .result_unpriv = ACCEPT,
14388 .result = ACCEPT,
14389 },
14129}; 14390};
14130 14391
14131static int probe_filter_length(const struct bpf_insn *fp) 14392static int probe_filter_length(const struct bpf_insn *fp)
@@ -14408,16 +14669,42 @@ out:
14408 return ret; 14669 return ret;
14409} 14670}
14410 14671
14672static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
14673 void *data, size_t size_data)
14674{
14675 __u8 tmp[TEST_DATA_LEN << 2];
14676 __u32 size_tmp = sizeof(tmp);
14677 uint32_t retval;
14678 int err;
14679
14680 if (unpriv)
14681 set_admin(true);
14682 err = bpf_prog_test_run(fd_prog, 1, data, size_data,
14683 tmp, &size_tmp, &retval, NULL);
14684 if (unpriv)
14685 set_admin(false);
14686 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
14687 printf("Unexpected bpf_prog_test_run error ");
14688 return err;
14689 }
14690 if (!err && retval != expected_val &&
14691 expected_val != POINTER_VALUE) {
14692 printf("FAIL retval %d != %d ", retval, expected_val);
14693 return 1;
14694 }
14695
14696 return 0;
14697}
14698
14411static void do_test_single(struct bpf_test *test, bool unpriv, 14699static void do_test_single(struct bpf_test *test, bool unpriv,
14412 int *passes, int *errors) 14700 int *passes, int *errors)
14413{ 14701{
14414 int fd_prog, expected_ret, alignment_prevented_execution; 14702 int fd_prog, expected_ret, alignment_prevented_execution;
14415 int prog_len, prog_type = test->prog_type; 14703 int prog_len, prog_type = test->prog_type;
14416 struct bpf_insn *prog = test->insns; 14704 struct bpf_insn *prog = test->insns;
14705 int run_errs, run_successes;
14417 int map_fds[MAX_NR_MAPS]; 14706 int map_fds[MAX_NR_MAPS];
14418 const char *expected_err; 14707 const char *expected_err;
14419 uint32_t expected_val;
14420 uint32_t retval;
14421 __u32 pflags; 14708 __u32 pflags;
14422 int i, err; 14709 int i, err;
14423 14710
@@ -14441,8 +14728,6 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
14441 test->result_unpriv : test->result; 14728 test->result_unpriv : test->result;
14442 expected_err = unpriv && test->errstr_unpriv ? 14729 expected_err = unpriv && test->errstr_unpriv ?
14443 test->errstr_unpriv : test->errstr; 14730 test->errstr_unpriv : test->errstr;
14444 expected_val = unpriv && test->retval_unpriv ?
14445 test->retval_unpriv : test->retval;
14446 14731
14447 alignment_prevented_execution = 0; 14732 alignment_prevented_execution = 0;
14448 14733
@@ -14454,10 +14739,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
14454 } 14739 }
14455#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 14740#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
14456 if (fd_prog >= 0 && 14741 if (fd_prog >= 0 &&
14457 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS)) { 14742 (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS))
14458 alignment_prevented_execution = 1; 14743 alignment_prevented_execution = 1;
14459 goto test_ok;
14460 }
14461#endif 14744#endif
14462 } else { 14745 } else {
14463 if (fd_prog >= 0) { 14746 if (fd_prog >= 0) {
@@ -14471,33 +14754,67 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
14471 } 14754 }
14472 } 14755 }
14473 14756
14474 if (fd_prog >= 0) { 14757 if (test->insn_processed) {
14475 __u8 tmp[TEST_DATA_LEN << 2]; 14758 uint32_t insn_processed;
14476 __u32 size_tmp = sizeof(tmp); 14759 char *proc;
14477 14760
14478 if (unpriv) 14761 proc = strstr(bpf_vlog, "processed ");
14479 set_admin(true); 14762 insn_processed = atoi(proc + 10);
14480 err = bpf_prog_test_run(fd_prog, 1, test->data, 14763 if (test->insn_processed != insn_processed) {
14481 sizeof(test->data), tmp, &size_tmp, 14764 printf("FAIL\nUnexpected insn_processed %u vs %u\n",
14482 &retval, NULL); 14765 insn_processed, test->insn_processed);
14483 if (unpriv)
14484 set_admin(false);
14485 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
14486 printf("Unexpected bpf_prog_test_run error\n");
14487 goto fail_log; 14766 goto fail_log;
14488 } 14767 }
14489 if (!err && retval != expected_val && 14768 }
14490 expected_val != POINTER_VALUE) { 14769
14491 printf("FAIL retval %d != %d\n", retval, expected_val); 14770 run_errs = 0;
14492 goto fail_log; 14771 run_successes = 0;
14772 if (!alignment_prevented_execution && fd_prog >= 0) {
14773 uint32_t expected_val;
14774 int i;
14775
14776 if (!test->runs) {
14777 expected_val = unpriv && test->retval_unpriv ?
14778 test->retval_unpriv : test->retval;
14779
14780 err = do_prog_test_run(fd_prog, unpriv, expected_val,
14781 test->data, sizeof(test->data));
14782 if (err)
14783 run_errs++;
14784 else
14785 run_successes++;
14786 }
14787
14788 for (i = 0; i < test->runs; i++) {
14789 if (unpriv && test->retvals[i].retval_unpriv)
14790 expected_val = test->retvals[i].retval_unpriv;
14791 else
14792 expected_val = test->retvals[i].retval;
14793
14794 err = do_prog_test_run(fd_prog, unpriv, expected_val,
14795 test->retvals[i].data,
14796 sizeof(test->retvals[i].data));
14797 if (err) {
14798 printf("(run %d/%d) ", i + 1, test->runs);
14799 run_errs++;
14800 } else {
14801 run_successes++;
14802 }
14493 } 14803 }
14494 } 14804 }
14495#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 14805
14496test_ok: 14806 if (!run_errs) {
14497#endif 14807 (*passes)++;
14498 (*passes)++; 14808 if (run_successes > 1)
14499 printf("OK%s\n", alignment_prevented_execution ? 14809 printf("%d cases ", run_successes);
14500 " (NOTE: not executed due to unknown alignment)" : ""); 14810 printf("OK");
14811 if (alignment_prevented_execution)
14812 printf(" (NOTE: not executed due to unknown alignment)");
14813 printf("\n");
14814 } else {
14815 printf("\n");
14816 goto fail_log;
14817 }
14501close_fds: 14818close_fds:
14502 close(fd_prog); 14819 close(fd_prog);
14503 for (i = 0; i < MAX_NR_MAPS; i++) 14820 for (i = 0; i < MAX_NR_MAPS; i++)