Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Daniel Borkmann says:

====================
pull-request: bpf-next 2024-02-29

We've added 119 non-merge commits during the last 32 day(s) which contain
a total of 150 files changed, 3589 insertions(+), 995 deletions(-).

The main changes are:

1) Extend the BPF verifier to enable static subprog calls in spin lock
critical sections, from Kumar Kartikeya Dwivedi.

2) Fix confusing and incorrect inference of PTR_TO_CTX argument type
in BPF global subprogs, from Andrii Nakryiko.

3) Larger batch of riscv BPF JIT improvements and enabling inlining
of the bpf_kptr_xchg() for RV64, from Pu Lehui.

4) Allow skeleton users to change the values of the fields in struct_ops
maps at runtime, from Kui-Feng Lee.

5) Extend the verifier's capabilities of tracking scalars when they
are spilled to stack, especially when the spill or fill is narrowing,
from Maxim Mikityanskiy & Eduard Zingerman.

6) Various BPF selftest improvements to fix errors under gcc BPF backend,
from Jose E. Marchesi.

7) Avoid module loading failure when the module trying to register
a struct_ops has its BTF section stripped, from Geliang Tang.

8) Annotate all kfuncs in .BTF_ids section which eventually allows
for automatic kfunc prototype generation from bpftool, from Daniel Xu.

9) Several updates to the instruction-set.rst IETF standardization
document, from Dave Thaler.

10) Shrink the size of struct bpf_map resp. bpf_array,
from Alexei Starovoitov.

11) Initial small subset of BPF verifier prepwork for sleepable bpf_timer,
from Benjamin Tissoires.

12) Fix bpftool to be more portable to musl libc by using POSIX's
basename(), from Arnaldo Carvalho de Melo.

13) Add libbpf support to gcc in CORE macro definitions,
from Cupertino Miranda.

14) Remove a duplicate type check in perf_event_bpf_event,
from Florian Lehner.

15) Fix bpf_spin_{un,}lock BPF helpers to actually annotate them
with notrace correctly, from Yonghong Song.

16) Replace the deprecated bpf_lpm_trie_key 0-length array with flexible
array to fix build warnings, from Kees Cook.

17) Fix resolve_btfids cross-compilation to non host-native endianness,
from Viktor Malik.

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (119 commits)
selftests/bpf: Test if shadow types work correctly.
bpftool: Add an example for struct_ops map and shadow type.
bpftool: Generated shadow variables for struct_ops maps.
libbpf: Convert st_ops->data to shadow type.
libbpf: Set btf_value_type_id of struct bpf_map for struct_ops.
bpf: Replace bpf_lpm_trie_key 0-length array with flexible array
bpf, arm64: use bpf_prog_pack for memory management
arm64: patching: implement text_poke API
bpf, arm64: support exceptions
arm64: stacktrace: Implement arch_bpf_stack_walk() for the BPF JIT
bpf: add is_async_callback_calling_insn() helper
bpf: introduce in_sleepable() helper
bpf: allow more maps in sleepable bpf programs
selftests/bpf: Test case for lacking CFI stub functions.
bpf: Check cfi_stubs before registering a struct_ops type.
bpf: Clarify batch lookup/lookup_and_delete semantics
bpf, docs: specify which BPF_ABS and BPF_IND fields were zero
bpf, docs: Fix typos in instruction-set.rst
selftests/bpf: update tcp_custom_syncookie to use scalar packet offset
bpf: Shrink size of struct bpf_map/bpf_array.
...
====================

Link: https://lore.kernel.org/r/20240301001625.8800-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+3585 -991
+4 -4
Documentation/bpf/kfuncs.rst
··· 177 177 type of kfunc(s) being registered with the BPF subsystem. To do so, we define 178 178 flags on a set of kfuncs as follows:: 179 179 180 - BTF_SET8_START(bpf_task_set) 180 + BTF_KFUNCS_START(bpf_task_set) 181 181 BTF_ID_FLAGS(func, bpf_get_task_pid, KF_ACQUIRE | KF_RET_NULL) 182 182 BTF_ID_FLAGS(func, bpf_put_pid, KF_RELEASE) 183 - BTF_SET8_END(bpf_task_set) 183 + BTF_KFUNCS_END(bpf_task_set) 184 184 185 185 This set encodes the BTF ID of each kfunc listed above, and encodes the flags 186 186 along with it. Ofcourse, it is also allowed to specify no flags. ··· 347 347 registering it with the BPF subsystem. Registration is done per BPF program 348 348 type. An example is shown below:: 349 349 350 - BTF_SET8_START(bpf_task_set) 350 + BTF_KFUNCS_START(bpf_task_set) 351 351 BTF_ID_FLAGS(func, bpf_get_task_pid, KF_ACQUIRE | KF_RET_NULL) 352 352 BTF_ID_FLAGS(func, bpf_put_pid, KF_RELEASE) 353 - BTF_SET8_END(bpf_task_set) 353 + BTF_KFUNCS_END(bpf_task_set) 354 354 355 355 static const struct btf_kfunc_id_set bpf_task_kfunc_set = { 356 356 .owner = THIS_MODULE,
+1 -1
Documentation/bpf/map_lpm_trie.rst
··· 17 17 18 18 LPM tries may be created with a maximum prefix length that is a multiple 19 19 of 8, in the range from 8 to 2048. The key used for lookup and update 20 - operations is a ``struct bpf_lpm_trie_key``, extended by 20 + operations is a ``struct bpf_lpm_trie_key_u8``, extended by 21 21 ``max_prefixlen/8`` bytes. 22 22 23 23 - For IPv4 addresses the data length is 4 bytes
+89 -66
Documentation/bpf/standardization/instruction-set.rst
··· 1 1 .. contents:: 2 2 .. sectnum:: 3 3 4 - ======================================= 5 - BPF Instruction Set Specification, v1.0 6 - ======================================= 4 + ====================================== 5 + BPF Instruction Set Architecture (ISA) 6 + ====================================== 7 7 8 - This document specifies version 1.0 of the BPF instruction set. 8 + This document specifies the BPF instruction set architecture (ISA). 9 9 10 10 Documentation conventions 11 11 ========================= ··· 102 102 103 103 An implementation does not need to support all instructions specified in this 104 104 document (e.g., deprecated instructions). Instead, a number of conformance 105 - groups are specified. An implementation must support the "basic" conformance 105 + groups are specified. An implementation must support the base32 conformance 106 106 group and may support additional conformance groups, where supporting a 107 107 conformance group means it must support all instructions in that conformance 108 108 group. ··· 112 112 instructions for the runtime. Thus, capability discovery in terms of 113 113 conformance groups might be done manually by users or automatically by tools. 114 114 115 - Each conformance group has a short ASCII label (e.g., "basic") that 115 + Each conformance group has a short ASCII label (e.g., "base32") that 116 116 corresponds to a set of instructions that are mandatory. That is, each 117 117 instruction has one or more conformance groups of which it is a member. 118 118 119 - The "basic" conformance group includes all instructions defined in this 120 - specification unless otherwise noted. 119 + This document defines the following conformance groups: 120 + 121 + * base32: includes all instructions defined in this 122 + specification unless otherwise noted. 123 + * base64: includes base32, plus instructions explicitly noted 124 + as being in the base64 conformance group. 125 + * atomic32: includes 32-bit atomic operation instructions (see `Atomic operations`_). 126 + * atomic64: includes atomic32, plus 64-bit atomic operation instructions. 127 + * divmul32: includes 32-bit division, multiplication, and modulo instructions. 128 + * divmul64: includes divmul32, plus 64-bit division, multiplication, 129 + and modulo instructions. 130 + * legacy: deprecated packet access instructions. 121 131 122 132 Instruction encoding 123 133 ==================== ··· 176 166 Unused fields shall be cleared to zero. 177 167 178 168 As discussed below in `64-bit immediate instructions`_, a 64-bit immediate 179 - instruction uses a 64-bit immediate value that is constructed as follows. 169 + instruction uses two 32-bit immediate values that are constructed as follows. 180 170 The 64 bits following the basic instruction contain a pseudo instruction 181 - using the same format but with opcode, dst_reg, src_reg, and offset all set to zero, 182 - and imm containing the high 32 bits of the immediate value. 171 + using the same format but with 'opcode', 'dst_reg', 'src_reg', and 'offset' all 172 + set to zero, and imm containing the high 32 bits of the immediate value. 183 173 184 174 This is depicted in the following figure:: 185 175 ··· 191 181 '--------------' 192 182 pseudo instruction 193 183 194 - Thus the 64-bit immediate value is constructed as follows: 195 - 196 - imm64 = (next_imm << 32) | imm 197 - 198 - where 'next_imm' refers to the imm value of the pseudo instruction 199 - following the basic instruction. The unused bytes in the pseudo 200 - instruction are reserved and shall be cleared to zero. 184 + Here, the imm value of the pseudo instruction is called 'next_imm'. The unused 185 + bytes in the pseudo instruction are reserved and shall be cleared to zero. 201 186 202 187 Instruction classes 203 188 ------------------- ··· 244 239 ----------------------- 245 240 246 241 ``BPF_ALU`` uses 32-bit wide operands while ``BPF_ALU64`` uses 64-bit wide operands for 247 - otherwise identical operations. 242 + otherwise identical operations. ``BPF_ALU64`` instructions belong to the 243 + base64 conformance group unless noted otherwise. 248 244 The 'code' field encodes the operation as below, where 'src' and 'dst' refer 249 245 to the values of the source and destination registers, respectively. 250 246 ··· 290 284 291 285 ``BPF_XOR | BPF_K | BPF_ALU`` means:: 292 286 293 - dst = (u32) dst ^ (u32) imm32 287 + dst = (u32) dst ^ (u32) imm 294 288 295 289 ``BPF_XOR | BPF_K | BPF_ALU64`` means:: 296 290 297 - dst = dst ^ imm32 291 + dst = dst ^ imm 298 292 299 293 Note that most instructions have instruction offset of 0. Only three instructions 300 294 (``BPF_SDIV``, ``BPF_SMOD``, ``BPF_MOVSX``) have a non-zero offset. 301 295 296 + Division, multiplication, and modulo operations for ``BPF_ALU`` are part 297 + of the "divmul32" conformance group, and division, multiplication, and 298 + modulo operations for ``BPF_ALU64`` are part of the "divmul64" conformance 299 + group. 302 300 The division and modulo operations support both unsigned and signed flavors. 303 301 304 302 For unsigned operations (``BPF_DIV`` and ``BPF_MOD``), for ``BPF_ALU``, ··· 359 349 ========= ========= ===== ================================================= 360 350 361 351 The 'imm' field encodes the width of the swap operations. The following widths 362 - are supported: 16, 32 and 64. 352 + are supported: 16, 32 and 64. Width 64 operations belong to the base64 353 + conformance group and other swap operations belong to the base32 354 + conformance group. 363 355 364 356 Examples: 365 357 ··· 386 374 Jump instructions 387 375 ----------------- 388 376 389 - ``BPF_JMP32`` uses 32-bit wide operands while ``BPF_JMP`` uses 64-bit wide operands for 390 - otherwise identical operations. 377 + ``BPF_JMP32`` uses 32-bit wide operands and indicates the base32 378 + conformance group, while ``BPF_JMP`` uses 64-bit wide operands for 379 + otherwise identical operations, and indicates the base64 conformance 380 + group unless otherwise specified. 391 381 The 'code' field encodes the operation as below: 392 382 393 - ======== ===== === =============================== ============================================= 394 - code value src description notes 395 - ======== ===== === =============================== ============================================= 396 - BPF_JA 0x0 0x0 PC += offset BPF_JMP | BPF_K only 397 - BPF_JA 0x0 0x0 PC += imm BPF_JMP32 | BPF_K only 398 - BPF_JEQ 0x1 any PC += offset if dst == src 399 - BPF_JGT 0x2 any PC += offset if dst > src unsigned 400 - BPF_JGE 0x3 any PC += offset if dst >= src unsigned 401 - BPF_JSET 0x4 any PC += offset if dst & src 402 - BPF_JNE 0x5 any PC += offset if dst != src 403 - BPF_JSGT 0x6 any PC += offset if dst > src signed 404 - BPF_JSGE 0x7 any PC += offset if dst >= src signed 405 - BPF_CALL 0x8 0x0 call helper function by address BPF_JMP | BPF_K only, see `Helper functions`_ 406 - BPF_CALL 0x8 0x1 call PC += imm BPF_JMP | BPF_K only, see `Program-local functions`_ 407 - BPF_CALL 0x8 0x2 call helper function by BTF ID BPF_JMP | BPF_K only, see `Helper functions`_ 408 - BPF_EXIT 0x9 0x0 return BPF_JMP | BPF_K only 409 - BPF_JLT 0xa any PC += offset if dst < src unsigned 410 - BPF_JLE 0xb any PC += offset if dst <= src unsigned 411 - BPF_JSLT 0xc any PC += offset if dst < src signed 412 - BPF_JSLE 0xd any PC += offset if dst <= src signed 413 - ======== ===== === =============================== ============================================= 383 + ======== ===== ======= =============================== ============================================= 384 + code value src_reg description notes 385 + ======== ===== ======= =============================== ============================================= 386 + BPF_JA 0x0 0x0 PC += offset BPF_JMP | BPF_K only 387 + BPF_JA 0x0 0x0 PC += imm BPF_JMP32 | BPF_K only 388 + BPF_JEQ 0x1 any PC += offset if dst == src 389 + BPF_JGT 0x2 any PC += offset if dst > src unsigned 390 + BPF_JGE 0x3 any PC += offset if dst >= src unsigned 391 + BPF_JSET 0x4 any PC += offset if dst & src 392 + BPF_JNE 0x5 any PC += offset if dst != src 393 + BPF_JSGT 0x6 any PC += offset if dst > src signed 394 + BPF_JSGE 0x7 any PC += offset if dst >= src signed 395 + BPF_CALL 0x8 0x0 call helper function by address BPF_JMP | BPF_K only, see `Helper functions`_ 396 + BPF_CALL 0x8 0x1 call PC += imm BPF_JMP | BPF_K only, see `Program-local functions`_ 397 + BPF_CALL 0x8 0x2 call helper function by BTF ID BPF_JMP | BPF_K only, see `Helper functions`_ 398 + BPF_EXIT 0x9 0x0 return BPF_JMP | BPF_K only 399 + BPF_JLT 0xa any PC += offset if dst < src unsigned 400 + BPF_JLE 0xb any PC += offset if dst <= src unsigned 401 + BPF_JSLT 0xc any PC += offset if dst < src signed 402 + BPF_JSLE 0xd any PC += offset if dst <= src signed 403 + ======== ===== ======= =============================== ============================================= 414 404 415 405 The BPF program needs to store the return value into register R0 before doing a 416 406 ``BPF_EXIT``. ··· 437 423 specified by the 'imm' field. A > 16-bit conditional jump may be 438 424 converted to a < 16-bit conditional jump plus a 32-bit unconditional 439 425 jump. 426 + 427 + All ``BPF_CALL`` and ``BPF_JA`` instructions belong to the 428 + base32 conformance group. 440 429 441 430 Helper functions 442 431 ~~~~~~~~~~~~~~~~ ··· 498 481 BPF_DW 0x18 double word (8 bytes) 499 482 ============= ===== ===================== 500 483 484 + Instructions using ``BPF_DW`` belong to the base64 conformance group. 485 + 501 486 Regular load and store operations 502 487 --------------------------------- 503 488 ··· 512 493 513 494 ``BPF_MEM | <size> | BPF_ST`` means:: 514 495 515 - *(size *) (dst + offset) = imm32 496 + *(size *) (dst + offset) = imm 516 497 517 498 ``BPF_MEM | <size> | BPF_LDX`` means:: 518 499 ··· 544 525 All atomic operations supported by BPF are encoded as store operations 545 526 that use the ``BPF_ATOMIC`` mode modifier as follows: 546 527 547 - * ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations 548 - * ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations 528 + * ``BPF_ATOMIC | BPF_W | BPF_STX`` for 32-bit operations, which are 529 + part of the "atomic32" conformance group. 530 + * ``BPF_ATOMIC | BPF_DW | BPF_STX`` for 64-bit operations, which are 531 + part of the "atomic64" conformance group. 549 532 * 8-bit and 16-bit wide atomic operations are not supported. 550 533 551 534 The 'imm' field is used to encode the actual atomic operation. ··· 568 547 569 548 *(u32 *)(dst + offset) += src 570 549 571 - ``BPF_ATOMIC | BPF_DW | BPF_STX`` with 'imm' = BPF ADD means:: 550 + ``BPF_ATOMIC | BPF_DW | BPF_STX`` with 'imm' = BPF_ADD means:: 572 551 573 552 *(u64 *)(dst + offset) += src 574 553 ··· 601 580 ----------------------------- 602 581 603 582 Instructions with the ``BPF_IMM`` 'mode' modifier use the wide instruction 604 - encoding defined in `Instruction encoding`_, and use the 'src' field of the 583 + encoding defined in `Instruction encoding`_, and use the 'src_reg' field of the 605 584 basic instruction to hold an opcode subtype. 606 585 607 586 The following table defines a set of ``BPF_IMM | BPF_DW | BPF_LD`` instructions 608 - with opcode subtypes in the 'src' field, using new terms such as "map" 587 + with opcode subtypes in the 'src_reg' field, using new terms such as "map" 609 588 defined further below: 610 589 611 - ========================= ====== === ========================================= =========== ============== 612 - opcode construction opcode src pseudocode imm type dst type 613 - ========================= ====== === ========================================= =========== ============== 614 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x0 dst = imm64 integer integer 615 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x1 dst = map_by_fd(imm) map fd map 616 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer 617 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x3 dst = var_addr(imm) variable id data pointer 618 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x4 dst = code_addr(imm) integer code pointer 619 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x5 dst = map_by_idx(imm) map index map 620 - BPF_IMM | BPF_DW | BPF_LD 0x18 0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer 621 - ========================= ====== === ========================================= =========== ============== 590 + ========================= ====== ======= ========================================= =========== ============== 591 + opcode construction opcode src_reg pseudocode imm type dst type 592 + ========================= ====== ======= ========================================= =========== ============== 593 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x0 dst = (next_imm << 32) | imm integer integer 594 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x1 dst = map_by_fd(imm) map fd map 595 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x2 dst = map_val(map_by_fd(imm)) + next_imm map fd data pointer 596 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x3 dst = var_addr(imm) variable id data pointer 597 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x4 dst = code_addr(imm) integer code pointer 598 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x5 dst = map_by_idx(imm) map index map 599 + BPF_IMM | BPF_DW | BPF_LD 0x18 0x6 dst = map_val(map_by_idx(imm)) + next_imm map index data pointer 600 + ========================= ====== ======= ========================================= =========== ============== 622 601 623 602 where 624 603 ··· 656 635 ------------------------------------- 657 636 658 637 BPF previously introduced special instructions for access to packet data that were 659 - carried over from classic BPF. However, these instructions are 660 - deprecated and should no longer be used. All legacy packet access 661 - instructions belong to the "legacy" conformance group instead of the "basic" 662 - conformance group. 638 + carried over from classic BPF. These instructions used an instruction 639 + class of BPF_LD, a size modifier of BPF_W, BPF_H, or BPF_B, and a 640 + mode modifier of BPF_ABS or BPF_IND. The 'dst_reg' and 'offset' fields were 641 + set to zero, and 'src_reg' was set to zero for BPF_ABS. However, these 642 + instructions are deprecated and should no longer be used. All legacy packet 643 + access instructions belong to the "legacy" conformance group.
+18 -13
Documentation/networking/af_xdp.rst
··· 329 329 sxdp_shared_umem_fd field as you registered the UMEM on that 330 330 socket. These two sockets will now share one and the same UMEM. 331 331 332 - There is no need to supply an XDP program like the one in the previous 333 - case where sockets were bound to the same queue id and 334 - device. Instead, use the NIC's packet steering capabilities to steer 335 - the packets to the right queue. In the previous example, there is only 336 - one queue shared among sockets, so the NIC cannot do this steering. It 337 - can only steer between queues. 332 + In this case, it is possible to use the NIC's packet steering 333 + capabilities to steer the packets to the right queue. This is not 334 + possible in the previous example as there is only one queue shared 335 + among sockets, so the NIC cannot do this steering as it can only steer 336 + between queues. 338 337 339 - In libbpf, you need to use the xsk_socket__create_shared() API as it 340 - takes a reference to a FILL ring and a COMPLETION ring that will be 341 - created for you and bound to the shared UMEM. You can use this 342 - function for all the sockets you create, or you can use it for the 343 - second and following ones and use xsk_socket__create() for the first 344 - one. Both methods yield the same result. 338 + In libxdp (or libbpf prior to version 1.0), you need to use the 339 + xsk_socket__create_shared() API as it takes a reference to a FILL ring 340 + and a COMPLETION ring that will be created for you and bound to the 341 + shared UMEM. You can use this function for all the sockets you create, 342 + or you can use it for the second and following ones and use 343 + xsk_socket__create() for the first one. Both methods yield the same 344 + result. 345 345 346 346 Note that a UMEM can be shared between sockets on the same queue id 347 347 and device, as well as between queues on the same device and between 348 - devices at the same time. 348 + devices at the same time. It is also possible to redirect to any 349 + socket as long as it is bound to the same umem with XDP_SHARED_UMEM. 349 350 350 351 XDP_USE_NEED_WAKEUP bind flag 351 352 ----------------------------- ··· 822 821 to the same queue id Y. In zero-copy mode, you should use the 823 822 switch, or other distribution mechanism, in your NIC to direct 824 823 traffic to the correct queue id and socket. 824 + 825 + Note that if you are using the XDP_SHARED_UMEM option, it is 826 + possible to switch traffic between any socket bound to the same 827 + umem. 825 828 826 829 Q: My packets are sometimes corrupted. What is wrong? 827 830
+2
arch/arm64/include/asm/patching.h
··· 8 8 int aarch64_insn_write(void *addr, u32 insn); 9 9 10 10 int aarch64_insn_write_literal_u64(void *addr, u64 val); 11 + void *aarch64_insn_set(void *dst, u32 insn, size_t len); 12 + void *aarch64_insn_copy(void *dst, void *src, size_t len); 11 13 12 14 int aarch64_insn_patch_text_nosync(void *addr, u32 insn); 13 15 int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt);
+75
arch/arm64/kernel/patching.c
··· 105 105 return ret; 106 106 } 107 107 108 + typedef void text_poke_f(void *dst, void *src, size_t patched, size_t len); 109 + 110 + static void *__text_poke(text_poke_f func, void *addr, void *src, size_t len) 111 + { 112 + unsigned long flags; 113 + size_t patched = 0; 114 + size_t size; 115 + void *waddr; 116 + void *ptr; 117 + 118 + raw_spin_lock_irqsave(&patch_lock, flags); 119 + 120 + while (patched < len) { 121 + ptr = addr + patched; 122 + size = min_t(size_t, PAGE_SIZE - offset_in_page(ptr), 123 + len - patched); 124 + 125 + waddr = patch_map(ptr, FIX_TEXT_POKE0); 126 + func(waddr, src, patched, size); 127 + patch_unmap(FIX_TEXT_POKE0); 128 + 129 + patched += size; 130 + } 131 + raw_spin_unlock_irqrestore(&patch_lock, flags); 132 + 133 + flush_icache_range((uintptr_t)addr, (uintptr_t)addr + len); 134 + 135 + return addr; 136 + } 137 + 138 + static void text_poke_memcpy(void *dst, void *src, size_t patched, size_t len) 139 + { 140 + copy_to_kernel_nofault(dst, src + patched, len); 141 + } 142 + 143 + static void text_poke_memset(void *dst, void *src, size_t patched, size_t len) 144 + { 145 + u32 c = *(u32 *)src; 146 + 147 + memset32(dst, c, len / 4); 148 + } 149 + 150 + /** 151 + * aarch64_insn_copy - Copy instructions into (an unused part of) RX memory 152 + * @dst: address to modify 153 + * @src: source of the copy 154 + * @len: length to copy 155 + * 156 + * Useful for JITs to dump new code blocks into unused regions of RX memory. 157 + */ 158 + noinstr void *aarch64_insn_copy(void *dst, void *src, size_t len) 159 + { 160 + /* A64 instructions must be word aligned */ 161 + if ((uintptr_t)dst & 0x3) 162 + return NULL; 163 + 164 + return __text_poke(text_poke_memcpy, dst, src, len); 165 + } 166 + 167 + /** 168 + * aarch64_insn_set - memset for RX memory regions. 169 + * @dst: address to modify 170 + * @insn: value to set 171 + * @len: length of memory region. 172 + * 173 + * Useful for JITs to fill regions of RX memory with illegal instructions. 174 + */ 175 + noinstr void *aarch64_insn_set(void *dst, u32 insn, size_t len) 176 + { 177 + if ((uintptr_t)dst & 0x3) 178 + return NULL; 179 + 180 + return __text_poke(text_poke_memset, dst, &insn, len); 181 + } 182 + 108 183 int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn) 109 184 { 110 185 u32 *tp = addr;
+26
arch/arm64/kernel/stacktrace.c
··· 7 7 #include <linux/kernel.h> 8 8 #include <linux/efi.h> 9 9 #include <linux/export.h> 10 + #include <linux/filter.h> 10 11 #include <linux/ftrace.h> 11 12 #include <linux/kprobes.h> 12 13 #include <linux/sched.h> ··· 265 264 }; 266 265 267 266 kunwind_stack_walk(arch_kunwind_consume_entry, &data, task, regs); 267 + } 268 + 269 + struct bpf_unwind_consume_entry_data { 270 + bool (*consume_entry)(void *cookie, u64 ip, u64 sp, u64 fp); 271 + void *cookie; 272 + }; 273 + 274 + static bool 275 + arch_bpf_unwind_consume_entry(const struct kunwind_state *state, void *cookie) 276 + { 277 + struct bpf_unwind_consume_entry_data *data = cookie; 278 + 279 + return data->consume_entry(data->cookie, state->common.pc, 0, 280 + state->common.fp); 281 + } 282 + 283 + noinline noinstr void arch_bpf_stack_walk(bool (*consume_entry)(void *cookie, u64 ip, u64 sp, 284 + u64 fp), void *cookie) 285 + { 286 + struct bpf_unwind_consume_entry_data data = { 287 + .consume_entry = consume_entry, 288 + .cookie = cookie, 289 + }; 290 + 291 + kunwind_stack_walk(arch_bpf_unwind_consume_entry, &data, current, NULL); 268 292 } 269 293 270 294 static bool dump_backtrace_entry(void *arg, unsigned long where)
+182 -42
arch/arm64/net/bpf_jit_comp.c
··· 76 76 int *offset; 77 77 int exentry_idx; 78 78 __le32 *image; 79 + __le32 *ro_image; 79 80 u32 stack_size; 80 81 int fpb_offset; 81 82 }; ··· 206 205 *ptr++ = cpu_to_le32(AARCH64_BREAK_FAULT); 207 206 } 208 207 208 + int bpf_arch_text_invalidate(void *dst, size_t len) 209 + { 210 + if (!aarch64_insn_set(dst, AARCH64_BREAK_FAULT, len)) 211 + return -EINVAL; 212 + 213 + return 0; 214 + } 215 + 209 216 static inline int epilogue_offset(const struct jit_ctx *ctx) 210 217 { 211 218 int to = ctx->epilogue_offset; ··· 294 285 /* Tail call offset to jump into */ 295 286 #define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8) 296 287 297 - static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf) 288 + static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf, 289 + bool is_exception_cb) 298 290 { 299 291 const struct bpf_prog *prog = ctx->prog; 300 292 const bool is_main_prog = !bpf_is_subprog(prog); ··· 343 333 emit(A64_MOV(1, A64_R(9), A64_LR), ctx); 344 334 emit(A64_NOP, ctx); 345 335 346 - /* Sign lr */ 347 - if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL)) 348 - emit(A64_PACIASP, ctx); 336 + if (!is_exception_cb) { 337 + /* Sign lr */ 338 + if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL)) 339 + emit(A64_PACIASP, ctx); 340 + /* Save FP and LR registers to stay align with ARM64 AAPCS */ 341 + emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx); 342 + emit(A64_MOV(1, A64_FP, A64_SP), ctx); 349 343 350 - /* Save FP and LR registers to stay align with ARM64 AAPCS */ 351 - emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx); 352 - emit(A64_MOV(1, A64_FP, A64_SP), ctx); 353 - 354 - /* Save callee-saved registers */ 355 - emit(A64_PUSH(r6, r7, A64_SP), ctx); 356 - emit(A64_PUSH(r8, r9, A64_SP), ctx); 357 - emit(A64_PUSH(fp, tcc, A64_SP), ctx); 358 - emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx); 344 + /* Save callee-saved registers */ 345 + emit(A64_PUSH(r6, r7, A64_SP), ctx); 346 + emit(A64_PUSH(r8, r9, A64_SP), ctx); 347 + emit(A64_PUSH(fp, tcc, A64_SP), ctx); 348 + emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx); 349 + } else { 350 + /* 351 + * Exception callback receives FP of Main Program as third 352 + * parameter 353 + */ 354 + emit(A64_MOV(1, A64_FP, A64_R(2)), ctx); 355 + /* 356 + * Main Program already pushed the frame record and the 357 + * callee-saved registers. The exception callback will not push 358 + * anything and re-use the main program's stack. 359 + * 360 + * 10 registers are on the stack 361 + */ 362 + emit(A64_SUB_I(1, A64_SP, A64_FP, 80), ctx); 363 + } 359 364 360 365 /* Set up BPF prog stack base register */ 361 366 emit(A64_MOV(1, fp, A64_SP), ctx); ··· 388 363 389 364 /* BTI landing pad for the tail call, done with a BR */ 390 365 emit_bti(A64_BTI_J, ctx); 366 + } 367 + 368 + /* 369 + * Program acting as exception boundary should save all ARM64 370 + * Callee-saved registers as the exception callback needs to recover 371 + * all ARM64 Callee-saved registers in its epilogue. 372 + */ 373 + if (prog->aux->exception_boundary) { 374 + /* 375 + * As we are pushing two more registers, BPF_FP should be moved 376 + * 16 bytes 377 + */ 378 + emit(A64_SUB_I(1, fp, fp, 16), ctx); 379 + emit(A64_PUSH(A64_R(23), A64_R(24), A64_SP), ctx); 391 380 } 392 381 393 382 emit(A64_SUB_I(1, fpb, fp, ctx->fpb_offset), ctx); ··· 692 653 plt->target = (u64)&dummy_tramp; 693 654 } 694 655 695 - static void build_epilogue(struct jit_ctx *ctx) 656 + static void build_epilogue(struct jit_ctx *ctx, bool is_exception_cb) 696 657 { 697 658 const u8 r0 = bpf2a64[BPF_REG_0]; 698 659 const u8 r6 = bpf2a64[BPF_REG_6]; ··· 704 665 705 666 /* We're done with BPF stack */ 706 667 emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx); 668 + 669 + /* 670 + * Program acting as exception boundary pushes R23 and R24 in addition 671 + * to BPF callee-saved registers. Exception callback uses the boundary 672 + * program's stack frame, so recover these extra registers in the above 673 + * two cases. 674 + */ 675 + if (ctx->prog->aux->exception_boundary || is_exception_cb) 676 + emit(A64_POP(A64_R(23), A64_R(24), A64_SP), ctx); 707 677 708 678 /* Restore x27 and x28 */ 709 679 emit(A64_POP(fpb, A64_R(28), A64_SP), ctx); ··· 755 707 struct jit_ctx *ctx, 756 708 int dst_reg) 757 709 { 758 - off_t offset; 710 + off_t ins_offset; 711 + off_t fixup_offset; 759 712 unsigned long pc; 760 713 struct exception_table_entry *ex; 761 714 ··· 773 724 return -EINVAL; 774 725 775 726 ex = &ctx->prog->aux->extable[ctx->exentry_idx]; 776 - pc = (unsigned long)&ctx->image[ctx->idx - 1]; 727 + pc = (unsigned long)&ctx->ro_image[ctx->idx - 1]; 777 728 778 - offset = pc - (long)&ex->insn; 779 - if (WARN_ON_ONCE(offset >= 0 || offset < INT_MIN)) 729 + /* 730 + * This is the relative offset of the instruction that may fault from 731 + * the exception table itself. This will be written to the exception 732 + * table and if this instruction faults, the destination register will 733 + * be set to '0' and the execution will jump to the next instruction. 734 + */ 735 + ins_offset = pc - (long)&ex->insn; 736 + if (WARN_ON_ONCE(ins_offset >= 0 || ins_offset < INT_MIN)) 780 737 return -ERANGE; 781 - ex->insn = offset; 782 738 783 739 /* 784 740 * Since the extable follows the program, the fixup offset is always ··· 792 738 * bits. We don't need to worry about buildtime or runtime sort 793 739 * modifying the upper bits because the table is already sorted, and 794 740 * isn't part of the main exception table. 741 + * 742 + * The fixup_offset is set to the next instruction from the instruction 743 + * that may fault. The execution will jump to this after handling the 744 + * fault. 795 745 */ 796 - offset = (long)&ex->fixup - (pc + AARCH64_INSN_SIZE); 797 - if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, offset)) 746 + fixup_offset = (long)&ex->fixup - (pc + AARCH64_INSN_SIZE); 747 + if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, fixup_offset)) 798 748 return -ERANGE; 799 749 800 - ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) | 750 + /* 751 + * The offsets above have been calculated using the RO buffer but we 752 + * need to use the R/W buffer for writes. 753 + * switch ex to rw buffer for writing. 754 + */ 755 + ex = (void *)ctx->image + ((void *)ex - (void *)ctx->ro_image); 756 + 757 + ex->insn = ins_offset; 758 + 759 + ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, fixup_offset) | 801 760 FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg); 802 761 803 762 ex->type = EX_TYPE_BPF; ··· 1578 1511 1579 1512 struct arm64_jit_data { 1580 1513 struct bpf_binary_header *header; 1581 - u8 *image; 1514 + u8 *ro_image; 1515 + struct bpf_binary_header *ro_header; 1582 1516 struct jit_ctx ctx; 1583 1517 }; 1584 1518 ··· 1588 1520 int image_size, prog_size, extable_size, extable_align, extable_offset; 1589 1521 struct bpf_prog *tmp, *orig_prog = prog; 1590 1522 struct bpf_binary_header *header; 1523 + struct bpf_binary_header *ro_header; 1591 1524 struct arm64_jit_data *jit_data; 1592 1525 bool was_classic = bpf_prog_was_classic(prog); 1593 1526 bool tmp_blinded = false; 1594 1527 bool extra_pass = false; 1595 1528 struct jit_ctx ctx; 1596 1529 u8 *image_ptr; 1530 + u8 *ro_image_ptr; 1597 1531 1598 1532 if (!prog->jit_requested) 1599 1533 return orig_prog; ··· 1622 1552 } 1623 1553 if (jit_data->ctx.offset) { 1624 1554 ctx = jit_data->ctx; 1625 - image_ptr = jit_data->image; 1555 + ro_image_ptr = jit_data->ro_image; 1556 + ro_header = jit_data->ro_header; 1626 1557 header = jit_data->header; 1558 + image_ptr = (void *)header + ((void *)ro_image_ptr 1559 + - (void *)ro_header); 1627 1560 extra_pass = true; 1628 1561 prog_size = sizeof(u32) * ctx.idx; 1629 1562 goto skip_init_ctx; ··· 1648 1575 * BPF line info needs ctx->offset[i] to be the offset of 1649 1576 * instruction[i] in jited image, so build prologue first. 1650 1577 */ 1651 - if (build_prologue(&ctx, was_classic)) { 1578 + if (build_prologue(&ctx, was_classic, prog->aux->exception_cb)) { 1652 1579 prog = orig_prog; 1653 1580 goto out_off; 1654 1581 } ··· 1659 1586 } 1660 1587 1661 1588 ctx.epilogue_offset = ctx.idx; 1662 - build_epilogue(&ctx); 1589 + build_epilogue(&ctx, prog->aux->exception_cb); 1663 1590 build_plt(&ctx); 1664 1591 1665 1592 extable_align = __alignof__(struct exception_table_entry); ··· 1671 1598 /* also allocate space for plt target */ 1672 1599 extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align); 1673 1600 image_size = extable_offset + extable_size; 1674 - header = bpf_jit_binary_alloc(image_size, &image_ptr, 1675 - sizeof(u32), jit_fill_hole); 1676 - if (header == NULL) { 1601 + ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr, 1602 + sizeof(u32), &header, &image_ptr, 1603 + jit_fill_hole); 1604 + if (!ro_header) { 1677 1605 prog = orig_prog; 1678 1606 goto out_off; 1679 1607 } 1680 1608 1681 1609 /* 2. Now, the actual pass. */ 1682 1610 1611 + /* 1612 + * Use the image(RW) for writing the JITed instructions. But also save 1613 + * the ro_image(RX) for calculating the offsets in the image. The RW 1614 + * image will be later copied to the RX image from where the program 1615 + * will run. The bpf_jit_binary_pack_finalize() will do this copy in the 1616 + * final step. 1617 + */ 1683 1618 ctx.image = (__le32 *)image_ptr; 1619 + ctx.ro_image = (__le32 *)ro_image_ptr; 1684 1620 if (extable_size) 1685 - prog->aux->extable = (void *)image_ptr + extable_offset; 1621 + prog->aux->extable = (void *)ro_image_ptr + extable_offset; 1686 1622 skip_init_ctx: 1687 1623 ctx.idx = 0; 1688 1624 ctx.exentry_idx = 0; 1689 1625 1690 - build_prologue(&ctx, was_classic); 1626 + build_prologue(&ctx, was_classic, prog->aux->exception_cb); 1691 1627 1692 1628 if (build_body(&ctx, extra_pass)) { 1693 - bpf_jit_binary_free(header); 1694 1629 prog = orig_prog; 1695 - goto out_off; 1630 + goto out_free_hdr; 1696 1631 } 1697 1632 1698 - build_epilogue(&ctx); 1633 + build_epilogue(&ctx, prog->aux->exception_cb); 1699 1634 build_plt(&ctx); 1700 1635 1701 1636 /* 3. Extra pass to validate JITed code. */ 1702 1637 if (validate_ctx(&ctx)) { 1703 - bpf_jit_binary_free(header); 1704 1638 prog = orig_prog; 1705 - goto out_off; 1639 + goto out_free_hdr; 1706 1640 } 1707 1641 1708 1642 /* And we're done. */ 1709 1643 if (bpf_jit_enable > 1) 1710 1644 bpf_jit_dump(prog->len, prog_size, 2, ctx.image); 1711 1645 1712 - bpf_flush_icache(header, ctx.image + ctx.idx); 1713 - 1714 1646 if (!prog->is_func || extra_pass) { 1715 1647 if (extra_pass && ctx.idx != jit_data->ctx.idx) { 1716 1648 pr_err_once("multi-func JIT bug %d != %d\n", 1717 1649 ctx.idx, jit_data->ctx.idx); 1718 - bpf_jit_binary_free(header); 1719 1650 prog->bpf_func = NULL; 1720 1651 prog->jited = 0; 1721 1652 prog->jited_len = 0; 1653 + goto out_free_hdr; 1654 + } 1655 + if (WARN_ON(bpf_jit_binary_pack_finalize(prog, ro_header, 1656 + header))) { 1657 + /* ro_header has been freed */ 1658 + ro_header = NULL; 1659 + prog = orig_prog; 1722 1660 goto out_off; 1723 1661 } 1724 - bpf_jit_binary_lock_ro(header); 1662 + /* 1663 + * The instructions have now been copied to the ROX region from 1664 + * where they will execute. Now the data cache has to be cleaned to 1665 + * the PoU and the I-cache has to be invalidated for the VAs. 1666 + */ 1667 + bpf_flush_icache(ro_header, ctx.ro_image + ctx.idx); 1725 1668 } else { 1726 1669 jit_data->ctx = ctx; 1727 - jit_data->image = image_ptr; 1670 + jit_data->ro_image = ro_image_ptr; 1728 1671 jit_data->header = header; 1672 + jit_data->ro_header = ro_header; 1729 1673 } 1730 - prog->bpf_func = (void *)ctx.image; 1674 + 1675 + prog->bpf_func = (void *)ctx.ro_image; 1731 1676 prog->jited = 1; 1732 1677 prog->jited_len = prog_size; 1733 1678 ··· 1766 1675 bpf_jit_prog_release_other(prog, prog == orig_prog ? 1767 1676 tmp : orig_prog); 1768 1677 return prog; 1678 + 1679 + out_free_hdr: 1680 + if (header) { 1681 + bpf_arch_text_copy(&ro_header->size, &header->size, 1682 + sizeof(header->size)); 1683 + bpf_jit_binary_pack_free(ro_header, header); 1684 + } 1685 + goto out_off; 1769 1686 } 1770 1687 1771 1688 bool bpf_jit_supports_kfunc_call(void) 1772 1689 { 1773 1690 return true; 1691 + } 1692 + 1693 + void *bpf_arch_text_copy(void *dst, void *src, size_t len) 1694 + { 1695 + if (!aarch64_insn_copy(dst, src, len)) 1696 + return ERR_PTR(-EINVAL); 1697 + return dst; 1774 1698 } 1775 1699 1776 1700 u64 bpf_jit_alloc_exec_limit(void) ··· 2415 2309 bool bpf_jit_supports_ptr_xchg(void) 2416 2310 { 2417 2311 return true; 2312 + } 2313 + 2314 + bool bpf_jit_supports_exceptions(void) 2315 + { 2316 + /* We unwind through both kernel frames starting from within bpf_throw 2317 + * call and BPF frames. Therefore we require FP unwinder to be enabled 2318 + * to walk kernel frames and reach BPF frames in the stack trace. 2319 + * ARM64 kernel is aways compiled with CONFIG_FRAME_POINTER=y 2320 + */ 2321 + return true; 2322 + } 2323 + 2324 + void bpf_jit_free(struct bpf_prog *prog) 2325 + { 2326 + if (prog->jited) { 2327 + struct arm64_jit_data *jit_data = prog->aux->jit_data; 2328 + struct bpf_binary_header *hdr; 2329 + 2330 + /* 2331 + * If we fail the final pass of JIT (from jit_subprogs), 2332 + * the program may not be finalized yet. Call finalize here 2333 + * before freeing it. 2334 + */ 2335 + if (jit_data) { 2336 + bpf_arch_text_copy(&jit_data->ro_header->size, &jit_data->header->size, 2337 + sizeof(jit_data->header->size)); 2338 + kfree(jit_data); 2339 + } 2340 + hdr = bpf_jit_binary_pack_hdr(prog); 2341 + bpf_jit_binary_pack_free(hdr, NULL); 2342 + WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog)); 2343 + } 2344 + 2345 + bpf_prog_unlock_free(prog); 2418 2346 }
+134
arch/riscv/net/bpf_jit.h
··· 18 18 return IS_ENABLED(CONFIG_RISCV_ISA_C); 19 19 } 20 20 21 + static inline bool rvzbb_enabled(void) 22 + { 23 + return IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && riscv_has_extension_likely(RISCV_ISA_EXT_ZBB); 24 + } 25 + 21 26 enum { 22 27 RV_REG_ZERO = 0, /* The constant value 0 */ 23 28 RV_REG_RA = 1, /* Return address */ ··· 735 730 return rv_css_insn(0x6, imm, rs2, 0x2); 736 731 } 737 732 733 + /* RVZBB instrutions. */ 734 + static inline u32 rvzbb_sextb(u8 rd, u8 rs1) 735 + { 736 + return rv_i_insn(0x604, rs1, 1, rd, 0x13); 737 + } 738 + 739 + static inline u32 rvzbb_sexth(u8 rd, u8 rs1) 740 + { 741 + return rv_i_insn(0x605, rs1, 1, rd, 0x13); 742 + } 743 + 744 + static inline u32 rvzbb_zexth(u8 rd, u8 rs) 745 + { 746 + if (IS_ENABLED(CONFIG_64BIT)) 747 + return rv_i_insn(0x80, rs, 4, rd, 0x3b); 748 + 749 + return rv_i_insn(0x80, rs, 4, rd, 0x33); 750 + } 751 + 752 + static inline u32 rvzbb_rev8(u8 rd, u8 rs) 753 + { 754 + if (IS_ENABLED(CONFIG_64BIT)) 755 + return rv_i_insn(0x6b8, rs, 5, rd, 0x13); 756 + 757 + return rv_i_insn(0x698, rs, 5, rd, 0x13); 758 + } 759 + 738 760 /* 739 761 * RV64-only instructions. 740 762 * ··· 1117 1085 emitc(rvc_subw(rd, rs2), ctx); 1118 1086 else 1119 1087 emit(rv_subw(rd, rs1, rs2), ctx); 1088 + } 1089 + 1090 + static inline void emit_sextb(u8 rd, u8 rs, struct rv_jit_context *ctx) 1091 + { 1092 + if (rvzbb_enabled()) { 1093 + emit(rvzbb_sextb(rd, rs), ctx); 1094 + return; 1095 + } 1096 + 1097 + emit_slli(rd, rs, 56, ctx); 1098 + emit_srai(rd, rd, 56, ctx); 1099 + } 1100 + 1101 + static inline void emit_sexth(u8 rd, u8 rs, struct rv_jit_context *ctx) 1102 + { 1103 + if (rvzbb_enabled()) { 1104 + emit(rvzbb_sexth(rd, rs), ctx); 1105 + return; 1106 + } 1107 + 1108 + emit_slli(rd, rs, 48, ctx); 1109 + emit_srai(rd, rd, 48, ctx); 1110 + } 1111 + 1112 + static inline void emit_sextw(u8 rd, u8 rs, struct rv_jit_context *ctx) 1113 + { 1114 + emit_addiw(rd, rs, 0, ctx); 1115 + } 1116 + 1117 + static inline void emit_zexth(u8 rd, u8 rs, struct rv_jit_context *ctx) 1118 + { 1119 + if (rvzbb_enabled()) { 1120 + emit(rvzbb_zexth(rd, rs), ctx); 1121 + return; 1122 + } 1123 + 1124 + emit_slli(rd, rs, 48, ctx); 1125 + emit_srli(rd, rd, 48, ctx); 1126 + } 1127 + 1128 + static inline void emit_zextw(u8 rd, u8 rs, struct rv_jit_context *ctx) 1129 + { 1130 + emit_slli(rd, rs, 32, ctx); 1131 + emit_srli(rd, rd, 32, ctx); 1132 + } 1133 + 1134 + static inline void emit_bswap(u8 rd, s32 imm, struct rv_jit_context *ctx) 1135 + { 1136 + if (rvzbb_enabled()) { 1137 + int bits = 64 - imm; 1138 + 1139 + emit(rvzbb_rev8(rd, rd), ctx); 1140 + if (bits) 1141 + emit_srli(rd, rd, bits, ctx); 1142 + return; 1143 + } 1144 + 1145 + emit_li(RV_REG_T2, 0, ctx); 1146 + 1147 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1148 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1149 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1150 + emit_srli(rd, rd, 8, ctx); 1151 + if (imm == 16) 1152 + goto out_be; 1153 + 1154 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1155 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1156 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1157 + emit_srli(rd, rd, 8, ctx); 1158 + 1159 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1160 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1161 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1162 + emit_srli(rd, rd, 8, ctx); 1163 + if (imm == 32) 1164 + goto out_be; 1165 + 1166 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1167 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1168 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1169 + emit_srli(rd, rd, 8, ctx); 1170 + 1171 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1172 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1173 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1174 + emit_srli(rd, rd, 8, ctx); 1175 + 1176 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1177 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1178 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1179 + emit_srli(rd, rd, 8, ctx); 1180 + 1181 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1182 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1183 + emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1184 + emit_srli(rd, rd, 8, ctx); 1185 + out_be: 1186 + emit_andi(RV_REG_T1, rd, 0xff, ctx); 1187 + emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1188 + 1189 + emit_mv(rd, RV_REG_T2, ctx); 1120 1190 } 1121 1191 1122 1192 #endif /* __riscv_xlen == 64 */
+76 -139
arch/riscv/net/bpf_jit_comp64.c
··· 141 141 val < ((1L << 31) - (1L << 11)); 142 142 } 143 143 144 + /* Modify rd pointer to alternate reg to avoid corrupting original reg */ 145 + static void emit_sextw_alt(u8 *rd, u8 ra, struct rv_jit_context *ctx) 146 + { 147 + emit_sextw(ra, *rd, ctx); 148 + *rd = ra; 149 + } 150 + 151 + static void emit_zextw_alt(u8 *rd, u8 ra, struct rv_jit_context *ctx) 152 + { 153 + emit_zextw(ra, *rd, ctx); 154 + *rd = ra; 155 + } 156 + 144 157 /* Emit fixed-length instructions for address */ 145 158 static int emit_addr(u8 rd, u64 addr, bool extra_pass, struct rv_jit_context *ctx) 146 159 { ··· 339 326 emit(rv_jalr(RV_REG_ZERO, RV_REG_T1, lower), ctx); 340 327 } 341 328 342 - static void emit_zext_32(u8 reg, struct rv_jit_context *ctx) 343 - { 344 - emit_slli(reg, reg, 32, ctx); 345 - emit_srli(reg, reg, 32, ctx); 346 - } 347 - 348 329 static int emit_bpf_tail_call(int insn, struct rv_jit_context *ctx) 349 330 { 350 331 int tc_ninsn, off, start_insn = ctx->ninsns; ··· 353 346 */ 354 347 tc_ninsn = insn ? ctx->offset[insn] - ctx->offset[insn - 1] : 355 348 ctx->offset[0]; 356 - emit_zext_32(RV_REG_A2, ctx); 349 + emit_zextw(RV_REG_A2, RV_REG_A2, ctx); 357 350 358 351 off = offsetof(struct bpf_array, map.max_entries); 359 352 if (is_12b_check(off, insn)) ··· 410 403 code & (BPF_JMP | BPF_X) || code & (BPF_JMP32 | BPF_X) || 411 404 code & BPF_LDX || code & BPF_STX) 412 405 *rs = bpf_to_rv_reg(insn->src_reg, ctx); 413 - } 414 - 415 - static void emit_zext_32_rd_rs(u8 *rd, u8 *rs, struct rv_jit_context *ctx) 416 - { 417 - emit_mv(RV_REG_T2, *rd, ctx); 418 - emit_zext_32(RV_REG_T2, ctx); 419 - emit_mv(RV_REG_T1, *rs, ctx); 420 - emit_zext_32(RV_REG_T1, ctx); 421 - *rd = RV_REG_T2; 422 - *rs = RV_REG_T1; 423 - } 424 - 425 - static void emit_sext_32_rd_rs(u8 *rd, u8 *rs, struct rv_jit_context *ctx) 426 - { 427 - emit_addiw(RV_REG_T2, *rd, 0, ctx); 428 - emit_addiw(RV_REG_T1, *rs, 0, ctx); 429 - *rd = RV_REG_T2; 430 - *rs = RV_REG_T1; 431 - } 432 - 433 - static void emit_zext_32_rd_t1(u8 *rd, struct rv_jit_context *ctx) 434 - { 435 - emit_mv(RV_REG_T2, *rd, ctx); 436 - emit_zext_32(RV_REG_T2, ctx); 437 - emit_zext_32(RV_REG_T1, ctx); 438 - *rd = RV_REG_T2; 439 - } 440 - 441 - static void emit_sext_32_rd(u8 *rd, struct rv_jit_context *ctx) 442 - { 443 - emit_addiw(RV_REG_T2, *rd, 0, ctx); 444 - *rd = RV_REG_T2; 445 406 } 446 407 447 408 static int emit_jump_and_link(u8 rd, s64 rvoff, bool fixed_addr, ··· 494 519 emit(is64 ? rv_amoadd_d(rs, rs, rd, 0, 0) : 495 520 rv_amoadd_w(rs, rs, rd, 0, 0), ctx); 496 521 if (!is64) 497 - emit_zext_32(rs, ctx); 522 + emit_zextw(rs, rs, ctx); 498 523 break; 499 524 case BPF_AND | BPF_FETCH: 500 525 emit(is64 ? rv_amoand_d(rs, rs, rd, 0, 0) : 501 526 rv_amoand_w(rs, rs, rd, 0, 0), ctx); 502 527 if (!is64) 503 - emit_zext_32(rs, ctx); 528 + emit_zextw(rs, rs, ctx); 504 529 break; 505 530 case BPF_OR | BPF_FETCH: 506 531 emit(is64 ? rv_amoor_d(rs, rs, rd, 0, 0) : 507 532 rv_amoor_w(rs, rs, rd, 0, 0), ctx); 508 533 if (!is64) 509 - emit_zext_32(rs, ctx); 534 + emit_zextw(rs, rs, ctx); 510 535 break; 511 536 case BPF_XOR | BPF_FETCH: 512 537 emit(is64 ? rv_amoxor_d(rs, rs, rd, 0, 0) : 513 538 rv_amoxor_w(rs, rs, rd, 0, 0), ctx); 514 539 if (!is64) 515 - emit_zext_32(rs, ctx); 540 + emit_zextw(rs, rs, ctx); 516 541 break; 517 542 /* src_reg = atomic_xchg(dst_reg + off16, src_reg); */ 518 543 case BPF_XCHG: 519 544 emit(is64 ? rv_amoswap_d(rs, rs, rd, 0, 0) : 520 545 rv_amoswap_w(rs, rs, rd, 0, 0), ctx); 521 546 if (!is64) 522 - emit_zext_32(rs, ctx); 547 + emit_zextw(rs, rs, ctx); 523 548 break; 524 549 /* r0 = atomic_cmpxchg(dst_reg + off16, r0, src_reg); */ 525 550 case BPF_CMPXCHG: ··· 1066 1091 case BPF_ALU64 | BPF_MOV | BPF_X: 1067 1092 if (imm == 1) { 1068 1093 /* Special mov32 for zext */ 1069 - emit_zext_32(rd, ctx); 1094 + emit_zextw(rd, rd, ctx); 1070 1095 break; 1071 1096 } 1072 1097 switch (insn->off) { ··· 1074 1099 emit_mv(rd, rs, ctx); 1075 1100 break; 1076 1101 case 8: 1102 + emit_sextb(rd, rs, ctx); 1103 + break; 1077 1104 case 16: 1078 - emit_slli(RV_REG_T1, rs, 64 - insn->off, ctx); 1079 - emit_srai(rd, RV_REG_T1, 64 - insn->off, ctx); 1105 + emit_sexth(rd, rs, ctx); 1080 1106 break; 1081 1107 case 32: 1082 - emit_addiw(rd, rs, 0, ctx); 1108 + emit_sextw(rd, rs, ctx); 1083 1109 break; 1084 1110 } 1085 1111 if (!is64 && !aux->verifier_zext) 1086 - emit_zext_32(rd, ctx); 1112 + emit_zextw(rd, rd, ctx); 1087 1113 break; 1088 1114 1089 1115 /* dst = dst OP src */ ··· 1092 1116 case BPF_ALU64 | BPF_ADD | BPF_X: 1093 1117 emit_add(rd, rd, rs, ctx); 1094 1118 if (!is64 && !aux->verifier_zext) 1095 - emit_zext_32(rd, ctx); 1119 + emit_zextw(rd, rd, ctx); 1096 1120 break; 1097 1121 case BPF_ALU | BPF_SUB | BPF_X: 1098 1122 case BPF_ALU64 | BPF_SUB | BPF_X: ··· 1102 1126 emit_subw(rd, rd, rs, ctx); 1103 1127 1104 1128 if (!is64 && !aux->verifier_zext) 1105 - emit_zext_32(rd, ctx); 1129 + emit_zextw(rd, rd, ctx); 1106 1130 break; 1107 1131 case BPF_ALU | BPF_AND | BPF_X: 1108 1132 case BPF_ALU64 | BPF_AND | BPF_X: 1109 1133 emit_and(rd, rd, rs, ctx); 1110 1134 if (!is64 && !aux->verifier_zext) 1111 - emit_zext_32(rd, ctx); 1135 + emit_zextw(rd, rd, ctx); 1112 1136 break; 1113 1137 case BPF_ALU | BPF_OR | BPF_X: 1114 1138 case BPF_ALU64 | BPF_OR | BPF_X: 1115 1139 emit_or(rd, rd, rs, ctx); 1116 1140 if (!is64 && !aux->verifier_zext) 1117 - emit_zext_32(rd, ctx); 1141 + emit_zextw(rd, rd, ctx); 1118 1142 break; 1119 1143 case BPF_ALU | BPF_XOR | BPF_X: 1120 1144 case BPF_ALU64 | BPF_XOR | BPF_X: 1121 1145 emit_xor(rd, rd, rs, ctx); 1122 1146 if (!is64 && !aux->verifier_zext) 1123 - emit_zext_32(rd, ctx); 1147 + emit_zextw(rd, rd, ctx); 1124 1148 break; 1125 1149 case BPF_ALU | BPF_MUL | BPF_X: 1126 1150 case BPF_ALU64 | BPF_MUL | BPF_X: 1127 1151 emit(is64 ? rv_mul(rd, rd, rs) : rv_mulw(rd, rd, rs), ctx); 1128 1152 if (!is64 && !aux->verifier_zext) 1129 - emit_zext_32(rd, ctx); 1153 + emit_zextw(rd, rd, ctx); 1130 1154 break; 1131 1155 case BPF_ALU | BPF_DIV | BPF_X: 1132 1156 case BPF_ALU64 | BPF_DIV | BPF_X: ··· 1135 1159 else 1136 1160 emit(is64 ? rv_divu(rd, rd, rs) : rv_divuw(rd, rd, rs), ctx); 1137 1161 if (!is64 && !aux->verifier_zext) 1138 - emit_zext_32(rd, ctx); 1162 + emit_zextw(rd, rd, ctx); 1139 1163 break; 1140 1164 case BPF_ALU | BPF_MOD | BPF_X: 1141 1165 case BPF_ALU64 | BPF_MOD | BPF_X: ··· 1144 1168 else 1145 1169 emit(is64 ? rv_remu(rd, rd, rs) : rv_remuw(rd, rd, rs), ctx); 1146 1170 if (!is64 && !aux->verifier_zext) 1147 - emit_zext_32(rd, ctx); 1171 + emit_zextw(rd, rd, ctx); 1148 1172 break; 1149 1173 case BPF_ALU | BPF_LSH | BPF_X: 1150 1174 case BPF_ALU64 | BPF_LSH | BPF_X: 1151 1175 emit(is64 ? rv_sll(rd, rd, rs) : rv_sllw(rd, rd, rs), ctx); 1152 1176 if (!is64 && !aux->verifier_zext) 1153 - emit_zext_32(rd, ctx); 1177 + emit_zextw(rd, rd, ctx); 1154 1178 break; 1155 1179 case BPF_ALU | BPF_RSH | BPF_X: 1156 1180 case BPF_ALU64 | BPF_RSH | BPF_X: 1157 1181 emit(is64 ? rv_srl(rd, rd, rs) : rv_srlw(rd, rd, rs), ctx); 1158 1182 if (!is64 && !aux->verifier_zext) 1159 - emit_zext_32(rd, ctx); 1183 + emit_zextw(rd, rd, ctx); 1160 1184 break; 1161 1185 case BPF_ALU | BPF_ARSH | BPF_X: 1162 1186 case BPF_ALU64 | BPF_ARSH | BPF_X: 1163 1187 emit(is64 ? rv_sra(rd, rd, rs) : rv_sraw(rd, rd, rs), ctx); 1164 1188 if (!is64 && !aux->verifier_zext) 1165 - emit_zext_32(rd, ctx); 1189 + emit_zextw(rd, rd, ctx); 1166 1190 break; 1167 1191 1168 1192 /* dst = -dst */ ··· 1170 1194 case BPF_ALU64 | BPF_NEG: 1171 1195 emit_sub(rd, RV_REG_ZERO, rd, ctx); 1172 1196 if (!is64 && !aux->verifier_zext) 1173 - emit_zext_32(rd, ctx); 1197 + emit_zextw(rd, rd, ctx); 1174 1198 break; 1175 1199 1176 1200 /* dst = BSWAP##imm(dst) */ 1177 1201 case BPF_ALU | BPF_END | BPF_FROM_LE: 1178 1202 switch (imm) { 1179 1203 case 16: 1180 - emit_slli(rd, rd, 48, ctx); 1181 - emit_srli(rd, rd, 48, ctx); 1204 + emit_zexth(rd, rd, ctx); 1182 1205 break; 1183 1206 case 32: 1184 1207 if (!aux->verifier_zext) 1185 - emit_zext_32(rd, ctx); 1208 + emit_zextw(rd, rd, ctx); 1186 1209 break; 1187 1210 case 64: 1188 1211 /* Do nothing */ 1189 1212 break; 1190 1213 } 1191 1214 break; 1192 - 1193 1215 case BPF_ALU | BPF_END | BPF_FROM_BE: 1194 1216 case BPF_ALU64 | BPF_END | BPF_FROM_LE: 1195 - emit_li(RV_REG_T2, 0, ctx); 1196 - 1197 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1198 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1199 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1200 - emit_srli(rd, rd, 8, ctx); 1201 - if (imm == 16) 1202 - goto out_be; 1203 - 1204 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1205 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1206 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1207 - emit_srli(rd, rd, 8, ctx); 1208 - 1209 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1210 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1211 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1212 - emit_srli(rd, rd, 8, ctx); 1213 - if (imm == 32) 1214 - goto out_be; 1215 - 1216 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1217 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1218 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1219 - emit_srli(rd, rd, 8, ctx); 1220 - 1221 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1222 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1223 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1224 - emit_srli(rd, rd, 8, ctx); 1225 - 1226 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1227 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1228 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1229 - emit_srli(rd, rd, 8, ctx); 1230 - 1231 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1232 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1233 - emit_slli(RV_REG_T2, RV_REG_T2, 8, ctx); 1234 - emit_srli(rd, rd, 8, ctx); 1235 - out_be: 1236 - emit_andi(RV_REG_T1, rd, 0xff, ctx); 1237 - emit_add(RV_REG_T2, RV_REG_T2, RV_REG_T1, ctx); 1238 - 1239 - emit_mv(rd, RV_REG_T2, ctx); 1217 + emit_bswap(rd, imm, ctx); 1240 1218 break; 1241 1219 1242 1220 /* dst = imm */ ··· 1198 1268 case BPF_ALU64 | BPF_MOV | BPF_K: 1199 1269 emit_imm(rd, imm, ctx); 1200 1270 if (!is64 && !aux->verifier_zext) 1201 - emit_zext_32(rd, ctx); 1271 + emit_zextw(rd, rd, ctx); 1202 1272 break; 1203 1273 1204 1274 /* dst = dst OP imm */ ··· 1211 1281 emit_add(rd, rd, RV_REG_T1, ctx); 1212 1282 } 1213 1283 if (!is64 && !aux->verifier_zext) 1214 - emit_zext_32(rd, ctx); 1284 + emit_zextw(rd, rd, ctx); 1215 1285 break; 1216 1286 case BPF_ALU | BPF_SUB | BPF_K: 1217 1287 case BPF_ALU64 | BPF_SUB | BPF_K: ··· 1222 1292 emit_sub(rd, rd, RV_REG_T1, ctx); 1223 1293 } 1224 1294 if (!is64 && !aux->verifier_zext) 1225 - emit_zext_32(rd, ctx); 1295 + emit_zextw(rd, rd, ctx); 1226 1296 break; 1227 1297 case BPF_ALU | BPF_AND | BPF_K: 1228 1298 case BPF_ALU64 | BPF_AND | BPF_K: ··· 1233 1303 emit_and(rd, rd, RV_REG_T1, ctx); 1234 1304 } 1235 1305 if (!is64 && !aux->verifier_zext) 1236 - emit_zext_32(rd, ctx); 1306 + emit_zextw(rd, rd, ctx); 1237 1307 break; 1238 1308 case BPF_ALU | BPF_OR | BPF_K: 1239 1309 case BPF_ALU64 | BPF_OR | BPF_K: ··· 1244 1314 emit_or(rd, rd, RV_REG_T1, ctx); 1245 1315 } 1246 1316 if (!is64 && !aux->verifier_zext) 1247 - emit_zext_32(rd, ctx); 1317 + emit_zextw(rd, rd, ctx); 1248 1318 break; 1249 1319 case BPF_ALU | BPF_XOR | BPF_K: 1250 1320 case BPF_ALU64 | BPF_XOR | BPF_K: ··· 1255 1325 emit_xor(rd, rd, RV_REG_T1, ctx); 1256 1326 } 1257 1327 if (!is64 && !aux->verifier_zext) 1258 - emit_zext_32(rd, ctx); 1328 + emit_zextw(rd, rd, ctx); 1259 1329 break; 1260 1330 case BPF_ALU | BPF_MUL | BPF_K: 1261 1331 case BPF_ALU64 | BPF_MUL | BPF_K: ··· 1263 1333 emit(is64 ? rv_mul(rd, rd, RV_REG_T1) : 1264 1334 rv_mulw(rd, rd, RV_REG_T1), ctx); 1265 1335 if (!is64 && !aux->verifier_zext) 1266 - emit_zext_32(rd, ctx); 1336 + emit_zextw(rd, rd, ctx); 1267 1337 break; 1268 1338 case BPF_ALU | BPF_DIV | BPF_K: 1269 1339 case BPF_ALU64 | BPF_DIV | BPF_K: ··· 1275 1345 emit(is64 ? rv_divu(rd, rd, RV_REG_T1) : 1276 1346 rv_divuw(rd, rd, RV_REG_T1), ctx); 1277 1347 if (!is64 && !aux->verifier_zext) 1278 - emit_zext_32(rd, ctx); 1348 + emit_zextw(rd, rd, ctx); 1279 1349 break; 1280 1350 case BPF_ALU | BPF_MOD | BPF_K: 1281 1351 case BPF_ALU64 | BPF_MOD | BPF_K: ··· 1287 1357 emit(is64 ? rv_remu(rd, rd, RV_REG_T1) : 1288 1358 rv_remuw(rd, rd, RV_REG_T1), ctx); 1289 1359 if (!is64 && !aux->verifier_zext) 1290 - emit_zext_32(rd, ctx); 1360 + emit_zextw(rd, rd, ctx); 1291 1361 break; 1292 1362 case BPF_ALU | BPF_LSH | BPF_K: 1293 1363 case BPF_ALU64 | BPF_LSH | BPF_K: 1294 1364 emit_slli(rd, rd, imm, ctx); 1295 1365 1296 1366 if (!is64 && !aux->verifier_zext) 1297 - emit_zext_32(rd, ctx); 1367 + emit_zextw(rd, rd, ctx); 1298 1368 break; 1299 1369 case BPF_ALU | BPF_RSH | BPF_K: 1300 1370 case BPF_ALU64 | BPF_RSH | BPF_K: ··· 1304 1374 emit(rv_srliw(rd, rd, imm), ctx); 1305 1375 1306 1376 if (!is64 && !aux->verifier_zext) 1307 - emit_zext_32(rd, ctx); 1377 + emit_zextw(rd, rd, ctx); 1308 1378 break; 1309 1379 case BPF_ALU | BPF_ARSH | BPF_K: 1310 1380 case BPF_ALU64 | BPF_ARSH | BPF_K: ··· 1314 1384 emit(rv_sraiw(rd, rd, imm), ctx); 1315 1385 1316 1386 if (!is64 && !aux->verifier_zext) 1317 - emit_zext_32(rd, ctx); 1387 + emit_zextw(rd, rd, ctx); 1318 1388 break; 1319 1389 1320 1390 /* JUMP off */ ··· 1355 1425 rvoff = rv_offset(i, off, ctx); 1356 1426 if (!is64) { 1357 1427 s = ctx->ninsns; 1358 - if (is_signed_bpf_cond(BPF_OP(code))) 1359 - emit_sext_32_rd_rs(&rd, &rs, ctx); 1360 - else 1361 - emit_zext_32_rd_rs(&rd, &rs, ctx); 1428 + if (is_signed_bpf_cond(BPF_OP(code))) { 1429 + emit_sextw_alt(&rs, RV_REG_T1, ctx); 1430 + emit_sextw_alt(&rd, RV_REG_T2, ctx); 1431 + } else { 1432 + emit_zextw_alt(&rs, RV_REG_T1, ctx); 1433 + emit_zextw_alt(&rd, RV_REG_T2, ctx); 1434 + } 1362 1435 e = ctx->ninsns; 1363 1436 1364 1437 /* Adjust for extra insns */ ··· 1372 1439 /* Adjust for and */ 1373 1440 rvoff -= 4; 1374 1441 emit_and(RV_REG_T1, rd, rs, ctx); 1375 - emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff, 1376 - ctx); 1442 + emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff, ctx); 1377 1443 } else { 1378 1444 emit_branch(BPF_OP(code), rd, rs, rvoff, ctx); 1379 1445 } ··· 1401 1469 case BPF_JMP32 | BPF_JSLE | BPF_K: 1402 1470 rvoff = rv_offset(i, off, ctx); 1403 1471 s = ctx->ninsns; 1404 - if (imm) { 1472 + if (imm) 1405 1473 emit_imm(RV_REG_T1, imm, ctx); 1406 - rs = RV_REG_T1; 1407 - } else { 1408 - /* If imm is 0, simply use zero register. */ 1409 - rs = RV_REG_ZERO; 1410 - } 1474 + rs = imm ? RV_REG_T1 : RV_REG_ZERO; 1411 1475 if (!is64) { 1412 - if (is_signed_bpf_cond(BPF_OP(code))) 1413 - emit_sext_32_rd(&rd, ctx); 1414 - else 1415 - emit_zext_32_rd_t1(&rd, ctx); 1476 + if (is_signed_bpf_cond(BPF_OP(code))) { 1477 + emit_sextw_alt(&rd, RV_REG_T2, ctx); 1478 + /* rs has been sign extended */ 1479 + } else { 1480 + emit_zextw_alt(&rd, RV_REG_T2, ctx); 1481 + if (imm) 1482 + emit_zextw(rs, rs, ctx); 1483 + } 1416 1484 } 1417 1485 e = ctx->ninsns; 1418 1486 ··· 1436 1504 * as t1 is used only in comparison against zero. 1437 1505 */ 1438 1506 if (!is64 && imm < 0) 1439 - emit_addiw(RV_REG_T1, RV_REG_T1, 0, ctx); 1507 + emit_sextw(RV_REG_T1, RV_REG_T1, ctx); 1440 1508 e = ctx->ninsns; 1441 1509 rvoff -= ninsns_rvoff(e - s); 1442 1510 emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff, ctx); ··· 1803 1871 } 1804 1872 1805 1873 bool bpf_jit_supports_kfunc_call(void) 1874 + { 1875 + return true; 1876 + } 1877 + 1878 + bool bpf_jit_supports_ptr_xchg(void) 1806 1879 { 1807 1880 return true; 1808 1881 }
+4 -4
drivers/hid/bpf/hid_bpf_dispatch.c
··· 176 176 * The following set contains all functions we agree BPF programs 177 177 * can use. 178 178 */ 179 - BTF_SET8_START(hid_bpf_kfunc_ids) 179 + BTF_KFUNCS_START(hid_bpf_kfunc_ids) 180 180 BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL) 181 - BTF_SET8_END(hid_bpf_kfunc_ids) 181 + BTF_KFUNCS_END(hid_bpf_kfunc_ids) 182 182 183 183 static const struct btf_kfunc_id_set hid_bpf_kfunc_set = { 184 184 .owner = THIS_MODULE, ··· 487 487 }; 488 488 489 489 /* for syscall HID-BPF */ 490 - BTF_SET8_START(hid_bpf_syscall_kfunc_ids) 490 + BTF_KFUNCS_START(hid_bpf_syscall_kfunc_ids) 491 491 BTF_ID_FLAGS(func, hid_bpf_attach_prog) 492 492 BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL) 493 493 BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE) 494 494 BTF_ID_FLAGS(func, hid_bpf_hw_request) 495 - BTF_SET8_END(hid_bpf_syscall_kfunc_ids) 495 + BTF_KFUNCS_END(hid_bpf_syscall_kfunc_ids) 496 496 497 497 static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = { 498 498 .owner = THIS_MODULE,
+2 -2
fs/verity/measure.c
··· 159 159 160 160 __bpf_kfunc_end_defs(); 161 161 162 - BTF_SET8_START(fsverity_set_ids) 162 + BTF_KFUNCS_START(fsverity_set_ids) 163 163 BTF_ID_FLAGS(func, bpf_get_fsverity_digest, KF_TRUSTED_ARGS) 164 - BTF_SET8_END(fsverity_set_ids) 164 + BTF_KFUNCS_END(fsverity_set_ids) 165 165 166 166 static int bpf_get_fsverity_digest_filter(const struct bpf_prog *prog, u32 kfunc_id) 167 167 {
+2 -1
include/linux/bpf-cgroup.h
··· 196 196 ({ \ 197 197 int __ret = 0; \ 198 198 if (cgroup_bpf_enabled(CGROUP_INET_INGRESS) && \ 199 - cgroup_bpf_sock_enabled(sk, CGROUP_INET_INGRESS)) \ 199 + cgroup_bpf_sock_enabled(sk, CGROUP_INET_INGRESS) && sk && \ 200 + sk_fullsock(sk)) \ 200 201 __ret = __cgroup_bpf_run_filter_skb(sk, skb, \ 201 202 CGROUP_INET_INGRESS); \ 202 203 \
+25 -10
include/linux/bpf.h
··· 251 251 } __attribute__((aligned(8))); 252 252 253 253 struct bpf_map { 254 - /* The first two cachelines with read-mostly members of which some 255 - * are also accessed in fast-path (e.g. ops, max_entries). 256 - */ 257 - const struct bpf_map_ops *ops ____cacheline_aligned; 254 + const struct bpf_map_ops *ops; 258 255 struct bpf_map *inner_map_meta; 259 256 #ifdef CONFIG_SECURITY 260 257 void *security; ··· 273 276 struct obj_cgroup *objcg; 274 277 #endif 275 278 char name[BPF_OBJ_NAME_LEN]; 276 - /* The 3rd and 4th cacheline with misc members to avoid false sharing 277 - * particularly with refcounting. 278 - */ 279 - atomic64_t refcnt ____cacheline_aligned; 279 + struct mutex freeze_mutex; 280 + atomic64_t refcnt; 280 281 atomic64_t usercnt; 281 282 /* rcu is used before freeing and work is only used during freeing */ 282 283 union { 283 284 struct work_struct work; 284 285 struct rcu_head rcu; 285 286 }; 286 - struct mutex freeze_mutex; 287 287 atomic64_t writecnt; 288 288 /* 'Ownership' of program-containing map is claimed by the first program 289 289 * that is going to use this map or by the first program which FD is ··· 1183 1189 int progs_cnt[BPF_TRAMP_MAX]; 1184 1190 /* Executable image of trampoline */ 1185 1191 struct bpf_tramp_image *cur_image; 1186 - struct module *mod; 1187 1192 }; 1188 1193 1189 1194 struct bpf_attach_target_info { ··· 1409 1416 struct bpf_ctx_arg_aux { 1410 1417 u32 offset; 1411 1418 enum bpf_reg_type reg_type; 1419 + struct btf *btf; 1412 1420 u32 btf_id; 1413 1421 }; 1414 1422 ··· 1703 1709 struct btf_func_model func_models[BPF_STRUCT_OPS_MAX_NR_MEMBERS]; 1704 1710 }; 1705 1711 1712 + /* Every member of a struct_ops type has an instance even a member is not 1713 + * an operator (function pointer). The "info" field will be assigned to 1714 + * prog->aux->ctx_arg_info of BPF struct_ops programs to provide the 1715 + * argument information required by the verifier to verify the program. 1716 + * 1717 + * btf_ctx_access() will lookup prog->aux->ctx_arg_info to find the 1718 + * corresponding entry for an given argument. 1719 + */ 1720 + struct bpf_struct_ops_arg_info { 1721 + struct bpf_ctx_arg_aux *info; 1722 + u32 cnt; 1723 + }; 1724 + 1706 1725 struct bpf_struct_ops_desc { 1707 1726 struct bpf_struct_ops *st_ops; 1708 1727 ··· 1723 1716 const struct btf_type *value_type; 1724 1717 u32 type_id; 1725 1718 u32 value_id; 1719 + 1720 + /* Collection of argument information for each member */ 1721 + struct bpf_struct_ops_arg_info *arg_info; 1726 1722 }; 1727 1723 1728 1724 enum bpf_struct_ops_state { ··· 1800 1790 struct btf *btf, 1801 1791 struct bpf_verifier_log *log); 1802 1792 void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struct bpf_map *map); 1793 + void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc); 1803 1794 #else 1804 1795 #define register_bpf_struct_ops(st_ops, type) ({ (void *)(st_ops); 0; }) 1805 1796 static inline bool bpf_try_module_get(const void *data, struct module *owner) ··· 1822 1811 return -EOPNOTSUPP; 1823 1812 } 1824 1813 static inline void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struct bpf_map *map) 1814 + { 1815 + } 1816 + 1817 + static inline void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc) 1825 1818 { 1826 1819 } 1827 1820
+28 -2
include/linux/bpf_local_storage.h
··· 129 129 struct bpf_local_storage_cache *cache, 130 130 bool bpf_ma); 131 131 132 - struct bpf_local_storage_data * 132 + void __bpf_local_storage_insert_cache(struct bpf_local_storage *local_storage, 133 + struct bpf_local_storage_map *smap, 134 + struct bpf_local_storage_elem *selem); 135 + /* If cacheit_lockit is false, this lookup function is lockless */ 136 + static inline struct bpf_local_storage_data * 133 137 bpf_local_storage_lookup(struct bpf_local_storage *local_storage, 134 138 struct bpf_local_storage_map *smap, 135 - bool cacheit_lockit); 139 + bool cacheit_lockit) 140 + { 141 + struct bpf_local_storage_data *sdata; 142 + struct bpf_local_storage_elem *selem; 143 + 144 + /* Fast path (cache hit) */ 145 + sdata = rcu_dereference_check(local_storage->cache[smap->cache_idx], 146 + bpf_rcu_lock_held()); 147 + if (sdata && rcu_access_pointer(sdata->smap) == smap) 148 + return sdata; 149 + 150 + /* Slow path (cache miss) */ 151 + hlist_for_each_entry_rcu(selem, &local_storage->list, snode, 152 + rcu_read_lock_trace_held()) 153 + if (rcu_access_pointer(SDATA(selem)->smap) == smap) 154 + break; 155 + 156 + if (!selem) 157 + return NULL; 158 + if (cacheit_lockit) 159 + __bpf_local_storage_insert_cache(local_storage, smap, selem); 160 + return SDATA(selem); 161 + } 136 162 137 163 void bpf_local_storage_destroy(struct bpf_local_storage *local_storage); 138 164
+10
include/linux/bpf_verifier.h
··· 610 610 enum bpf_arg_type arg_type; 611 611 union { 612 612 u32 mem_size; 613 + u32 btf_id; 613 614 }; 614 615 }; 615 616 ··· 917 916 { 918 917 env->scratched_regs = ~0U; 919 918 env->scratched_stack_slots = ~0ULL; 919 + } 920 + 921 + static inline bool bpf_stack_narrow_access_ok(int off, int fill_size, int spill_size) 922 + { 923 + #ifdef __BIG_ENDIAN 924 + off -= spill_size - fill_size; 925 + #endif 926 + 927 + return !(off % BPF_REG_SIZE); 920 928 } 921 929 922 930 const char *reg_type_str(struct bpf_verifier_env *env, enum bpf_reg_type type);
+14 -9
include/linux/btf.h
··· 495 495 return bsearch(&id, set->pairs, set->cnt, sizeof(set->pairs[0]), btf_id_cmp_func); 496 496 } 497 497 498 + bool btf_param_match_suffix(const struct btf *btf, 499 + const struct btf_param *arg, 500 + const char *suffix); 501 + int btf_ctx_arg_offset(const struct btf *btf, const struct btf_type *func_proto, 502 + u32 arg_no); 503 + 498 504 struct bpf_verifier_log; 499 505 500 506 #if defined(CONFIG_BPF_JIT) && defined(CONFIG_BPF_SYSCALL) ··· 531 525 int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_cnt, 532 526 struct module *owner); 533 527 struct btf_struct_meta *btf_find_struct_meta(const struct btf *btf, u32 btf_id); 534 - const struct btf_type * 535 - btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, 536 - const struct btf_type *t, enum bpf_prog_type prog_type, 537 - int arg); 528 + bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, 529 + const struct btf_type *t, enum bpf_prog_type prog_type, 530 + int arg); 538 531 int get_kern_ctx_btf_id(struct bpf_verifier_log *log, enum bpf_prog_type prog_type); 539 532 bool btf_types_are_same(const struct btf *btf1, u32 id1, 540 533 const struct btf *btf2, u32 id2); ··· 573 568 { 574 569 return NULL; 575 570 } 576 - static inline const struct btf_member * 577 - btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, 578 - const struct btf_type *t, enum bpf_prog_type prog_type, 579 - int arg) 571 + static inline bool 572 + btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, 573 + const struct btf_type *t, enum bpf_prog_type prog_type, 574 + int arg) 580 575 { 581 - return NULL; 576 + return false; 582 577 } 583 578 static inline int get_kern_ctx_btf_id(struct bpf_verifier_log *log, 584 579 enum bpf_prog_type prog_type) {
+17 -4
include/linux/btf_ids.h
··· 8 8 u32 ids[]; 9 9 }; 10 10 11 + /* This flag implies BTF_SET8 holds kfunc(s) */ 12 + #define BTF_SET8_KFUNCS (1 << 0) 13 + 11 14 struct btf_id_set8 { 12 15 u32 cnt; 13 16 u32 flags; ··· 24 21 25 22 #include <linux/compiler.h> /* for __PASTE */ 26 23 #include <linux/compiler_attributes.h> /* for __maybe_unused */ 24 + #include <linux/stringify.h> 27 25 28 26 /* 29 27 * Following macros help to define lists of BTF IDs placed ··· 187 183 * .word (1 << 3) | (1 << 1) | (1 << 2) 188 184 * 189 185 */ 190 - #define __BTF_SET8_START(name, scope) \ 186 + #define __BTF_SET8_START(name, scope, flags) \ 187 + __BTF_ID_LIST(name, local) \ 191 188 asm( \ 192 189 ".pushsection " BTF_IDS_SECTION ",\"a\"; \n" \ 193 190 "." #scope " __BTF_ID__set8__" #name "; \n" \ 194 191 "__BTF_ID__set8__" #name ":; \n" \ 195 - ".zero 8 \n" \ 192 + ".zero 4 \n" \ 193 + ".long " __stringify(flags) "\n" \ 196 194 ".popsection; \n"); 197 195 198 196 #define BTF_SET8_START(name) \ 199 - __BTF_ID_LIST(name, local) \ 200 - __BTF_SET8_START(name, local) 197 + __BTF_SET8_START(name, local, 0) 201 198 202 199 #define BTF_SET8_END(name) \ 203 200 asm( \ ··· 206 201 ".size __BTF_ID__set8__" #name ", .-" #name " \n" \ 207 202 ".popsection; \n"); \ 208 203 extern struct btf_id_set8 name; 204 + 205 + #define BTF_KFUNCS_START(name) \ 206 + __BTF_SET8_START(name, local, BTF_SET8_KFUNCS) 207 + 208 + #define BTF_KFUNCS_END(name) \ 209 + BTF_SET8_END(name) 209 210 210 211 #else 211 212 ··· 227 216 #define BTF_SET_END(name) 228 217 #define BTF_SET8_START(name) static struct btf_id_set8 __maybe_unused name = { 0 }; 229 218 #define BTF_SET8_END(name) 219 + #define BTF_KFUNCS_START(name) static struct btf_id_set8 __maybe_unused name = { .flags = BTF_SET8_KFUNCS }; 220 + #define BTF_KFUNCS_END(name) 230 221 231 222 #endif /* CONFIG_DEBUG_INFO_BTF */ 232 223
+12 -9
include/linux/filter.h
··· 547 547 __BPF_MAP(n, __BPF_DECL_ARGS, __BPF_N, u64, __ur_1, u64, __ur_2, \ 548 548 u64, __ur_3, u64, __ur_4, u64, __ur_5) 549 549 550 - #define BPF_CALL_x(x, name, ...) \ 550 + #define BPF_CALL_x(x, attr, name, ...) \ 551 551 static __always_inline \ 552 552 u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ 553 553 typedef u64 (*btf_##name)(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)); \ 554 - u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \ 555 - u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \ 554 + attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)); \ 555 + attr u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__)) \ 556 556 { \ 557 557 return ((btf_##name)____##name)(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\ 558 558 } \ 559 559 static __always_inline \ 560 560 u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__)) 561 561 562 - #define BPF_CALL_0(name, ...) BPF_CALL_x(0, name, __VA_ARGS__) 563 - #define BPF_CALL_1(name, ...) BPF_CALL_x(1, name, __VA_ARGS__) 564 - #define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__) 565 - #define BPF_CALL_3(name, ...) BPF_CALL_x(3, name, __VA_ARGS__) 566 - #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__) 567 - #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__) 562 + #define __NOATTR 563 + #define BPF_CALL_0(name, ...) BPF_CALL_x(0, __NOATTR, name, __VA_ARGS__) 564 + #define BPF_CALL_1(name, ...) BPF_CALL_x(1, __NOATTR, name, __VA_ARGS__) 565 + #define BPF_CALL_2(name, ...) BPF_CALL_x(2, __NOATTR, name, __VA_ARGS__) 566 + #define BPF_CALL_3(name, ...) BPF_CALL_x(3, __NOATTR, name, __VA_ARGS__) 567 + #define BPF_CALL_4(name, ...) BPF_CALL_x(4, __NOATTR, name, __VA_ARGS__) 568 + #define BPF_CALL_5(name, ...) BPF_CALL_x(5, __NOATTR, name, __VA_ARGS__) 569 + 570 + #define NOTRACE_BPF_CALL_1(name, ...) BPF_CALL_x(1, notrace, name, __VA_ARGS__) 568 571 569 572 #define bpf_ctx_range(TYPE, MEMBER) \ 570 573 offsetof(TYPE, MEMBER) ... offsetofend(TYPE, MEMBER) - 1
+23 -2
include/uapi/linux/bpf.h
··· 77 77 __s32 imm; /* signed immediate constant */ 78 78 }; 79 79 80 - /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ 80 + /* Deprecated: use struct bpf_lpm_trie_key_u8 (when the "data" member is needed for 81 + * byte access) or struct bpf_lpm_trie_key_hdr (when using an alternative type for 82 + * the trailing flexible array member) instead. 83 + */ 81 84 struct bpf_lpm_trie_key { 82 85 __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ 83 86 __u8 data[0]; /* Arbitrary size */ 87 + }; 88 + 89 + /* Header for bpf_lpm_trie_key structs */ 90 + struct bpf_lpm_trie_key_hdr { 91 + __u32 prefixlen; 92 + }; 93 + 94 + /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry, with trailing byte array. */ 95 + struct bpf_lpm_trie_key_u8 { 96 + union { 97 + struct bpf_lpm_trie_key_hdr hdr; 98 + __u32 prefixlen; 99 + }; 100 + __u8 data[]; /* Arbitrary size */ 84 101 }; 85 102 86 103 struct bpf_cgroup_storage_key { ··· 634 617 * to NULL to begin the batched operation. After each subsequent 635 618 * **BPF_MAP_LOOKUP_BATCH**, the caller should pass the resultant 636 619 * *out_batch* as the *in_batch* for the next operation to 637 - * continue iteration from the current point. 620 + * continue iteration from the current point. Both *in_batch* and 621 + * *out_batch* must point to memory large enough to hold a key, 622 + * except for maps of type **BPF_MAP_TYPE_{HASH, PERCPU_HASH, 623 + * LRU_HASH, LRU_PERCPU_HASH}**, for which batch parameters 624 + * must be at least 4 bytes wide regardless of key size. 638 625 * 639 626 * The *keys* and *values* are output parameters which must point 640 627 * to memory large enough to hold *count* items based on the key
-5
init/Kconfig
··· 1466 1466 config HAVE_PCSPKR_PLATFORM 1467 1467 bool 1468 1468 1469 - # interpreter that classic socket filters depend on 1470 - config BPF 1471 - bool 1472 - select CRYPTO_LIB_SHA1 1473 - 1474 1469 menuconfig EXPERT 1475 1470 bool "Configure standard kernel features (expert users)" 1476 1471 # Unhide debug options, to make the on-by-default options visible
+1
kernel/bpf/Kconfig
··· 3 3 # BPF interpreter that, for example, classic socket filters depend on. 4 4 config BPF 5 5 bool 6 + select CRYPTO_LIB_SHA1 6 7 7 8 # Used by archs to tell that they support BPF JIT compiler plus which 8 9 # flavour. Only one of the two can be selected for a specific arch since
+13 -39
kernel/bpf/bpf_local_storage.c
··· 414 414 bpf_selem_unlink_storage(selem, reuse_now); 415 415 } 416 416 417 - /* If cacheit_lockit is false, this lookup function is lockless */ 418 - struct bpf_local_storage_data * 419 - bpf_local_storage_lookup(struct bpf_local_storage *local_storage, 420 - struct bpf_local_storage_map *smap, 421 - bool cacheit_lockit) 417 + void __bpf_local_storage_insert_cache(struct bpf_local_storage *local_storage, 418 + struct bpf_local_storage_map *smap, 419 + struct bpf_local_storage_elem *selem) 422 420 { 423 - struct bpf_local_storage_data *sdata; 424 - struct bpf_local_storage_elem *selem; 421 + unsigned long flags; 425 422 426 - /* Fast path (cache hit) */ 427 - sdata = rcu_dereference_check(local_storage->cache[smap->cache_idx], 428 - bpf_rcu_lock_held()); 429 - if (sdata && rcu_access_pointer(sdata->smap) == smap) 430 - return sdata; 431 - 432 - /* Slow path (cache miss) */ 433 - hlist_for_each_entry_rcu(selem, &local_storage->list, snode, 434 - rcu_read_lock_trace_held()) 435 - if (rcu_access_pointer(SDATA(selem)->smap) == smap) 436 - break; 437 - 438 - if (!selem) 439 - return NULL; 440 - 441 - sdata = SDATA(selem); 442 - if (cacheit_lockit) { 443 - unsigned long flags; 444 - 445 - /* spinlock is needed to avoid racing with the 446 - * parallel delete. Otherwise, publishing an already 447 - * deleted sdata to the cache will become a use-after-free 448 - * problem in the next bpf_local_storage_lookup(). 449 - */ 450 - raw_spin_lock_irqsave(&local_storage->lock, flags); 451 - if (selem_linked_to_storage(selem)) 452 - rcu_assign_pointer(local_storage->cache[smap->cache_idx], 453 - sdata); 454 - raw_spin_unlock_irqrestore(&local_storage->lock, flags); 455 - } 456 - 457 - return sdata; 423 + /* spinlock is needed to avoid racing with the 424 + * parallel delete. Otherwise, publishing an already 425 + * deleted sdata to the cache will become a use-after-free 426 + * problem in the next bpf_local_storage_lookup(). 427 + */ 428 + raw_spin_lock_irqsave(&local_storage->lock, flags); 429 + if (selem_linked_to_storage(selem)) 430 + rcu_assign_pointer(local_storage->cache[smap->cache_idx], SDATA(selem)); 431 + raw_spin_unlock_irqrestore(&local_storage->lock, flags); 458 432 } 459 433 460 434 static int check_flags(const struct bpf_local_storage_data *old_sdata,
+2 -4
kernel/bpf/bpf_lsm.c
··· 282 282 BTF_ID(func, bpf_lsm_file_open) 283 283 BTF_ID(func, bpf_lsm_file_receive) 284 284 285 - #ifdef CONFIG_SECURITY_NETWORK 286 - BTF_ID(func, bpf_lsm_inet_conn_established) 287 - #endif /* CONFIG_SECURITY_NETWORK */ 288 - 289 285 BTF_ID(func, bpf_lsm_inode_create) 290 286 BTF_ID(func, bpf_lsm_inode_free_security) 291 287 BTF_ID(func, bpf_lsm_inode_getattr) ··· 332 336 BTF_ID(func, bpf_lsm_settime) 333 337 334 338 #ifdef CONFIG_SECURITY_NETWORK 339 + BTF_ID(func, bpf_lsm_inet_conn_established) 340 + 335 341 BTF_ID(func, bpf_lsm_socket_accept) 336 342 BTF_ID(func, bpf_lsm_socket_bind) 337 343 BTF_ID(func, bpf_lsm_socket_connect)
+209 -18
kernel/bpf/bpf_struct_ops.c
··· 116 116 return true; 117 117 } 118 118 119 + #define MAYBE_NULL_SUFFIX "__nullable" 120 + #define MAX_STUB_NAME 128 121 + 122 + /* Return the type info of a stub function, if it exists. 123 + * 124 + * The name of a stub function is made up of the name of the struct_ops and 125 + * the name of the function pointer member, separated by "__". For example, 126 + * if the struct_ops type is named "foo_ops" and the function pointer 127 + * member is named "bar", the stub function name would be "foo_ops__bar". 128 + */ 129 + static const struct btf_type * 130 + find_stub_func_proto(const struct btf *btf, const char *st_op_name, 131 + const char *member_name) 132 + { 133 + char stub_func_name[MAX_STUB_NAME]; 134 + const struct btf_type *func_type; 135 + s32 btf_id; 136 + int cp; 137 + 138 + cp = snprintf(stub_func_name, MAX_STUB_NAME, "%s__%s", 139 + st_op_name, member_name); 140 + if (cp >= MAX_STUB_NAME) { 141 + pr_warn("Stub function name too long\n"); 142 + return NULL; 143 + } 144 + btf_id = btf_find_by_name_kind(btf, stub_func_name, BTF_KIND_FUNC); 145 + if (btf_id < 0) 146 + return NULL; 147 + func_type = btf_type_by_id(btf, btf_id); 148 + if (!func_type) 149 + return NULL; 150 + 151 + return btf_type_by_id(btf, func_type->type); /* FUNC_PROTO */ 152 + } 153 + 154 + /* Prepare argument info for every nullable argument of a member of a 155 + * struct_ops type. 156 + * 157 + * Initialize a struct bpf_struct_ops_arg_info according to type info of 158 + * the arguments of a stub function. (Check kCFI for more information about 159 + * stub functions.) 160 + * 161 + * Each member in the struct_ops type has a struct bpf_struct_ops_arg_info 162 + * to provide an array of struct bpf_ctx_arg_aux, which in turn provides 163 + * the information that used by the verifier to check the arguments of the 164 + * BPF struct_ops program assigned to the member. Here, we only care about 165 + * the arguments that are marked as __nullable. 166 + * 167 + * The array of struct bpf_ctx_arg_aux is eventually assigned to 168 + * prog->aux->ctx_arg_info of BPF struct_ops programs and passed to the 169 + * verifier. (See check_struct_ops_btf_id()) 170 + * 171 + * arg_info->info will be the list of struct bpf_ctx_arg_aux if success. If 172 + * fails, it will be kept untouched. 173 + */ 174 + static int prepare_arg_info(struct btf *btf, 175 + const char *st_ops_name, 176 + const char *member_name, 177 + const struct btf_type *func_proto, 178 + struct bpf_struct_ops_arg_info *arg_info) 179 + { 180 + const struct btf_type *stub_func_proto, *pointed_type; 181 + const struct btf_param *stub_args, *args; 182 + struct bpf_ctx_arg_aux *info, *info_buf; 183 + u32 nargs, arg_no, info_cnt = 0; 184 + u32 arg_btf_id; 185 + int offset; 186 + 187 + stub_func_proto = find_stub_func_proto(btf, st_ops_name, member_name); 188 + if (!stub_func_proto) 189 + return 0; 190 + 191 + /* Check if the number of arguments of the stub function is the same 192 + * as the number of arguments of the function pointer. 193 + */ 194 + nargs = btf_type_vlen(func_proto); 195 + if (nargs != btf_type_vlen(stub_func_proto)) { 196 + pr_warn("the number of arguments of the stub function %s__%s does not match the number of arguments of the member %s of struct %s\n", 197 + st_ops_name, member_name, member_name, st_ops_name); 198 + return -EINVAL; 199 + } 200 + 201 + if (!nargs) 202 + return 0; 203 + 204 + args = btf_params(func_proto); 205 + stub_args = btf_params(stub_func_proto); 206 + 207 + info_buf = kcalloc(nargs, sizeof(*info_buf), GFP_KERNEL); 208 + if (!info_buf) 209 + return -ENOMEM; 210 + 211 + /* Prepare info for every nullable argument */ 212 + info = info_buf; 213 + for (arg_no = 0; arg_no < nargs; arg_no++) { 214 + /* Skip arguments that is not suffixed with 215 + * "__nullable". 216 + */ 217 + if (!btf_param_match_suffix(btf, &stub_args[arg_no], 218 + MAYBE_NULL_SUFFIX)) 219 + continue; 220 + 221 + /* Should be a pointer to struct */ 222 + pointed_type = btf_type_resolve_ptr(btf, 223 + args[arg_no].type, 224 + &arg_btf_id); 225 + if (!pointed_type || 226 + !btf_type_is_struct(pointed_type)) { 227 + pr_warn("stub function %s__%s has %s tagging to an unsupported type\n", 228 + st_ops_name, member_name, MAYBE_NULL_SUFFIX); 229 + goto err_out; 230 + } 231 + 232 + offset = btf_ctx_arg_offset(btf, func_proto, arg_no); 233 + if (offset < 0) { 234 + pr_warn("stub function %s__%s has an invalid trampoline ctx offset for arg#%u\n", 235 + st_ops_name, member_name, arg_no); 236 + goto err_out; 237 + } 238 + 239 + if (args[arg_no].type != stub_args[arg_no].type) { 240 + pr_warn("arg#%u type in stub function %s__%s does not match with its original func_proto\n", 241 + arg_no, st_ops_name, member_name); 242 + goto err_out; 243 + } 244 + 245 + /* Fill the information of the new argument */ 246 + info->reg_type = 247 + PTR_TRUSTED | PTR_TO_BTF_ID | PTR_MAYBE_NULL; 248 + info->btf_id = arg_btf_id; 249 + info->btf = btf; 250 + info->offset = offset; 251 + 252 + info++; 253 + info_cnt++; 254 + } 255 + 256 + if (info_cnt) { 257 + arg_info->info = info_buf; 258 + arg_info->cnt = info_cnt; 259 + } else { 260 + kfree(info_buf); 261 + } 262 + 263 + return 0; 264 + 265 + err_out: 266 + kfree(info_buf); 267 + 268 + return -EINVAL; 269 + } 270 + 271 + /* Clean up the arg_info in a struct bpf_struct_ops_desc. */ 272 + void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc) 273 + { 274 + struct bpf_struct_ops_arg_info *arg_info; 275 + int i; 276 + 277 + arg_info = st_ops_desc->arg_info; 278 + for (i = 0; i < btf_type_vlen(st_ops_desc->type); i++) 279 + kfree(arg_info[i].info); 280 + 281 + kfree(arg_info); 282 + } 283 + 119 284 int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc, 120 285 struct btf *btf, 121 286 struct bpf_verifier_log *log) 122 287 { 123 288 struct bpf_struct_ops *st_ops = st_ops_desc->st_ops; 289 + struct bpf_struct_ops_arg_info *arg_info; 124 290 const struct btf_member *member; 125 291 const struct btf_type *t; 126 292 s32 type_id, value_id; 127 293 char value_name[128]; 128 294 const char *mname; 129 - int i; 295 + int i, err; 130 296 131 297 if (strlen(st_ops->name) + VALUE_PREFIX_LEN >= 132 298 sizeof(value_name)) { ··· 301 135 return -EINVAL; 302 136 } 303 137 sprintf(value_name, "%s%s", VALUE_PREFIX, st_ops->name); 138 + 139 + if (!st_ops->cfi_stubs) { 140 + pr_warn("struct_ops for %s has no cfi_stubs\n", st_ops->name); 141 + return -EINVAL; 142 + } 304 143 305 144 type_id = btf_find_by_name_kind(btf, st_ops->name, 306 145 BTF_KIND_STRUCT); ··· 331 160 if (!is_valid_value_type(btf, value_id, t, value_name)) 332 161 return -EINVAL; 333 162 163 + arg_info = kcalloc(btf_type_vlen(t), sizeof(*arg_info), 164 + GFP_KERNEL); 165 + if (!arg_info) 166 + return -ENOMEM; 167 + 168 + st_ops_desc->arg_info = arg_info; 169 + st_ops_desc->type = t; 170 + st_ops_desc->type_id = type_id; 171 + st_ops_desc->value_id = value_id; 172 + st_ops_desc->value_type = btf_type_by_id(btf, value_id); 173 + 334 174 for_each_member(i, t, member) { 335 175 const struct btf_type *func_proto; 336 176 ··· 349 167 if (!*mname) { 350 168 pr_warn("anon member in struct %s is not supported\n", 351 169 st_ops->name); 352 - return -EOPNOTSUPP; 170 + err = -EOPNOTSUPP; 171 + goto errout; 353 172 } 354 173 355 174 if (__btf_member_bitfield_size(t, member)) { 356 175 pr_warn("bit field member %s in struct %s is not supported\n", 357 176 mname, st_ops->name); 358 - return -EOPNOTSUPP; 177 + err = -EOPNOTSUPP; 178 + goto errout; 359 179 } 360 180 361 181 func_proto = btf_type_resolve_func_ptr(btf, 362 182 member->type, 363 183 NULL); 364 - if (func_proto && 365 - btf_distill_func_proto(log, btf, 184 + if (!func_proto) 185 + continue; 186 + 187 + if (btf_distill_func_proto(log, btf, 366 188 func_proto, mname, 367 189 &st_ops->func_models[i])) { 368 190 pr_warn("Error in parsing func ptr %s in struct %s\n", 369 191 mname, st_ops->name); 370 - return -EINVAL; 192 + err = -EINVAL; 193 + goto errout; 371 194 } 195 + 196 + err = prepare_arg_info(btf, st_ops->name, mname, 197 + func_proto, 198 + arg_info + i); 199 + if (err) 200 + goto errout; 372 201 } 373 202 374 - if (i == btf_type_vlen(t)) { 375 - if (st_ops->init(btf)) { 376 - pr_warn("Error in init bpf_struct_ops %s\n", 377 - st_ops->name); 378 - return -EINVAL; 379 - } else { 380 - st_ops_desc->type_id = type_id; 381 - st_ops_desc->type = t; 382 - st_ops_desc->value_id = value_id; 383 - st_ops_desc->value_type = btf_type_by_id(btf, 384 - value_id); 385 - } 203 + if (st_ops->init(btf)) { 204 + pr_warn("Error in init bpf_struct_ops %s\n", 205 + st_ops->name); 206 + err = -EINVAL; 207 + goto errout; 386 208 } 387 209 388 210 return 0; 211 + 212 + errout: 213 + bpf_struct_ops_desc_release(st_ops_desc); 214 + 215 + return err; 389 216 } 390 217 391 218 static int bpf_struct_ops_map_get_next_key(struct bpf_map *map, void *key,
+209 -66
kernel/bpf/btf.c
··· 1699 1699 static void btf_free_struct_ops_tab(struct btf *btf) 1700 1700 { 1701 1701 struct btf_struct_ops_tab *tab = btf->struct_ops_tab; 1702 + u32 i; 1703 + 1704 + if (!tab) 1705 + return; 1706 + 1707 + for (i = 0; i < tab->cnt; i++) 1708 + bpf_struct_ops_desc_release(&tab->ops[i]); 1702 1709 1703 1710 kfree(tab); 1704 1711 btf->struct_ops_tab = NULL; ··· 5694 5687 return ctx_type->type; 5695 5688 } 5696 5689 5697 - const struct btf_type * 5698 - btf_get_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, 5699 - const struct btf_type *t, enum bpf_prog_type prog_type, 5700 - int arg) 5690 + bool btf_is_prog_ctx_type(struct bpf_verifier_log *log, const struct btf *btf, 5691 + const struct btf_type *t, enum bpf_prog_type prog_type, 5692 + int arg) 5701 5693 { 5702 5694 const struct btf_type *ctx_type; 5703 5695 const char *tname, *ctx_tname; 5704 5696 5705 5697 t = btf_type_by_id(btf, t->type); 5698 + 5699 + /* KPROBE programs allow bpf_user_pt_regs_t typedef, which we need to 5700 + * check before we skip all the typedef below. 5701 + */ 5702 + if (prog_type == BPF_PROG_TYPE_KPROBE) { 5703 + while (btf_type_is_modifier(t) && !btf_type_is_typedef(t)) 5704 + t = btf_type_by_id(btf, t->type); 5705 + 5706 + if (btf_type_is_typedef(t)) { 5707 + tname = btf_name_by_offset(btf, t->name_off); 5708 + if (tname && strcmp(tname, "bpf_user_pt_regs_t") == 0) 5709 + return true; 5710 + } 5711 + } 5712 + 5706 5713 while (btf_type_is_modifier(t)) 5707 5714 t = btf_type_by_id(btf, t->type); 5708 5715 if (!btf_type_is_struct(t)) { ··· 5725 5704 * is not supported yet. 5726 5705 * BPF_PROG_TYPE_RAW_TRACEPOINT is fine. 5727 5706 */ 5728 - return NULL; 5707 + return false; 5729 5708 } 5730 5709 tname = btf_name_by_offset(btf, t->name_off); 5731 5710 if (!tname) { 5732 5711 bpf_log(log, "arg#%d struct doesn't have a name\n", arg); 5733 - return NULL; 5712 + return false; 5734 5713 } 5735 5714 5736 5715 ctx_type = find_canonical_prog_ctx_type(prog_type); 5737 5716 if (!ctx_type) { 5738 5717 bpf_log(log, "btf_vmlinux is malformed\n"); 5739 5718 /* should not happen */ 5740 - return NULL; 5719 + return false; 5741 5720 } 5742 5721 again: 5743 5722 ctx_tname = btf_name_by_offset(btf_vmlinux, ctx_type->name_off); 5744 5723 if (!ctx_tname) { 5745 5724 /* should not happen */ 5746 5725 bpf_log(log, "Please fix kernel include/linux/bpf_types.h\n"); 5747 - return NULL; 5726 + return false; 5748 5727 } 5728 + /* program types without named context types work only with arg:ctx tag */ 5729 + if (ctx_tname[0] == '\0') 5730 + return false; 5749 5731 /* only compare that prog's ctx type name is the same as 5750 5732 * kernel expects. No need to compare field by field. 5751 5733 * It's ok for bpf prog to do: ··· 5757 5733 * { // no fields of skb are ever used } 5758 5734 */ 5759 5735 if (strcmp(ctx_tname, "__sk_buff") == 0 && strcmp(tname, "sk_buff") == 0) 5760 - return ctx_type; 5736 + return true; 5761 5737 if (strcmp(ctx_tname, "xdp_md") == 0 && strcmp(tname, "xdp_buff") == 0) 5762 - return ctx_type; 5738 + return true; 5763 5739 if (strcmp(ctx_tname, tname)) { 5764 5740 /* bpf_user_pt_regs_t is a typedef, so resolve it to 5765 5741 * underlying struct and check name again 5766 5742 */ 5767 5743 if (!btf_type_is_modifier(ctx_type)) 5768 - return NULL; 5744 + return false; 5769 5745 while (btf_type_is_modifier(ctx_type)) 5770 5746 ctx_type = btf_type_by_id(btf_vmlinux, ctx_type->type); 5771 5747 goto again; 5772 5748 } 5773 - return ctx_type; 5749 + return true; 5774 5750 } 5775 5751 5776 5752 /* forward declarations for arch-specific underlying types of ··· 5922 5898 enum bpf_prog_type prog_type, 5923 5899 int arg) 5924 5900 { 5925 - if (!btf_get_prog_ctx_type(log, btf, t, prog_type, arg)) 5901 + if (!btf_is_prog_ctx_type(log, btf, t, prog_type, arg)) 5926 5902 return -ENOENT; 5927 5903 return find_kern_ctx_type_id(prog_type); 5928 5904 } ··· 6154 6130 } 6155 6131 } 6156 6132 6133 + int btf_ctx_arg_offset(const struct btf *btf, const struct btf_type *func_proto, 6134 + u32 arg_no) 6135 + { 6136 + const struct btf_param *args; 6137 + const struct btf_type *t; 6138 + int off = 0, i; 6139 + u32 sz; 6140 + 6141 + args = btf_params(func_proto); 6142 + for (i = 0; i < arg_no; i++) { 6143 + t = btf_type_by_id(btf, args[i].type); 6144 + t = btf_resolve_size(btf, t, &sz); 6145 + if (IS_ERR(t)) 6146 + return PTR_ERR(t); 6147 + off += roundup(sz, 8); 6148 + } 6149 + 6150 + return off; 6151 + } 6152 + 6157 6153 bool btf_ctx_access(int off, int size, enum bpf_access_type type, 6158 6154 const struct bpf_prog *prog, 6159 6155 struct bpf_insn_access_aux *info) ··· 6310 6266 } 6311 6267 6312 6268 info->reg_type = ctx_arg_info->reg_type; 6313 - info->btf = btf_vmlinux; 6269 + info->btf = ctx_arg_info->btf ? : btf_vmlinux; 6314 6270 info->btf_id = ctx_arg_info->btf_id; 6315 6271 return true; 6316 6272 } ··· 7029 6985 return false; 7030 6986 } 7031 6987 6988 + struct bpf_cand_cache { 6989 + const char *name; 6990 + u32 name_len; 6991 + u16 kind; 6992 + u16 cnt; 6993 + struct { 6994 + const struct btf *btf; 6995 + u32 id; 6996 + } cands[]; 6997 + }; 6998 + 6999 + static DEFINE_MUTEX(cand_cache_mutex); 7000 + 7001 + static struct bpf_cand_cache * 7002 + bpf_core_find_cands(struct bpf_core_ctx *ctx, u32 local_type_id); 7003 + 7004 + static int btf_get_ptr_to_btf_id(struct bpf_verifier_log *log, int arg_idx, 7005 + const struct btf *btf, const struct btf_type *t) 7006 + { 7007 + struct bpf_cand_cache *cc; 7008 + struct bpf_core_ctx ctx = { 7009 + .btf = btf, 7010 + .log = log, 7011 + }; 7012 + u32 kern_type_id, type_id; 7013 + int err = 0; 7014 + 7015 + /* skip PTR and modifiers */ 7016 + type_id = t->type; 7017 + t = btf_type_by_id(btf, t->type); 7018 + while (btf_type_is_modifier(t)) { 7019 + type_id = t->type; 7020 + t = btf_type_by_id(btf, t->type); 7021 + } 7022 + 7023 + mutex_lock(&cand_cache_mutex); 7024 + cc = bpf_core_find_cands(&ctx, type_id); 7025 + if (IS_ERR(cc)) { 7026 + err = PTR_ERR(cc); 7027 + bpf_log(log, "arg#%d reference type('%s %s') candidate matching error: %d\n", 7028 + arg_idx, btf_type_str(t), __btf_name_by_offset(btf, t->name_off), 7029 + err); 7030 + goto cand_cache_unlock; 7031 + } 7032 + if (cc->cnt != 1) { 7033 + bpf_log(log, "arg#%d reference type('%s %s') %s\n", 7034 + arg_idx, btf_type_str(t), __btf_name_by_offset(btf, t->name_off), 7035 + cc->cnt == 0 ? "has no matches" : "is ambiguous"); 7036 + err = cc->cnt == 0 ? -ENOENT : -ESRCH; 7037 + goto cand_cache_unlock; 7038 + } 7039 + if (btf_is_module(cc->cands[0].btf)) { 7040 + bpf_log(log, "arg#%d reference type('%s %s') points to kernel module type (unsupported)\n", 7041 + arg_idx, btf_type_str(t), __btf_name_by_offset(btf, t->name_off)); 7042 + err = -EOPNOTSUPP; 7043 + goto cand_cache_unlock; 7044 + } 7045 + kern_type_id = cc->cands[0].id; 7046 + 7047 + cand_cache_unlock: 7048 + mutex_unlock(&cand_cache_mutex); 7049 + if (err) 7050 + return err; 7051 + 7052 + return kern_type_id; 7053 + } 7054 + 7032 7055 enum btf_arg_tag { 7033 7056 ARG_TAG_CTX = 0x1, 7034 7057 ARG_TAG_NONNULL = 0x2, 7058 + ARG_TAG_TRUSTED = 0x4, 7059 + ARG_TAG_NULLABLE = 0x8, 7035 7060 }; 7036 7061 7037 7062 /* Process BTF of a function to produce high-level expectation of function ··· 7166 7053 args = (const struct btf_param *)(t + 1); 7167 7054 nargs = btf_type_vlen(t); 7168 7055 if (nargs > MAX_BPF_FUNC_REG_ARGS) { 7056 + if (!is_global) 7057 + return -EINVAL; 7169 7058 bpf_log(log, "Global function %s() with %d > %d args. Buggy compiler.\n", 7170 7059 tname, nargs, MAX_BPF_FUNC_REG_ARGS); 7171 7060 return -EINVAL; ··· 7177 7062 while (btf_type_is_modifier(t)) 7178 7063 t = btf_type_by_id(btf, t->type); 7179 7064 if (!btf_type_is_int(t) && !btf_is_any_enum(t)) { 7065 + if (!is_global) 7066 + return -EINVAL; 7180 7067 bpf_log(log, 7181 7068 "Global function %s() doesn't return scalar. Only those are supported.\n", 7182 7069 tname); ··· 7206 7089 7207 7090 if (strcmp(tag, "ctx") == 0) { 7208 7091 tags |= ARG_TAG_CTX; 7092 + } else if (strcmp(tag, "trusted") == 0) { 7093 + tags |= ARG_TAG_TRUSTED; 7209 7094 } else if (strcmp(tag, "nonnull") == 0) { 7210 7095 tags |= ARG_TAG_NONNULL; 7096 + } else if (strcmp(tag, "nullable") == 0) { 7097 + tags |= ARG_TAG_NULLABLE; 7211 7098 } else { 7212 7099 bpf_log(log, "arg#%d has unsupported set of tags\n", i); 7213 7100 return -EOPNOTSUPP; ··· 7228 7107 if (!btf_type_is_ptr(t)) 7229 7108 goto skip_pointer; 7230 7109 7231 - if ((tags & ARG_TAG_CTX) || btf_get_prog_ctx_type(log, btf, t, prog_type, i)) { 7110 + if ((tags & ARG_TAG_CTX) || btf_is_prog_ctx_type(log, btf, t, prog_type, i)) { 7232 7111 if (tags & ~ARG_TAG_CTX) { 7233 7112 bpf_log(log, "arg#%d has invalid combination of tags\n", i); 7234 7113 return -EINVAL; 7235 7114 } 7115 + if ((tags & ARG_TAG_CTX) && 7116 + btf_validate_prog_ctx_type(log, btf, t, i, prog_type, 7117 + prog->expected_attach_type)) 7118 + return -EINVAL; 7236 7119 sub->args[i].arg_type = ARG_PTR_TO_CTX; 7237 7120 continue; 7238 7121 } ··· 7248 7123 sub->args[i].arg_type = ARG_PTR_TO_DYNPTR | MEM_RDONLY; 7249 7124 continue; 7250 7125 } 7126 + if (tags & ARG_TAG_TRUSTED) { 7127 + int kern_type_id; 7128 + 7129 + if (tags & ARG_TAG_NONNULL) { 7130 + bpf_log(log, "arg#%d has invalid combination of tags\n", i); 7131 + return -EINVAL; 7132 + } 7133 + 7134 + kern_type_id = btf_get_ptr_to_btf_id(log, i, btf, t); 7135 + if (kern_type_id < 0) 7136 + return kern_type_id; 7137 + 7138 + sub->args[i].arg_type = ARG_PTR_TO_BTF_ID | PTR_TRUSTED; 7139 + if (tags & ARG_TAG_NULLABLE) 7140 + sub->args[i].arg_type |= PTR_MAYBE_NULL; 7141 + sub->args[i].btf_id = kern_type_id; 7142 + continue; 7143 + } 7251 7144 if (is_global) { /* generic user data pointer */ 7252 7145 u32 mem_size; 7146 + 7147 + if (tags & ARG_TAG_NULLABLE) { 7148 + bpf_log(log, "arg#%d has invalid combination of tags\n", i); 7149 + return -EINVAL; 7150 + } 7253 7151 7254 7152 t = btf_type_skip_modifiers(btf, t->type, NULL); 7255 7153 ref_t = btf_resolve_size(btf, t, &mem_size); ··· 7299 7151 sub->args[i].arg_type = ARG_ANYTHING; 7300 7152 continue; 7301 7153 } 7154 + if (!is_global) 7155 + return -EINVAL; 7302 7156 bpf_log(log, "Arg#%d type %s in %s() is not supported yet.\n", 7303 7157 i, btf_type_str(t), tname); 7304 7158 return -EINVAL; 7305 - } 7306 - 7307 - for (i = 0; i < nargs; i++) { 7308 - const char *tag; 7309 - 7310 - if (sub->args[i].arg_type != ARG_PTR_TO_CTX) 7311 - continue; 7312 - 7313 - /* check if arg has "arg:ctx" tag */ 7314 - t = btf_type_by_id(btf, args[i].type); 7315 - tag = btf_find_decl_tag_value(btf, fn_t, i, "arg:"); 7316 - if (IS_ERR_OR_NULL(tag) || strcmp(tag, "ctx") != 0) 7317 - continue; 7318 - 7319 - if (btf_validate_prog_ctx_type(log, btf, t, i, prog_type, 7320 - prog->expected_attach_type)) 7321 - return -EINVAL; 7322 7159 } 7323 7160 7324 7161 sub->arg_cnt = nargs; ··· 7782 7649 return btf; 7783 7650 } 7784 7651 7652 + static int check_btf_kconfigs(const struct module *module, const char *feature) 7653 + { 7654 + if (!module && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) { 7655 + pr_err("missing vmlinux BTF, cannot register %s\n", feature); 7656 + return -ENOENT; 7657 + } 7658 + if (module && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES)) 7659 + pr_warn("missing module BTF, cannot register %s\n", feature); 7660 + return 0; 7661 + } 7662 + 7785 7663 BPF_CALL_4(bpf_btf_find_by_name_kind, char *, name, int, name_sz, u32, kind, int, flags) 7786 7664 { 7787 7665 struct btf *btf = NULL; ··· 8153 8009 int ret, i; 8154 8010 8155 8011 btf = btf_get_module_btf(kset->owner); 8156 - if (!btf) { 8157 - if (!kset->owner && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) { 8158 - pr_err("missing vmlinux BTF, cannot register kfuncs\n"); 8159 - return -ENOENT; 8160 - } 8161 - if (kset->owner && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES)) 8162 - pr_warn("missing module BTF, cannot register kfuncs\n"); 8163 - return 0; 8164 - } 8012 + if (!btf) 8013 + return check_btf_kconfigs(kset->owner, "kfunc"); 8165 8014 if (IS_ERR(btf)) 8166 8015 return PTR_ERR(btf); 8167 8016 ··· 8177 8040 const struct btf_kfunc_id_set *kset) 8178 8041 { 8179 8042 enum btf_kfunc_hook hook; 8043 + 8044 + /* All kfuncs need to be tagged as such in BTF. 8045 + * WARN() for initcall registrations that do not check errors. 8046 + */ 8047 + if (!(kset->set->flags & BTF_SET8_KFUNCS)) { 8048 + WARN_ON(!kset->owner); 8049 + return -EINVAL; 8050 + } 8180 8051 8181 8052 hook = bpf_prog_type_to_kfunc_hook(prog_type); 8182 8053 return __register_btf_kfunc_id_set(hook, kset); ··· 8262 8117 int ret; 8263 8118 8264 8119 btf = btf_get_module_btf(owner); 8265 - if (!btf) { 8266 - if (!owner && IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) { 8267 - pr_err("missing vmlinux BTF, cannot register dtor kfuncs\n"); 8268 - return -ENOENT; 8269 - } 8270 - if (owner && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES)) { 8271 - pr_err("missing module BTF, cannot register dtor kfuncs\n"); 8272 - return -ENOENT; 8273 - } 8274 - return 0; 8275 - } 8120 + if (!btf) 8121 + return check_btf_kconfigs(owner, "dtor kfuncs"); 8276 8122 if (IS_ERR(btf)) 8277 8123 return PTR_ERR(btf); 8278 8124 ··· 8378 8242 return n; 8379 8243 } 8380 8244 8381 - struct bpf_cand_cache { 8382 - const char *name; 8383 - u32 name_len; 8384 - u16 kind; 8385 - u16 cnt; 8386 - struct { 8387 - const struct btf *btf; 8388 - u32 id; 8389 - } cands[]; 8390 - }; 8391 - 8392 8245 static void bpf_free_cands(struct bpf_cand_cache *cands) 8393 8246 { 8394 8247 if (!cands->cnt) ··· 8397 8272 8398 8273 #define MODULE_CAND_CACHE_SIZE 31 8399 8274 static struct bpf_cand_cache *module_cand_cache[MODULE_CAND_CACHE_SIZE]; 8400 - 8401 - static DEFINE_MUTEX(cand_cache_mutex); 8402 8275 8403 8276 static void __print_cand_cache(struct bpf_verifier_log *log, 8404 8277 struct bpf_cand_cache **cache, ··· 8926 8803 8927 8804 btf = btf_get_module_btf(st_ops->owner); 8928 8805 if (!btf) 8929 - return -EINVAL; 8806 + return check_btf_kconfigs(st_ops->owner, "struct_ops"); 8807 + if (IS_ERR(btf)) 8808 + return PTR_ERR(btf); 8930 8809 8931 8810 log = kzalloc(sizeof(*log), GFP_KERNEL | __GFP_NOWARN); 8932 8811 if (!log) { ··· 8948 8823 } 8949 8824 EXPORT_SYMBOL_GPL(__register_bpf_struct_ops); 8950 8825 #endif 8826 + 8827 + bool btf_param_match_suffix(const struct btf *btf, 8828 + const struct btf_param *arg, 8829 + const char *suffix) 8830 + { 8831 + int suffix_len = strlen(suffix), len; 8832 + const char *param_name; 8833 + 8834 + /* In the future, this can be ported to use BTF tagging */ 8835 + param_name = btf_name_by_offset(btf, arg->name_off); 8836 + if (str_is_empty(param_name)) 8837 + return false; 8838 + len = strlen(param_name); 8839 + if (len <= suffix_len) 8840 + return false; 8841 + param_name += len - suffix_len; 8842 + return !strncmp(param_name, suffix, suffix_len); 8843 + }
-3
kernel/bpf/cgroup.c
··· 1364 1364 struct cgroup *cgrp; 1365 1365 int ret; 1366 1366 1367 - if (!sk || !sk_fullsock(sk)) 1368 - return 0; 1369 - 1370 1367 if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6) 1371 1368 return 0; 1372 1369
+2 -2
kernel/bpf/cpumask.c
··· 424 424 425 425 __bpf_kfunc_end_defs(); 426 426 427 - BTF_SET8_START(cpumask_kfunc_btf_ids) 427 + BTF_KFUNCS_START(cpumask_kfunc_btf_ids) 428 428 BTF_ID_FLAGS(func, bpf_cpumask_create, KF_ACQUIRE | KF_RET_NULL) 429 429 BTF_ID_FLAGS(func, bpf_cpumask_release, KF_RELEASE) 430 430 BTF_ID_FLAGS(func, bpf_cpumask_acquire, KF_ACQUIRE | KF_TRUSTED_ARGS) ··· 450 450 BTF_ID_FLAGS(func, bpf_cpumask_any_distribute, KF_RCU) 451 451 BTF_ID_FLAGS(func, bpf_cpumask_any_and_distribute, KF_RCU) 452 452 BTF_ID_FLAGS(func, bpf_cpumask_weight, KF_RCU) 453 - BTF_SET8_END(cpumask_kfunc_btf_ids) 453 + BTF_KFUNCS_END(cpumask_kfunc_btf_ids) 454 454 455 455 static const struct btf_kfunc_id_set cpumask_kfunc_set = { 456 456 .owner = THIS_MODULE,
+8 -8
kernel/bpf/helpers.c
··· 334 334 __this_cpu_write(irqsave_flags, flags); 335 335 } 336 336 337 - notrace BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock) 337 + NOTRACE_BPF_CALL_1(bpf_spin_lock, struct bpf_spin_lock *, lock) 338 338 { 339 339 __bpf_spin_lock_irqsave(lock); 340 340 return 0; ··· 357 357 local_irq_restore(flags); 358 358 } 359 359 360 - notrace BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock) 360 + NOTRACE_BPF_CALL_1(bpf_spin_unlock, struct bpf_spin_lock *, lock) 361 361 { 362 362 __bpf_spin_unlock_irqrestore(lock); 363 363 return 0; ··· 2487 2487 return obj; 2488 2488 } 2489 2489 2490 - __bpf_kfunc void *bpf_rdonly_cast(void *obj__ign, u32 btf_id__k) 2490 + __bpf_kfunc void *bpf_rdonly_cast(const void *obj__ign, u32 btf_id__k) 2491 2491 { 2492 - return obj__ign; 2492 + return (void *)obj__ign; 2493 2493 } 2494 2494 2495 2495 __bpf_kfunc void bpf_rcu_read_lock(void) ··· 2547 2547 2548 2548 __bpf_kfunc_end_defs(); 2549 2549 2550 - BTF_SET8_START(generic_btf_ids) 2550 + BTF_KFUNCS_START(generic_btf_ids) 2551 2551 #ifdef CONFIG_KEXEC_CORE 2552 2552 BTF_ID_FLAGS(func, crash_kexec, KF_DESTRUCTIVE) 2553 2553 #endif ··· 2576 2576 #endif 2577 2577 BTF_ID_FLAGS(func, bpf_task_from_pid, KF_ACQUIRE | KF_RET_NULL) 2578 2578 BTF_ID_FLAGS(func, bpf_throw) 2579 - BTF_SET8_END(generic_btf_ids) 2579 + BTF_KFUNCS_END(generic_btf_ids) 2580 2580 2581 2581 static const struct btf_kfunc_id_set generic_kfunc_set = { 2582 2582 .owner = THIS_MODULE, ··· 2592 2592 BTF_ID(func, bpf_cgroup_release_dtor) 2593 2593 #endif 2594 2594 2595 - BTF_SET8_START(common_btf_ids) 2595 + BTF_KFUNCS_START(common_btf_ids) 2596 2596 BTF_ID_FLAGS(func, bpf_cast_to_kern_ctx) 2597 2597 BTF_ID_FLAGS(func, bpf_rdonly_cast) 2598 2598 BTF_ID_FLAGS(func, bpf_rcu_read_lock) ··· 2621 2621 BTF_ID_FLAGS(func, bpf_dynptr_is_rdonly) 2622 2622 BTF_ID_FLAGS(func, bpf_dynptr_size) 2623 2623 BTF_ID_FLAGS(func, bpf_dynptr_clone) 2624 - BTF_SET8_END(common_btf_ids) 2624 + BTF_KFUNCS_END(common_btf_ids) 2625 2625 2626 2626 static const struct btf_kfunc_id_set common_kfunc_set = { 2627 2627 .owner = THIS_MODULE,
+52 -10
kernel/bpf/log.c
··· 9 9 #include <linux/bpf.h> 10 10 #include <linux/bpf_verifier.h> 11 11 #include <linux/math64.h> 12 + #include <linux/string.h> 12 13 13 14 #define verbose(env, fmt, args...) bpf_verifier_log_write(env, fmt, ##args) 14 15 ··· 334 333 { 335 334 const struct bpf_line_info *linfo; 336 335 const struct bpf_prog *prog; 337 - u32 i, nr_linfo; 336 + u32 nr_linfo; 337 + int l, r, m; 338 338 339 339 prog = env->prog; 340 340 nr_linfo = prog->aux->nr_linfo; ··· 344 342 return NULL; 345 343 346 344 linfo = prog->aux->linfo; 347 - for (i = 1; i < nr_linfo; i++) 348 - if (insn_off < linfo[i].insn_off) 349 - break; 345 + /* Loop invariant: linfo[l].insn_off <= insns_off. 346 + * linfo[0].insn_off == 0 which always satisfies above condition. 347 + * Binary search is searching for rightmost linfo entry that satisfies 348 + * the above invariant, giving us the desired record that covers given 349 + * instruction offset. 350 + */ 351 + l = 0; 352 + r = nr_linfo - 1; 353 + while (l < r) { 354 + /* (r - l + 1) / 2 means we break a tie to the right, so if: 355 + * l=1, r=2, linfo[l].insn_off <= insn_off, linfo[r].insn_off > insn_off, 356 + * then m=2, we see that linfo[m].insn_off > insn_off, and so 357 + * r becomes 1 and we exit the loop with correct l==1. 358 + * If the tie was broken to the left, m=1 would end us up in 359 + * an endless loop where l and m stay at 1 and r stays at 2. 360 + */ 361 + m = l + (r - l + 1) / 2; 362 + if (linfo[m].insn_off <= insn_off) 363 + l = m; 364 + else 365 + r = m - 1; 366 + } 350 367 351 - return &linfo[i - 1]; 368 + return &linfo[l]; 352 369 } 353 370 354 371 static const char *ltrim(const char *s) ··· 382 361 u32 insn_off, 383 362 const char *prefix_fmt, ...) 384 363 { 385 - const struct bpf_line_info *linfo; 364 + const struct bpf_line_info *linfo, *prev_linfo; 365 + const struct btf *btf; 366 + const char *s, *fname; 386 367 387 368 if (!bpf_verifier_log_needed(&env->log)) 388 369 return; 389 370 371 + prev_linfo = env->prev_linfo; 390 372 linfo = find_linfo(env, insn_off); 391 - if (!linfo || linfo == env->prev_linfo) 373 + if (!linfo || linfo == prev_linfo) 374 + return; 375 + 376 + /* It often happens that two separate linfo records point to the same 377 + * source code line, but have differing column numbers. Given verifier 378 + * log doesn't emit column information, from user perspective we just 379 + * end up emitting the same source code line twice unnecessarily. 380 + * So instead check that previous and current linfo record point to 381 + * the same file (file_name_offs match) and the same line number, and 382 + * avoid emitting duplicated source code line in such case. 383 + */ 384 + if (prev_linfo && linfo->file_name_off == prev_linfo->file_name_off && 385 + BPF_LINE_INFO_LINE_NUM(linfo->line_col) == BPF_LINE_INFO_LINE_NUM(prev_linfo->line_col)) 392 386 return; 393 387 394 388 if (prefix_fmt) { ··· 414 378 va_end(args); 415 379 } 416 380 417 - verbose(env, "%s\n", 418 - ltrim(btf_name_by_offset(env->prog->aux->btf, 419 - linfo->line_off))); 381 + btf = env->prog->aux->btf; 382 + s = ltrim(btf_name_by_offset(btf, linfo->line_off)); 383 + verbose(env, "%s", s); /* source code line */ 384 + 385 + s = btf_name_by_offset(btf, linfo->file_name_off); 386 + /* leave only file name */ 387 + fname = strrchr(s, '/'); 388 + fname = fname ? fname + 1 : s; 389 + verbose(env, " @ %s:%u\n", fname, BPF_LINE_INFO_LINE_NUM(linfo->line_col)); 420 390 421 391 env->prev_linfo = linfo; 422 392 }
+10 -10
kernel/bpf/lpm_trie.c
··· 164 164 */ 165 165 static size_t longest_prefix_match(const struct lpm_trie *trie, 166 166 const struct lpm_trie_node *node, 167 - const struct bpf_lpm_trie_key *key) 167 + const struct bpf_lpm_trie_key_u8 *key) 168 168 { 169 169 u32 limit = min(node->prefixlen, key->prefixlen); 170 170 u32 prefixlen = 0, i = 0; 171 171 172 172 BUILD_BUG_ON(offsetof(struct lpm_trie_node, data) % sizeof(u32)); 173 - BUILD_BUG_ON(offsetof(struct bpf_lpm_trie_key, data) % sizeof(u32)); 173 + BUILD_BUG_ON(offsetof(struct bpf_lpm_trie_key_u8, data) % sizeof(u32)); 174 174 175 175 #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && defined(CONFIG_64BIT) 176 176 ··· 229 229 { 230 230 struct lpm_trie *trie = container_of(map, struct lpm_trie, map); 231 231 struct lpm_trie_node *node, *found = NULL; 232 - struct bpf_lpm_trie_key *key = _key; 232 + struct bpf_lpm_trie_key_u8 *key = _key; 233 233 234 234 if (key->prefixlen > trie->max_prefixlen) 235 235 return NULL; ··· 309 309 struct lpm_trie *trie = container_of(map, struct lpm_trie, map); 310 310 struct lpm_trie_node *node, *im_node = NULL, *new_node = NULL; 311 311 struct lpm_trie_node __rcu **slot; 312 - struct bpf_lpm_trie_key *key = _key; 312 + struct bpf_lpm_trie_key_u8 *key = _key; 313 313 unsigned long irq_flags; 314 314 unsigned int next_bit; 315 315 size_t matchlen = 0; ··· 437 437 static long trie_delete_elem(struct bpf_map *map, void *_key) 438 438 { 439 439 struct lpm_trie *trie = container_of(map, struct lpm_trie, map); 440 - struct bpf_lpm_trie_key *key = _key; 440 + struct bpf_lpm_trie_key_u8 *key = _key; 441 441 struct lpm_trie_node __rcu **trim, **trim2; 442 442 struct lpm_trie_node *node, *parent; 443 443 unsigned long irq_flags; ··· 536 536 sizeof(struct lpm_trie_node)) 537 537 #define LPM_VAL_SIZE_MIN 1 538 538 539 - #define LPM_KEY_SIZE(X) (sizeof(struct bpf_lpm_trie_key) + (X)) 539 + #define LPM_KEY_SIZE(X) (sizeof(struct bpf_lpm_trie_key_u8) + (X)) 540 540 #define LPM_KEY_SIZE_MAX LPM_KEY_SIZE(LPM_DATA_SIZE_MAX) 541 541 #define LPM_KEY_SIZE_MIN LPM_KEY_SIZE(LPM_DATA_SIZE_MIN) 542 542 ··· 565 565 /* copy mandatory map attributes */ 566 566 bpf_map_init_from_attr(&trie->map, attr); 567 567 trie->data_size = attr->key_size - 568 - offsetof(struct bpf_lpm_trie_key, data); 568 + offsetof(struct bpf_lpm_trie_key_u8, data); 569 569 trie->max_prefixlen = trie->data_size * 8; 570 570 571 571 spin_lock_init(&trie->lock); ··· 616 616 { 617 617 struct lpm_trie_node *node, *next_node = NULL, *parent, *search_root; 618 618 struct lpm_trie *trie = container_of(map, struct lpm_trie, map); 619 - struct bpf_lpm_trie_key *key = _key, *next_key = _next_key; 619 + struct bpf_lpm_trie_key_u8 *key = _key, *next_key = _next_key; 620 620 struct lpm_trie_node **node_stack = NULL; 621 621 int err = 0, stack_ptr = -1; 622 622 unsigned int next_bit; ··· 703 703 } 704 704 do_copy: 705 705 next_key->prefixlen = next_node->prefixlen; 706 - memcpy((void *)next_key + offsetof(struct bpf_lpm_trie_key, data), 706 + memcpy((void *)next_key + offsetof(struct bpf_lpm_trie_key_u8, data), 707 707 next_node->data, trie->data_size); 708 708 free_stack: 709 709 kfree(node_stack); ··· 715 715 const struct btf_type *key_type, 716 716 const struct btf_type *value_type) 717 717 { 718 - /* Keys must have struct bpf_lpm_trie_key embedded. */ 718 + /* Keys must have struct bpf_lpm_trie_key_u8 embedded. */ 719 719 return BTF_INFO_KIND(key_type->info) != BTF_KIND_STRUCT ? 720 720 -EINVAL : 0; 721 721 }
+2 -2
kernel/bpf/map_iter.c
··· 213 213 214 214 __bpf_kfunc_end_defs(); 215 215 216 - BTF_SET8_START(bpf_map_iter_kfunc_ids) 216 + BTF_KFUNCS_START(bpf_map_iter_kfunc_ids) 217 217 BTF_ID_FLAGS(func, bpf_map_sum_elem_count, KF_TRUSTED_ARGS) 218 - BTF_SET8_END(bpf_map_iter_kfunc_ids) 218 + BTF_KFUNCS_END(bpf_map_iter_kfunc_ids) 219 219 220 220 static const struct btf_kfunc_id_set bpf_map_iter_kfunc_set = { 221 221 .owner = THIS_MODULE,
+8 -8
kernel/bpf/token.c
··· 72 72 u64 mask; 73 73 74 74 BUILD_BUG_ON(__MAX_BPF_CMD >= 64); 75 - mask = (1ULL << __MAX_BPF_CMD) - 1; 75 + mask = BIT_ULL(__MAX_BPF_CMD) - 1; 76 76 if ((token->allowed_cmds & mask) == mask) 77 77 seq_printf(m, "allowed_cmds:\tany\n"); 78 78 else 79 79 seq_printf(m, "allowed_cmds:\t0x%llx\n", token->allowed_cmds); 80 80 81 81 BUILD_BUG_ON(__MAX_BPF_MAP_TYPE >= 64); 82 - mask = (1ULL << __MAX_BPF_MAP_TYPE) - 1; 82 + mask = BIT_ULL(__MAX_BPF_MAP_TYPE) - 1; 83 83 if ((token->allowed_maps & mask) == mask) 84 84 seq_printf(m, "allowed_maps:\tany\n"); 85 85 else 86 86 seq_printf(m, "allowed_maps:\t0x%llx\n", token->allowed_maps); 87 87 88 88 BUILD_BUG_ON(__MAX_BPF_PROG_TYPE >= 64); 89 - mask = (1ULL << __MAX_BPF_PROG_TYPE) - 1; 89 + mask = BIT_ULL(__MAX_BPF_PROG_TYPE) - 1; 90 90 if ((token->allowed_progs & mask) == mask) 91 91 seq_printf(m, "allowed_progs:\tany\n"); 92 92 else 93 93 seq_printf(m, "allowed_progs:\t0x%llx\n", token->allowed_progs); 94 94 95 95 BUILD_BUG_ON(__MAX_BPF_ATTACH_TYPE >= 64); 96 - mask = (1ULL << __MAX_BPF_ATTACH_TYPE) - 1; 96 + mask = BIT_ULL(__MAX_BPF_ATTACH_TYPE) - 1; 97 97 if ((token->allowed_attachs & mask) == mask) 98 98 seq_printf(m, "allowed_attachs:\tany\n"); 99 99 else ··· 253 253 { 254 254 if (!token) 255 255 return false; 256 - if (!(token->allowed_cmds & (1ULL << cmd))) 256 + if (!(token->allowed_cmds & BIT_ULL(cmd))) 257 257 return false; 258 258 return security_bpf_token_cmd(token, cmd) == 0; 259 259 } ··· 263 263 if (!token || type >= __MAX_BPF_MAP_TYPE) 264 264 return false; 265 265 266 - return token->allowed_maps & (1ULL << type); 266 + return token->allowed_maps & BIT_ULL(type); 267 267 } 268 268 269 269 bool bpf_token_allow_prog_type(const struct bpf_token *token, ··· 273 273 if (!token || prog_type >= __MAX_BPF_PROG_TYPE || attach_type >= __MAX_BPF_ATTACH_TYPE) 274 274 return false; 275 275 276 - return (token->allowed_progs & (1ULL << prog_type)) && 277 - (token->allowed_attachs & (1ULL << attach_type)); 276 + return (token->allowed_progs & BIT_ULL(prog_type)) && 277 + (token->allowed_attachs & BIT_ULL(attach_type)); 278 278 }
+165 -71
kernel/bpf/verifier.c
··· 528 528 (bpf_pseudo_kfunc_call(insn) && is_sync_callback_calling_kfunc(insn->imm)); 529 529 } 530 530 531 + static bool is_async_callback_calling_insn(struct bpf_insn *insn) 532 + { 533 + return bpf_helper_call(insn) && is_async_callback_calling_function(insn->imm); 534 + } 535 + 531 536 static bool is_storage_get_function(enum bpf_func_id func_id) 532 537 { 533 538 return func_id == BPF_FUNC_sk_storage_get || ··· 1157 1152 static bool is_spilled_scalar_reg(const struct bpf_stack_state *stack) 1158 1153 { 1159 1154 return stack->slot_type[BPF_REG_SIZE - 1] == STACK_SPILL && 1155 + stack->spilled_ptr.type == SCALAR_VALUE; 1156 + } 1157 + 1158 + static bool is_spilled_scalar_reg64(const struct bpf_stack_state *stack) 1159 + { 1160 + return stack->slot_type[0] == STACK_SPILL && 1160 1161 stack->spilled_ptr.type == SCALAR_VALUE; 1161 1162 } 1162 1163 ··· 2275 2264 } 2276 2265 2277 2266 /* Mark a register as having a completely unknown (scalar) value. */ 2278 - static void __mark_reg_unknown(const struct bpf_verifier_env *env, 2279 - struct bpf_reg_state *reg) 2267 + static void __mark_reg_unknown_imprecise(struct bpf_reg_state *reg) 2280 2268 { 2281 2269 /* 2282 2270 * Clear type, off, and union(map_ptr, range) and ··· 2287 2277 reg->ref_obj_id = 0; 2288 2278 reg->var_off = tnum_unknown; 2289 2279 reg->frameno = 0; 2290 - reg->precise = !env->bpf_capable; 2280 + reg->precise = false; 2291 2281 __mark_reg_unbounded(reg); 2282 + } 2283 + 2284 + /* Mark a register as having a completely unknown (scalar) value, 2285 + * initialize .precise as true when not bpf capable. 2286 + */ 2287 + static void __mark_reg_unknown(const struct bpf_verifier_env *env, 2288 + struct bpf_reg_state *reg) 2289 + { 2290 + __mark_reg_unknown_imprecise(reg); 2291 + reg->precise = !env->bpf_capable; 2292 2292 } 2293 2293 2294 2294 static void mark_reg_unknown(struct bpf_verifier_env *env, ··· 4400 4380 return subreg32 ? tnum_subreg(reg->var_off).value : reg->var_off.value; 4401 4381 } 4402 4382 4403 - static bool __is_scalar_unbounded(struct bpf_reg_state *reg) 4404 - { 4405 - return tnum_is_unknown(reg->var_off) && 4406 - reg->smin_value == S64_MIN && reg->smax_value == S64_MAX && 4407 - reg->umin_value == 0 && reg->umax_value == U64_MAX && 4408 - reg->s32_min_value == S32_MIN && reg->s32_max_value == S32_MAX && 4409 - reg->u32_min_value == 0 && reg->u32_max_value == U32_MAX; 4410 - } 4411 - 4412 - static bool register_is_bounded(struct bpf_reg_state *reg) 4413 - { 4414 - return reg->type == SCALAR_VALUE && !__is_scalar_unbounded(reg); 4415 - } 4416 - 4417 4383 static bool __is_pointer_value(bool allow_ptr_leaks, 4418 4384 const struct bpf_reg_state *reg) 4419 4385 { ··· 4510 4504 return err; 4511 4505 4512 4506 mark_stack_slot_scratched(env, spi); 4513 - if (reg && !(off % BPF_REG_SIZE) && register_is_bounded(reg) && env->bpf_capable) { 4507 + if (reg && !(off % BPF_REG_SIZE) && reg->type == SCALAR_VALUE && env->bpf_capable) { 4514 4508 bool reg_value_fits; 4515 4509 4516 4510 reg_value_fits = get_reg_width(reg) <= BITS_PER_BYTE * size; ··· 4798 4792 if (dst_regno < 0) 4799 4793 return 0; 4800 4794 4801 - if (!(off % BPF_REG_SIZE) && size == spill_size) { 4795 + if (size <= spill_size && 4796 + bpf_stack_narrow_access_ok(off, size, spill_size)) { 4802 4797 /* The earlier check_reg_arg() has decided the 4803 4798 * subreg_def for this insn. Save it first. 4804 4799 */ ··· 4807 4800 4808 4801 copy_register_state(&state->regs[dst_regno], reg); 4809 4802 state->regs[dst_regno].subreg_def = subreg_def; 4803 + 4804 + /* Break the relation on a narrowing fill. 4805 + * coerce_reg_to_size will adjust the boundaries. 4806 + */ 4807 + if (get_reg_width(reg) > size * BITS_PER_BYTE) 4808 + state->regs[dst_regno].id = 0; 4810 4809 } else { 4811 4810 int spill_cnt = 0, zero_cnt = 0; 4812 4811 ··· 5260 5247 return -EINVAL; 5261 5248 } 5262 5249 5250 + static bool in_sleepable(struct bpf_verifier_env *env) 5251 + { 5252 + return env->prog->aux->sleepable; 5253 + } 5254 + 5263 5255 /* The non-sleepable programs and sleepable programs with explicit bpf_rcu_read_lock() 5264 5256 * can dereference RCU protected pointers and result is PTR_TRUSTED. 5265 5257 */ ··· 5272 5254 { 5273 5255 return env->cur_state->active_rcu_lock || 5274 5256 env->cur_state->active_lock.ptr || 5275 - !env->prog->aux->sleepable; 5257 + !in_sleepable(env); 5276 5258 } 5277 5259 5278 5260 /* Once GCC supports btf_type_tag the following mechanism will be replaced with tag check */ ··· 5824 5806 strict); 5825 5807 } 5826 5808 5809 + static int round_up_stack_depth(struct bpf_verifier_env *env, int stack_depth) 5810 + { 5811 + if (env->prog->jit_requested) 5812 + return round_up(stack_depth, 16); 5813 + 5814 + /* round up to 32-bytes, since this is granularity 5815 + * of interpreter stack size 5816 + */ 5817 + return round_up(max_t(u32, stack_depth, 1), 32); 5818 + } 5819 + 5827 5820 /* starting from main bpf function walk all instructions of the function 5828 5821 * and recursively walk all callees that given function can call. 5829 5822 * Ignore jump and exit insns. ··· 5878 5849 depth); 5879 5850 return -EACCES; 5880 5851 } 5881 - /* round up to 32-bytes, since this is granularity 5882 - * of interpreter stack size 5883 - */ 5884 - depth += round_up(max_t(u32, subprog[idx].stack_depth, 1), 32); 5852 + depth += round_up_stack_depth(env, subprog[idx].stack_depth); 5885 5853 if (depth > MAX_BPF_STACK) { 5886 5854 verbose(env, "combined stack size of %d calls is %d. Too large\n", 5887 5855 frame + 1, depth); ··· 5972 5946 */ 5973 5947 if (frame == 0) 5974 5948 return 0; 5975 - depth -= round_up(max_t(u32, subprog[idx].stack_depth, 1), 32); 5949 + depth -= round_up_stack_depth(env, subprog[idx].stack_depth); 5976 5950 frame--; 5977 5951 i = ret_insn[frame]; 5978 5952 idx = ret_prog[frame]; ··· 6103 6077 * values are also truncated so we push 64-bit bounds into 6104 6078 * 32-bit bounds. Above were truncated < 32-bits already. 6105 6079 */ 6106 - if (size < 4) { 6080 + if (size < 4) 6107 6081 __mark_reg32_unbounded(reg); 6108 - reg_bounds_sync(reg); 6109 - } 6082 + 6083 + reg_bounds_sync(reg); 6110 6084 } 6111 6085 6112 6086 static void set_sext64_default_val(struct bpf_reg_state *reg, int size) ··· 8262 8236 switch ((int)reg->type) { 8263 8237 case PTR_TO_BTF_ID: 8264 8238 case PTR_TO_BTF_ID | PTR_TRUSTED: 8239 + case PTR_TO_BTF_ID | PTR_TRUSTED | PTR_MAYBE_NULL: 8265 8240 case PTR_TO_BTF_ID | MEM_RCU: 8266 8241 case PTR_TO_BTF_ID | PTR_MAYBE_NULL: 8267 8242 case PTR_TO_BTF_ID | PTR_MAYBE_NULL | MEM_RCU: ··· 9365 9338 ret = process_dynptr_func(env, regno, -1, arg->arg_type, 0); 9366 9339 if (ret) 9367 9340 return ret; 9341 + } else if (base_type(arg->arg_type) == ARG_PTR_TO_BTF_ID) { 9342 + struct bpf_call_arg_meta meta; 9343 + int err; 9344 + 9345 + if (register_is_null(reg) && type_may_be_null(arg->arg_type)) 9346 + continue; 9347 + 9348 + memset(&meta, 0, sizeof(meta)); /* leave func_id as zero */ 9349 + err = check_reg_type(env, regno, arg->arg_type, &arg->btf_id, &meta); 9350 + err = err ?: check_func_arg_reg_off(env, reg, regno, arg->arg_type); 9351 + if (err) 9352 + return err; 9368 9353 } else { 9369 9354 bpf_log(log, "verifier bug: unrecognized arg#%d type %d\n", 9370 9355 i, arg->arg_type); ··· 9452 9413 return -EFAULT; 9453 9414 } 9454 9415 9455 - if (insn->code == (BPF_JMP | BPF_CALL) && 9456 - insn->src_reg == 0 && 9457 - insn->imm == BPF_FUNC_timer_set_callback) { 9416 + if (is_async_callback_calling_insn(insn)) { 9458 9417 struct bpf_verifier_state *async_cb; 9459 9418 9460 9419 /* there is no real recursion here. timer callbacks are async */ ··· 9510 9473 return err; 9511 9474 if (subprog_is_global(env, subprog)) { 9512 9475 const char *sub_name = subprog_name(env, subprog); 9476 + 9477 + /* Only global subprogs cannot be called with a lock held. */ 9478 + if (env->cur_state->active_lock.ptr) { 9479 + verbose(env, "global function calls are not allowed while holding a lock,\n" 9480 + "use static function instead\n"); 9481 + return -EINVAL; 9482 + } 9513 9483 9514 9484 if (err) { 9515 9485 verbose(env, "Caller passes invalid args into func#%d ('%s')\n", ··· 10174 10130 return -EINVAL; 10175 10131 } 10176 10132 10177 - if (!env->prog->aux->sleepable && fn->might_sleep) { 10133 + if (!in_sleepable(env) && fn->might_sleep) { 10178 10134 verbose(env, "helper call might sleep in a non-sleepable prog\n"); 10179 10135 return -EINVAL; 10180 10136 } ··· 10204 10160 return -EINVAL; 10205 10161 } 10206 10162 10207 - if (env->prog->aux->sleepable && is_storage_get_function(func_id)) 10163 + if (in_sleepable(env) && is_storage_get_function(func_id)) 10208 10164 env->insn_aux_data[insn_idx].storage_get_func_atomic = true; 10209 10165 } 10210 10166 ··· 10700 10656 return meta->kfunc_flags & KF_RCU_PROTECTED; 10701 10657 } 10702 10658 10703 - static bool __kfunc_param_match_suffix(const struct btf *btf, 10704 - const struct btf_param *arg, 10705 - const char *suffix) 10706 - { 10707 - int suffix_len = strlen(suffix), len; 10708 - const char *param_name; 10709 - 10710 - /* In the future, this can be ported to use BTF tagging */ 10711 - param_name = btf_name_by_offset(btf, arg->name_off); 10712 - if (str_is_empty(param_name)) 10713 - return false; 10714 - len = strlen(param_name); 10715 - if (len < suffix_len) 10716 - return false; 10717 - param_name += len - suffix_len; 10718 - return !strncmp(param_name, suffix, suffix_len); 10719 - } 10720 - 10721 10659 static bool is_kfunc_arg_mem_size(const struct btf *btf, 10722 10660 const struct btf_param *arg, 10723 10661 const struct bpf_reg_state *reg) ··· 10710 10684 if (!btf_type_is_scalar(t) || reg->type != SCALAR_VALUE) 10711 10685 return false; 10712 10686 10713 - return __kfunc_param_match_suffix(btf, arg, "__sz"); 10687 + return btf_param_match_suffix(btf, arg, "__sz"); 10714 10688 } 10715 10689 10716 10690 static bool is_kfunc_arg_const_mem_size(const struct btf *btf, ··· 10723 10697 if (!btf_type_is_scalar(t) || reg->type != SCALAR_VALUE) 10724 10698 return false; 10725 10699 10726 - return __kfunc_param_match_suffix(btf, arg, "__szk"); 10700 + return btf_param_match_suffix(btf, arg, "__szk"); 10727 10701 } 10728 10702 10729 10703 static bool is_kfunc_arg_optional(const struct btf *btf, const struct btf_param *arg) 10730 10704 { 10731 - return __kfunc_param_match_suffix(btf, arg, "__opt"); 10705 + return btf_param_match_suffix(btf, arg, "__opt"); 10732 10706 } 10733 10707 10734 10708 static bool is_kfunc_arg_constant(const struct btf *btf, const struct btf_param *arg) 10735 10709 { 10736 - return __kfunc_param_match_suffix(btf, arg, "__k"); 10710 + return btf_param_match_suffix(btf, arg, "__k"); 10737 10711 } 10738 10712 10739 10713 static bool is_kfunc_arg_ignore(const struct btf *btf, const struct btf_param *arg) 10740 10714 { 10741 - return __kfunc_param_match_suffix(btf, arg, "__ign"); 10715 + return btf_param_match_suffix(btf, arg, "__ign"); 10742 10716 } 10743 10717 10744 10718 static bool is_kfunc_arg_alloc_obj(const struct btf *btf, const struct btf_param *arg) 10745 10719 { 10746 - return __kfunc_param_match_suffix(btf, arg, "__alloc"); 10720 + return btf_param_match_suffix(btf, arg, "__alloc"); 10747 10721 } 10748 10722 10749 10723 static bool is_kfunc_arg_uninit(const struct btf *btf, const struct btf_param *arg) 10750 10724 { 10751 - return __kfunc_param_match_suffix(btf, arg, "__uninit"); 10725 + return btf_param_match_suffix(btf, arg, "__uninit"); 10752 10726 } 10753 10727 10754 10728 static bool is_kfunc_arg_refcounted_kptr(const struct btf *btf, const struct btf_param *arg) 10755 10729 { 10756 - return __kfunc_param_match_suffix(btf, arg, "__refcounted_kptr"); 10730 + return btf_param_match_suffix(btf, arg, "__refcounted_kptr"); 10757 10731 } 10758 10732 10759 10733 static bool is_kfunc_arg_nullable(const struct btf *btf, const struct btf_param *arg) 10760 10734 { 10761 - return __kfunc_param_match_suffix(btf, arg, "__nullable"); 10735 + return btf_param_match_suffix(btf, arg, "__nullable"); 10762 10736 } 10763 10737 10764 10738 static bool is_kfunc_arg_const_str(const struct btf *btf, const struct btf_param *arg) 10765 10739 { 10766 - return __kfunc_param_match_suffix(btf, arg, "__str"); 10740 + return btf_param_match_suffix(btf, arg, "__str"); 10767 10741 } 10768 10742 10769 10743 static bool is_kfunc_arg_scalar_with_name(const struct btf *btf, ··· 11033 11007 * type to our caller. When a set of conditions hold in the BTF type of 11034 11008 * arguments, we resolve it to a known kfunc_ptr_arg_type. 11035 11009 */ 11036 - if (btf_get_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), argno)) 11010 + if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), argno)) 11037 11011 return KF_ARG_PTR_TO_CTX; 11038 11012 11039 11013 if (is_kfunc_arg_alloc_obj(meta->btf, &args[argno])) ··· 11545 11519 return true; 11546 11520 fallthrough; 11547 11521 default: 11548 - return env->prog->aux->sleepable; 11522 + return in_sleepable(env); 11549 11523 } 11550 11524 } 11551 11525 ··· 12066 12040 } 12067 12041 12068 12042 sleepable = is_kfunc_sleepable(&meta); 12069 - if (sleepable && !env->prog->aux->sleepable) { 12043 + if (sleepable && !in_sleepable(env)) { 12070 12044 verbose(env, "program must be sleepable to call sleepable kfunc %s\n", func_name); 12071 12045 return -EACCES; 12072 12046 } ··· 15593 15567 return DONE_EXPLORING; 15594 15568 15595 15569 case BPF_CALL: 15596 - if (insn->src_reg == 0 && insn->imm == BPF_FUNC_timer_set_callback) 15570 + if (is_async_callback_calling_insn(insn)) 15597 15571 /* Mark this call insn as a prune point to trigger 15598 15572 * is_state_visited() check before call itself is 15599 15573 * processed by __check_func_call(). Otherwise new ··· 16509 16483 } 16510 16484 } 16511 16485 16486 + static struct bpf_reg_state unbound_reg; 16487 + 16488 + static __init int unbound_reg_init(void) 16489 + { 16490 + __mark_reg_unknown_imprecise(&unbound_reg); 16491 + unbound_reg.live |= REG_LIVE_READ; 16492 + return 0; 16493 + } 16494 + late_initcall(unbound_reg_init); 16495 + 16496 + static bool is_stack_all_misc(struct bpf_verifier_env *env, 16497 + struct bpf_stack_state *stack) 16498 + { 16499 + u32 i; 16500 + 16501 + for (i = 0; i < ARRAY_SIZE(stack->slot_type); ++i) { 16502 + if ((stack->slot_type[i] == STACK_MISC) || 16503 + (stack->slot_type[i] == STACK_INVALID && env->allow_uninit_stack)) 16504 + continue; 16505 + return false; 16506 + } 16507 + 16508 + return true; 16509 + } 16510 + 16511 + static struct bpf_reg_state *scalar_reg_for_stack(struct bpf_verifier_env *env, 16512 + struct bpf_stack_state *stack) 16513 + { 16514 + if (is_spilled_scalar_reg64(stack)) 16515 + return &stack->spilled_ptr; 16516 + 16517 + if (is_stack_all_misc(env, stack)) 16518 + return &unbound_reg; 16519 + 16520 + return NULL; 16521 + } 16522 + 16512 16523 static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, 16513 16524 struct bpf_func_state *cur, struct bpf_idmap *idmap, bool exact) 16514 16525 { ··· 16583 16520 */ 16584 16521 if (i >= cur->allocated_stack) 16585 16522 return false; 16523 + 16524 + /* 64-bit scalar spill vs all slots MISC and vice versa. 16525 + * Load from all slots MISC produces unbound scalar. 16526 + * Construct a fake register for such stack and call 16527 + * regsafe() to ensure scalar ids are compared. 16528 + */ 16529 + old_reg = scalar_reg_for_stack(env, &old->stack[spi]); 16530 + cur_reg = scalar_reg_for_stack(env, &cur->stack[spi]); 16531 + if (old_reg && cur_reg) { 16532 + if (!regsafe(env, old_reg, cur_reg, idmap, exact)) 16533 + return false; 16534 + i += BPF_REG_SIZE - 1; 16535 + continue; 16536 + } 16586 16537 16587 16538 /* if old state was safe with misc data in the stack 16588 16539 * it will be safe with zero-initialized stack. ··· 17651 17574 17652 17575 if (env->cur_state->active_lock.ptr) { 17653 17576 if ((insn->src_reg == BPF_REG_0 && insn->imm != BPF_FUNC_spin_unlock) || 17654 - (insn->src_reg == BPF_PSEUDO_CALL) || 17655 17577 (insn->src_reg == BPF_PSEUDO_KFUNC_CALL && 17656 17578 (insn->off != 0 || !is_bpf_graph_api_kfunc(insn->imm)))) { 17657 17579 verbose(env, "function calls are not allowed while holding a lock\n"); ··· 17698 17622 return -EINVAL; 17699 17623 } 17700 17624 process_bpf_exit_full: 17701 - if (env->cur_state->active_lock.ptr && 17702 - !in_rbtree_lock_required_cb(env)) { 17625 + if (env->cur_state->active_lock.ptr && !env->cur_state->curframe) { 17703 17626 verbose(env, "bpf_spin_unlock is missing\n"); 17704 17627 return -EINVAL; 17705 17628 } 17706 17629 17707 - if (env->cur_state->active_rcu_lock && 17708 - !in_rbtree_lock_required_cb(env)) { 17630 + if (env->cur_state->active_rcu_lock && !env->cur_state->curframe) { 17709 17631 verbose(env, "bpf_rcu_read_unlock is missing\n"); 17710 17632 return -EINVAL; 17711 17633 } ··· 18032 17958 case BPF_MAP_TYPE_SK_STORAGE: 18033 17959 case BPF_MAP_TYPE_TASK_STORAGE: 18034 17960 case BPF_MAP_TYPE_CGRP_STORAGE: 17961 + case BPF_MAP_TYPE_QUEUE: 17962 + case BPF_MAP_TYPE_STACK: 18035 17963 break; 18036 17964 default: 18037 17965 verbose(env, ··· 19679 19603 } 19680 19604 19681 19605 if (is_storage_get_function(insn->imm)) { 19682 - if (!env->prog->aux->sleepable || 19606 + if (!in_sleepable(env) || 19683 19607 env->insn_aux_data[i + delta].storage_get_func_atomic) 19684 19608 insn_buf[0] = BPF_MOV64_IMM(BPF_REG_5, (__force __s32)GFP_ATOMIC); 19685 19609 else ··· 20215 20139 mark_reg_known_zero(env, regs, i); 20216 20140 reg->mem_size = arg->mem_size; 20217 20141 reg->id = ++env->id_gen; 20142 + } else if (base_type(arg->arg_type) == ARG_PTR_TO_BTF_ID) { 20143 + reg->type = PTR_TO_BTF_ID; 20144 + if (arg->arg_type & PTR_MAYBE_NULL) 20145 + reg->type |= PTR_MAYBE_NULL; 20146 + if (arg->arg_type & PTR_UNTRUSTED) 20147 + reg->type |= PTR_UNTRUSTED; 20148 + if (arg->arg_type & PTR_TRUSTED) 20149 + reg->type |= PTR_TRUSTED; 20150 + mark_reg_known_zero(env, regs, i); 20151 + reg->btf = bpf_get_btf_vmlinux(); /* can't fail at this point */ 20152 + reg->btf_id = arg->btf_id; 20153 + reg->id = ++env->id_gen; 20218 20154 } else { 20219 20155 WARN_ONCE(1, "BUG: unhandled arg#%d type %d\n", 20220 20156 i - BPF_REG_1, arg->arg_type); ··· 20438 20350 return err; 20439 20351 } 20440 20352 } 20353 + 20354 + /* btf_ctx_access() used this to provide argument type info */ 20355 + prog->aux->ctx_arg_info = 20356 + st_ops_desc->arg_info[member_idx].info; 20357 + prog->aux->ctx_arg_info_size = 20358 + st_ops_desc->arg_info[member_idx].cnt; 20441 20359 20442 20360 prog->aux->attach_func_proto = func_proto; 20443 20361 prog->aux->attach_func_name = mname;
+2 -2
kernel/cgroup/rstat.c
··· 562 562 } 563 563 564 564 /* Add bpf kfuncs for cgroup_rstat_updated() and cgroup_rstat_flush() */ 565 - BTF_SET8_START(bpf_rstat_kfunc_ids) 565 + BTF_KFUNCS_START(bpf_rstat_kfunc_ids) 566 566 BTF_ID_FLAGS(func, cgroup_rstat_updated) 567 567 BTF_ID_FLAGS(func, cgroup_rstat_flush, KF_SLEEPABLE) 568 - BTF_SET8_END(bpf_rstat_kfunc_ids) 568 + BTF_KFUNCS_END(bpf_rstat_kfunc_ids) 569 569 570 570 static const struct btf_kfunc_id_set bpf_rstat_kfunc_set = { 571 571 .owner = THIS_MODULE,
+1 -5
kernel/events/core.c
··· 9302 9302 { 9303 9303 struct perf_bpf_event bpf_event; 9304 9304 9305 - if (type <= PERF_BPF_EVENT_UNKNOWN || 9306 - type >= PERF_BPF_EVENT_MAX) 9307 - return; 9308 - 9309 9305 switch (type) { 9310 9306 case PERF_BPF_EVENT_PROG_LOAD: 9311 9307 case PERF_BPF_EVENT_PROG_UNLOAD: ··· 9309 9313 perf_event_bpf_emit_ksymbols(prog, type); 9310 9314 break; 9311 9315 default: 9312 - break; 9316 + return; 9313 9317 } 9314 9318 9315 9319 if (!atomic_read(&nr_bpf_events))
+4 -4
kernel/trace/bpf_trace.c
··· 1412 1412 1413 1413 __bpf_kfunc_end_defs(); 1414 1414 1415 - BTF_SET8_START(key_sig_kfunc_set) 1415 + BTF_KFUNCS_START(key_sig_kfunc_set) 1416 1416 BTF_ID_FLAGS(func, bpf_lookup_user_key, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE) 1417 1417 BTF_ID_FLAGS(func, bpf_lookup_system_key, KF_ACQUIRE | KF_RET_NULL) 1418 1418 BTF_ID_FLAGS(func, bpf_key_put, KF_RELEASE) 1419 1419 #ifdef CONFIG_SYSTEM_DATA_VERIFICATION 1420 1420 BTF_ID_FLAGS(func, bpf_verify_pkcs7_signature, KF_SLEEPABLE) 1421 1421 #endif 1422 - BTF_SET8_END(key_sig_kfunc_set) 1422 + BTF_KFUNCS_END(key_sig_kfunc_set) 1423 1423 1424 1424 static const struct btf_kfunc_id_set bpf_key_sig_kfunc_set = { 1425 1425 .owner = THIS_MODULE, ··· 1475 1475 1476 1476 __bpf_kfunc_end_defs(); 1477 1477 1478 - BTF_SET8_START(fs_kfunc_set_ids) 1478 + BTF_KFUNCS_START(fs_kfunc_set_ids) 1479 1479 BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE | KF_TRUSTED_ARGS) 1480 - BTF_SET8_END(fs_kfunc_set_ids) 1480 + BTF_KFUNCS_END(fs_kfunc_set_ids) 1481 1481 1482 1482 static int bpf_get_file_xattr_filter(const struct bpf_prog *prog, u32 kfunc_id) 1483 1483 {
+4 -4
net/bpf/test_run.c
··· 617 617 618 618 __bpf_kfunc_end_defs(); 619 619 620 - BTF_SET8_START(bpf_test_modify_return_ids) 620 + BTF_KFUNCS_START(bpf_test_modify_return_ids) 621 621 BTF_ID_FLAGS(func, bpf_modify_return_test) 622 622 BTF_ID_FLAGS(func, bpf_modify_return_test2) 623 623 BTF_ID_FLAGS(func, bpf_fentry_test1, KF_SLEEPABLE) 624 - BTF_SET8_END(bpf_test_modify_return_ids) 624 + BTF_KFUNCS_END(bpf_test_modify_return_ids) 625 625 626 626 static const struct btf_kfunc_id_set bpf_test_modify_return_set = { 627 627 .owner = THIS_MODULE, 628 628 .set = &bpf_test_modify_return_ids, 629 629 }; 630 630 631 - BTF_SET8_START(test_sk_check_kfunc_ids) 631 + BTF_KFUNCS_START(test_sk_check_kfunc_ids) 632 632 BTF_ID_FLAGS(func, bpf_kfunc_call_test_release, KF_RELEASE) 633 633 BTF_ID_FLAGS(func, bpf_kfunc_call_memb_release, KF_RELEASE) 634 - BTF_SET8_END(test_sk_check_kfunc_ids) 634 + BTF_KFUNCS_END(test_sk_check_kfunc_ids) 635 635 636 636 static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, 637 637 u32 size, u32 headroom, u32 tailroom)
+10 -10
net/core/filter.c
··· 11982 11982 return 0; 11983 11983 } 11984 11984 11985 - BTF_SET8_START(bpf_kfunc_check_set_skb) 11985 + BTF_KFUNCS_START(bpf_kfunc_check_set_skb) 11986 11986 BTF_ID_FLAGS(func, bpf_dynptr_from_skb) 11987 - BTF_SET8_END(bpf_kfunc_check_set_skb) 11987 + BTF_KFUNCS_END(bpf_kfunc_check_set_skb) 11988 11988 11989 - BTF_SET8_START(bpf_kfunc_check_set_xdp) 11989 + BTF_KFUNCS_START(bpf_kfunc_check_set_xdp) 11990 11990 BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) 11991 - BTF_SET8_END(bpf_kfunc_check_set_xdp) 11991 + BTF_KFUNCS_END(bpf_kfunc_check_set_xdp) 11992 11992 11993 - BTF_SET8_START(bpf_kfunc_check_set_sock_addr) 11993 + BTF_KFUNCS_START(bpf_kfunc_check_set_sock_addr) 11994 11994 BTF_ID_FLAGS(func, bpf_sock_addr_set_sun_path) 11995 - BTF_SET8_END(bpf_kfunc_check_set_sock_addr) 11995 + BTF_KFUNCS_END(bpf_kfunc_check_set_sock_addr) 11996 11996 11997 - BTF_SET8_START(bpf_kfunc_check_set_tcp_reqsk) 11997 + BTF_KFUNCS_START(bpf_kfunc_check_set_tcp_reqsk) 11998 11998 BTF_ID_FLAGS(func, bpf_sk_assign_tcp_reqsk, KF_TRUSTED_ARGS) 11999 - BTF_SET8_END(bpf_kfunc_check_set_tcp_reqsk) 11999 + BTF_KFUNCS_END(bpf_kfunc_check_set_tcp_reqsk) 12000 12000 12001 12001 static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { 12002 12002 .owner = THIS_MODULE, ··· 12075 12075 12076 12076 __bpf_kfunc_end_defs(); 12077 12077 12078 - BTF_SET8_START(bpf_sk_iter_kfunc_ids) 12078 + BTF_KFUNCS_START(bpf_sk_iter_kfunc_ids) 12079 12079 BTF_ID_FLAGS(func, bpf_sock_destroy, KF_TRUSTED_ARGS) 12080 - BTF_SET8_END(bpf_sk_iter_kfunc_ids) 12080 + BTF_KFUNCS_END(bpf_sk_iter_kfunc_ids) 12081 12081 12082 12082 static int tracing_iter_filter(const struct bpf_prog *prog, u32 kfunc_id) 12083 12083 {
+2 -2
net/core/xdp.c
··· 771 771 772 772 __bpf_kfunc_end_defs(); 773 773 774 - BTF_SET8_START(xdp_metadata_kfunc_ids) 774 + BTF_KFUNCS_START(xdp_metadata_kfunc_ids) 775 775 #define XDP_METADATA_KFUNC(_, __, name, ___) BTF_ID_FLAGS(func, name, KF_TRUSTED_ARGS) 776 776 XDP_METADATA_KFUNC_xxx 777 777 #undef XDP_METADATA_KFUNC 778 - BTF_SET8_END(xdp_metadata_kfunc_ids) 778 + BTF_KFUNCS_END(xdp_metadata_kfunc_ids) 779 779 780 780 static const struct btf_kfunc_id_set xdp_metadata_kfunc_set = { 781 781 .owner = THIS_MODULE,
+2 -2
net/ipv4/bpf_tcp_ca.c
··· 201 201 } 202 202 } 203 203 204 - BTF_SET8_START(bpf_tcp_ca_check_kfunc_ids) 204 + BTF_KFUNCS_START(bpf_tcp_ca_check_kfunc_ids) 205 205 BTF_ID_FLAGS(func, tcp_reno_ssthresh) 206 206 BTF_ID_FLAGS(func, tcp_reno_cong_avoid) 207 207 BTF_ID_FLAGS(func, tcp_reno_undo_cwnd) 208 208 BTF_ID_FLAGS(func, tcp_slow_start) 209 209 BTF_ID_FLAGS(func, tcp_cong_avoid_ai) 210 - BTF_SET8_END(bpf_tcp_ca_check_kfunc_ids) 210 + BTF_KFUNCS_END(bpf_tcp_ca_check_kfunc_ids) 211 211 212 212 static const struct btf_kfunc_id_set bpf_tcp_ca_kfunc_set = { 213 213 .owner = THIS_MODULE,
+2 -2
net/ipv4/fou_bpf.c
··· 100 100 101 101 __bpf_kfunc_end_defs(); 102 102 103 - BTF_SET8_START(fou_kfunc_set) 103 + BTF_KFUNCS_START(fou_kfunc_set) 104 104 BTF_ID_FLAGS(func, bpf_skb_set_fou_encap) 105 105 BTF_ID_FLAGS(func, bpf_skb_get_fou_encap) 106 - BTF_SET8_END(fou_kfunc_set) 106 + BTF_KFUNCS_END(fou_kfunc_set) 107 107 108 108 static const struct btf_kfunc_id_set fou_bpf_kfunc_set = { 109 109 .owner = THIS_MODULE,
+2 -2
net/ipv4/tcp_bbr.c
··· 1155 1155 .set_state = bbr_set_state, 1156 1156 }; 1157 1157 1158 - BTF_SET8_START(tcp_bbr_check_kfunc_ids) 1158 + BTF_KFUNCS_START(tcp_bbr_check_kfunc_ids) 1159 1159 #ifdef CONFIG_X86 1160 1160 #ifdef CONFIG_DYNAMIC_FTRACE 1161 1161 BTF_ID_FLAGS(func, bbr_init) ··· 1168 1168 BTF_ID_FLAGS(func, bbr_set_state) 1169 1169 #endif 1170 1170 #endif 1171 - BTF_SET8_END(tcp_bbr_check_kfunc_ids) 1171 + BTF_KFUNCS_END(tcp_bbr_check_kfunc_ids) 1172 1172 1173 1173 static const struct btf_kfunc_id_set tcp_bbr_kfunc_set = { 1174 1174 .owner = THIS_MODULE,
+2 -2
net/ipv4/tcp_cubic.c
··· 485 485 .name = "cubic", 486 486 }; 487 487 488 - BTF_SET8_START(tcp_cubic_check_kfunc_ids) 488 + BTF_KFUNCS_START(tcp_cubic_check_kfunc_ids) 489 489 #ifdef CONFIG_X86 490 490 #ifdef CONFIG_DYNAMIC_FTRACE 491 491 BTF_ID_FLAGS(func, cubictcp_init) ··· 496 496 BTF_ID_FLAGS(func, cubictcp_acked) 497 497 #endif 498 498 #endif 499 - BTF_SET8_END(tcp_cubic_check_kfunc_ids) 499 + BTF_KFUNCS_END(tcp_cubic_check_kfunc_ids) 500 500 501 501 static const struct btf_kfunc_id_set tcp_cubic_kfunc_set = { 502 502 .owner = THIS_MODULE,
+2 -2
net/ipv4/tcp_dctcp.c
··· 260 260 .name = "dctcp-reno", 261 261 }; 262 262 263 - BTF_SET8_START(tcp_dctcp_check_kfunc_ids) 263 + BTF_KFUNCS_START(tcp_dctcp_check_kfunc_ids) 264 264 #ifdef CONFIG_X86 265 265 #ifdef CONFIG_DYNAMIC_FTRACE 266 266 BTF_ID_FLAGS(func, dctcp_init) ··· 271 271 BTF_ID_FLAGS(func, dctcp_state) 272 272 #endif 273 273 #endif 274 - BTF_SET8_END(tcp_dctcp_check_kfunc_ids) 274 + BTF_KFUNCS_END(tcp_dctcp_check_kfunc_ids) 275 275 276 276 static const struct btf_kfunc_id_set tcp_dctcp_kfunc_set = { 277 277 .owner = THIS_MODULE,
+2 -2
net/netfilter/nf_conntrack_bpf.c
··· 467 467 468 468 __bpf_kfunc_end_defs(); 469 469 470 - BTF_SET8_START(nf_ct_kfunc_set) 470 + BTF_KFUNCS_START(nf_ct_kfunc_set) 471 471 BTF_ID_FLAGS(func, bpf_xdp_ct_alloc, KF_ACQUIRE | KF_RET_NULL) 472 472 BTF_ID_FLAGS(func, bpf_xdp_ct_lookup, KF_ACQUIRE | KF_RET_NULL) 473 473 BTF_ID_FLAGS(func, bpf_skb_ct_alloc, KF_ACQUIRE | KF_RET_NULL) ··· 478 478 BTF_ID_FLAGS(func, bpf_ct_change_timeout, KF_TRUSTED_ARGS) 479 479 BTF_ID_FLAGS(func, bpf_ct_set_status, KF_TRUSTED_ARGS) 480 480 BTF_ID_FLAGS(func, bpf_ct_change_status, KF_TRUSTED_ARGS) 481 - BTF_SET8_END(nf_ct_kfunc_set) 481 + BTF_KFUNCS_END(nf_ct_kfunc_set) 482 482 483 483 static const struct btf_kfunc_id_set nf_conntrack_kfunc_set = { 484 484 .owner = THIS_MODULE,
+2 -2
net/netfilter/nf_nat_bpf.c
··· 54 54 55 55 __bpf_kfunc_end_defs(); 56 56 57 - BTF_SET8_START(nf_nat_kfunc_set) 57 + BTF_KFUNCS_START(nf_nat_kfunc_set) 58 58 BTF_ID_FLAGS(func, bpf_ct_set_nat_info, KF_TRUSTED_ARGS) 59 - BTF_SET8_END(nf_nat_kfunc_set) 59 + BTF_KFUNCS_END(nf_nat_kfunc_set) 60 60 61 61 static const struct btf_kfunc_id_set nf_bpf_nat_kfunc_set = { 62 62 .owner = THIS_MODULE,
+4 -1
net/xdp/xsk.c
··· 313 313 314 314 static int xsk_rcv_check(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len) 315 315 { 316 + struct net_device *dev = xdp->rxq->dev; 317 + u32 qid = xdp->rxq->queue_index; 318 + 316 319 if (!xsk_is_bound(xs)) 317 320 return -ENXIO; 318 321 319 - if (xs->dev != xdp->rxq->dev || xs->queue_id != xdp->rxq->queue_index) 322 + if (!dev->_rx[qid].pool || xs->umem != dev->_rx[qid].pool->umem) 320 323 return -EINVAL; 321 324 322 325 if (len > xsk_pool_get_rx_frame_size(xs->pool) && !xs->sg) {
+2 -2
net/xfrm/xfrm_interface_bpf.c
··· 93 93 94 94 __bpf_kfunc_end_defs(); 95 95 96 - BTF_SET8_START(xfrm_ifc_kfunc_set) 96 + BTF_KFUNCS_START(xfrm_ifc_kfunc_set) 97 97 BTF_ID_FLAGS(func, bpf_skb_get_xfrm_info) 98 98 BTF_ID_FLAGS(func, bpf_skb_set_xfrm_info) 99 - BTF_SET8_END(xfrm_ifc_kfunc_set) 99 + BTF_KFUNCS_END(xfrm_ifc_kfunc_set) 100 100 101 101 static const struct btf_kfunc_id_set xfrm_interface_kfunc_set = { 102 102 .owner = THIS_MODULE,
+2 -2
net/xfrm/xfrm_state_bpf.c
··· 117 117 118 118 __bpf_kfunc_end_defs(); 119 119 120 - BTF_SET8_START(xfrm_state_kfunc_set) 120 + BTF_KFUNCS_START(xfrm_state_kfunc_set) 121 121 BTF_ID_FLAGS(func, bpf_xdp_get_xfrm_state, KF_RET_NULL | KF_ACQUIRE) 122 122 BTF_ID_FLAGS(func, bpf_xdp_xfrm_state_release, KF_RELEASE) 123 - BTF_SET8_END(xfrm_state_kfunc_set) 123 + BTF_KFUNCS_END(xfrm_state_kfunc_set) 124 124 125 125 static const struct btf_kfunc_id_set xfrm_state_xdp_kfunc_set = { 126 126 .owner = THIS_MODULE,
+1 -1
samples/bpf/map_perf_test_user.c
··· 370 370 371 371 static void fill_lpm_trie(void) 372 372 { 373 - struct bpf_lpm_trie_key *key; 373 + struct bpf_lpm_trie_key_u8 *key; 374 374 unsigned long value = 0; 375 375 unsigned int i; 376 376 int r;
+1 -1
samples/bpf/xdp_router_ipv4_user.c
··· 91 91 static void read_route(struct nlmsghdr *nh, int nll) 92 92 { 93 93 char dsts[24], gws[24], ifs[16], dsts_len[24], metrics[24]; 94 - struct bpf_lpm_trie_key *prefix_key; 94 + struct bpf_lpm_trie_key_u8 *prefix_key; 95 95 struct rtattr *rt_attr; 96 96 struct rtmsg *rt_msg; 97 97 int rtm_family;
+1 -1
scripts/bpf_doc.py
··· 827 827 print(' *{}{}'.format(' \t' if line else '', line)) 828 828 829 829 print(' */') 830 - print('static %s %s(*%s)(' % (self.map_type(proto['ret_type']), 830 + print('static %s %s(* const %s)(' % (self.map_type(proto['ret_type']), 831 831 proto['ret_star'], proto['name']), end='') 832 832 comma = '' 833 833 for i, a in enumerate(proto['args']):
+52 -6
tools/bpf/bpftool/Documentation/bpftool-gen.rst
··· 257 257 return 0; 258 258 } 259 259 260 - This is example BPF application with two BPF programs and a mix of BPF maps 261 - and global variables. Source code is split across two source code files. 260 + **$ cat example3.bpf.c** 261 + 262 + :: 263 + 264 + #include <linux/ptrace.h> 265 + #include <linux/bpf.h> 266 + #include <bpf/bpf_helpers.h> 267 + /* This header file is provided by the bpf_testmod module. */ 268 + #include "bpf_testmod.h" 269 + 270 + int test_2_result = 0; 271 + 272 + /* bpf_Testmod.ko calls this function, passing a "4" 273 + * and testmod_map->data. 274 + */ 275 + SEC("struct_ops/test_2") 276 + void BPF_PROG(test_2, int a, int b) 277 + { 278 + test_2_result = a + b; 279 + } 280 + 281 + SEC(".struct_ops") 282 + struct bpf_testmod_ops testmod_map = { 283 + .test_2 = (void *)test_2, 284 + .data = 0x1, 285 + }; 286 + 287 + This is example BPF application with three BPF programs and a mix of BPF 288 + maps and global variables. Source code is split across three source code 289 + files. 262 290 263 291 **$ clang --target=bpf -g example1.bpf.c -o example1.bpf.o** 264 292 265 293 **$ clang --target=bpf -g example2.bpf.c -o example2.bpf.o** 266 294 267 - **$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o** 295 + **$ clang --target=bpf -g example3.bpf.c -o example3.bpf.o** 268 296 269 - This set of commands compiles *example1.bpf.c* and *example2.bpf.c* 270 - individually and then statically links respective object files into the final 271 - BPF ELF object file *example.bpf.o*. 297 + **$ bpftool gen object example.bpf.o example1.bpf.o example2.bpf.o example3.bpf.o** 298 + 299 + This set of commands compiles *example1.bpf.c*, *example2.bpf.c* and 300 + *example3.bpf.c* individually and then statically links respective object 301 + files into the final BPF ELF object file *example.bpf.o*. 272 302 273 303 **$ bpftool gen skeleton example.bpf.o name example | tee example.skel.h** 274 304 ··· 321 291 struct bpf_map *data; 322 292 struct bpf_map *bss; 323 293 struct bpf_map *my_map; 294 + struct bpf_map *testmod_map; 324 295 } maps; 296 + struct { 297 + struct example__testmod_map__bpf_testmod_ops { 298 + const struct bpf_program *test_1; 299 + const struct bpf_program *test_2; 300 + int data; 301 + } *testmod_map; 302 + } struct_ops; 325 303 struct { 326 304 struct bpf_program *handle_sys_enter; 327 305 struct bpf_program *handle_sys_exit; ··· 342 304 struct { 343 305 int x; 344 306 } data; 307 + int test_2_result; 345 308 } *bss; 346 309 struct example__data { 347 310 _Bool global_flag; ··· 381 342 382 343 skel->rodata->param1 = 128; 383 344 345 + /* Change the value through the pointer of shadow type */ 346 + skel->struct_ops.testmod_map->data = 13; 347 + 384 348 err = example__load(skel); 385 349 if (err) 386 350 goto cleanup; 351 + 352 + /* The result of the function test_2() */ 353 + printf("test_2_result: %d\n", skel->bss->test_2_result); 387 354 388 355 err = example__attach(skel); 389 356 if (err) ··· 417 372 418 373 :: 419 374 375 + test_2_result: 17 420 376 my_map name: my_map 421 377 sys_enter prog FD: 8 422 378 my_static_var: 7
+242 -4
tools/bpf/bpftool/gen.c
··· 7 7 #include <ctype.h> 8 8 #include <errno.h> 9 9 #include <fcntl.h> 10 + #include <libgen.h> 10 11 #include <linux/err.h> 11 12 #include <stdbool.h> 12 13 #include <stdio.h> ··· 55 54 return true; 56 55 } 57 56 57 + static const struct btf_type * 58 + resolve_func_ptr(const struct btf *btf, __u32 id, __u32 *res_id) 59 + { 60 + const struct btf_type *t; 61 + 62 + t = skip_mods_and_typedefs(btf, id, NULL); 63 + if (!btf_is_ptr(t)) 64 + return NULL; 65 + 66 + t = skip_mods_and_typedefs(btf, t->type, res_id); 67 + 68 + return btf_is_func_proto(t) ? t : NULL; 69 + } 70 + 58 71 static void get_obj_name(char *name, const char *file) 59 72 { 60 - /* Using basename() GNU version which doesn't modify arg. */ 61 - strncpy(name, basename(file), MAX_OBJ_NAME_LEN - 1); 62 - name[MAX_OBJ_NAME_LEN - 1] = '\0'; 73 + char file_copy[PATH_MAX]; 74 + 75 + /* Using basename() POSIX version to be more portable. */ 76 + strncpy(file_copy, file, PATH_MAX - 1)[PATH_MAX - 1] = '\0'; 77 + strncpy(name, basename(file_copy), MAX_OBJ_NAME_LEN - 1)[MAX_OBJ_NAME_LEN - 1] = '\0'; 63 78 if (str_has_suffix(name, ".o")) 64 79 name[strlen(name) - 2] = '\0'; 65 80 sanitize_identifier(name); ··· 923 906 } 924 907 } 925 908 909 + static int walk_st_ops_shadow_vars(struct btf *btf, const char *ident, 910 + const struct btf_type *map_type, __u32 map_type_id) 911 + { 912 + LIBBPF_OPTS(btf_dump_emit_type_decl_opts, opts, .indent_level = 3); 913 + const struct btf_type *member_type; 914 + __u32 offset, next_offset = 0; 915 + const struct btf_member *m; 916 + struct btf_dump *d = NULL; 917 + const char *member_name; 918 + __u32 member_type_id; 919 + int i, err = 0, n; 920 + int size; 921 + 922 + d = btf_dump__new(btf, codegen_btf_dump_printf, NULL, NULL); 923 + if (!d) 924 + return -errno; 925 + 926 + n = btf_vlen(map_type); 927 + for (i = 0, m = btf_members(map_type); i < n; i++, m++) { 928 + member_type = skip_mods_and_typedefs(btf, m->type, &member_type_id); 929 + member_name = btf__name_by_offset(btf, m->name_off); 930 + 931 + offset = m->offset / 8; 932 + if (next_offset < offset) 933 + printf("\t\t\tchar __padding_%d[%d];\n", i, offset - next_offset); 934 + 935 + switch (btf_kind(member_type)) { 936 + case BTF_KIND_INT: 937 + case BTF_KIND_FLOAT: 938 + case BTF_KIND_ENUM: 939 + case BTF_KIND_ENUM64: 940 + /* scalar type */ 941 + printf("\t\t\t"); 942 + opts.field_name = member_name; 943 + err = btf_dump__emit_type_decl(d, member_type_id, &opts); 944 + if (err) { 945 + p_err("Failed to emit type declaration for %s: %d", member_name, err); 946 + goto out; 947 + } 948 + printf(";\n"); 949 + 950 + size = btf__resolve_size(btf, member_type_id); 951 + if (size < 0) { 952 + p_err("Failed to resolve size of %s: %d\n", member_name, size); 953 + err = size; 954 + goto out; 955 + } 956 + 957 + next_offset = offset + size; 958 + break; 959 + 960 + case BTF_KIND_PTR: 961 + if (resolve_func_ptr(btf, m->type, NULL)) { 962 + /* Function pointer */ 963 + printf("\t\t\tstruct bpf_program *%s;\n", member_name); 964 + 965 + next_offset = offset + sizeof(void *); 966 + break; 967 + } 968 + /* All pointer types are unsupported except for 969 + * function pointers. 970 + */ 971 + fallthrough; 972 + 973 + default: 974 + /* Unsupported types 975 + * 976 + * Types other than scalar types and function 977 + * pointers are currently not supported in order to 978 + * prevent conflicts in the generated code caused 979 + * by multiple definitions. For instance, if the 980 + * struct type FOO is used in a struct_ops map, 981 + * bpftool has to generate definitions for FOO, 982 + * which may result in conflicts if FOO is defined 983 + * in different skeleton files. 984 + */ 985 + size = btf__resolve_size(btf, member_type_id); 986 + if (size < 0) { 987 + p_err("Failed to resolve size of %s: %d\n", member_name, size); 988 + err = size; 989 + goto out; 990 + } 991 + printf("\t\t\tchar __unsupported_%d[%d];\n", i, size); 992 + 993 + next_offset = offset + size; 994 + break; 995 + } 996 + } 997 + 998 + /* Cannot fail since it must be a struct type */ 999 + size = btf__resolve_size(btf, map_type_id); 1000 + if (next_offset < (__u32)size) 1001 + printf("\t\t\tchar __padding_end[%d];\n", size - next_offset); 1002 + 1003 + out: 1004 + btf_dump__free(d); 1005 + 1006 + return err; 1007 + } 1008 + 1009 + /* Generate the pointer of the shadow type for a struct_ops map. 1010 + * 1011 + * This function adds a pointer of the shadow type for a struct_ops map. 1012 + * The members of a struct_ops map can be exported through a pointer to a 1013 + * shadow type. The user can access these members through the pointer. 1014 + * 1015 + * A shadow type includes not all members, only members of some types. 1016 + * They are scalar types and function pointers. The function pointers are 1017 + * translated to the pointer of the struct bpf_program. The scalar types 1018 + * are translated to the original type without any modifiers. 1019 + * 1020 + * Unsupported types will be translated to a char array to occupy the same 1021 + * space as the original field, being renamed as __unsupported_*. The user 1022 + * should treat these fields as opaque data. 1023 + */ 1024 + static int gen_st_ops_shadow_type(const char *obj_name, struct btf *btf, const char *ident, 1025 + const struct bpf_map *map) 1026 + { 1027 + const struct btf_type *map_type; 1028 + const char *type_name; 1029 + __u32 map_type_id; 1030 + int err; 1031 + 1032 + map_type_id = bpf_map__btf_value_type_id(map); 1033 + if (map_type_id == 0) 1034 + return -EINVAL; 1035 + map_type = btf__type_by_id(btf, map_type_id); 1036 + if (!map_type) 1037 + return -EINVAL; 1038 + 1039 + type_name = btf__name_by_offset(btf, map_type->name_off); 1040 + 1041 + printf("\t\tstruct %s__%s__%s {\n", obj_name, ident, type_name); 1042 + 1043 + err = walk_st_ops_shadow_vars(btf, ident, map_type, map_type_id); 1044 + if (err) 1045 + return err; 1046 + 1047 + printf("\t\t} *%s;\n", ident); 1048 + 1049 + return 0; 1050 + } 1051 + 1052 + static int gen_st_ops_shadow(const char *obj_name, struct btf *btf, struct bpf_object *obj) 1053 + { 1054 + int err, st_ops_cnt = 0; 1055 + struct bpf_map *map; 1056 + char ident[256]; 1057 + 1058 + if (!btf) 1059 + return 0; 1060 + 1061 + /* Generate the pointers to shadow types of 1062 + * struct_ops maps. 1063 + */ 1064 + bpf_object__for_each_map(map, obj) { 1065 + if (bpf_map__type(map) != BPF_MAP_TYPE_STRUCT_OPS) 1066 + continue; 1067 + if (!get_map_ident(map, ident, sizeof(ident))) 1068 + continue; 1069 + 1070 + if (st_ops_cnt == 0) /* first struct_ops map */ 1071 + printf("\tstruct {\n"); 1072 + st_ops_cnt++; 1073 + 1074 + err = gen_st_ops_shadow_type(obj_name, btf, ident, map); 1075 + if (err) 1076 + return err; 1077 + } 1078 + 1079 + if (st_ops_cnt) 1080 + printf("\t} struct_ops;\n"); 1081 + 1082 + return 0; 1083 + } 1084 + 1085 + /* Generate the code to initialize the pointers of shadow types. */ 1086 + static void gen_st_ops_shadow_init(struct btf *btf, struct bpf_object *obj) 1087 + { 1088 + struct bpf_map *map; 1089 + char ident[256]; 1090 + 1091 + if (!btf) 1092 + return; 1093 + 1094 + /* Initialize the pointers to_ops shadow types of 1095 + * struct_ops maps. 1096 + */ 1097 + bpf_object__for_each_map(map, obj) { 1098 + if (bpf_map__type(map) != BPF_MAP_TYPE_STRUCT_OPS) 1099 + continue; 1100 + if (!get_map_ident(map, ident, sizeof(ident))) 1101 + continue; 1102 + codegen("\ 1103 + \n\ 1104 + obj->struct_ops.%1$s = bpf_map__initial_value(obj->maps.%1$s, NULL);\n\ 1105 + \n\ 1106 + ", ident); 1107 + } 1108 + } 1109 + 926 1110 static int do_skeleton(int argc, char **argv) 927 1111 { 928 1112 char header_guard[MAX_OBJ_NAME_LEN + sizeof("__SKEL_H__")]; ··· 1267 1049 printf("\t} maps;\n"); 1268 1050 } 1269 1051 1052 + btf = bpf_object__btf(obj); 1053 + err = gen_st_ops_shadow(obj_name, btf, obj); 1054 + if (err) 1055 + goto out; 1056 + 1270 1057 if (prog_cnt) { 1271 1058 printf("\tstruct {\n"); 1272 1059 bpf_object__for_each_program(prog, obj) { ··· 1295 1072 printf("\t} links;\n"); 1296 1073 } 1297 1074 1298 - btf = bpf_object__btf(obj); 1299 1075 if (btf) { 1300 1076 err = codegen_datasecs(obj, obj_name); 1301 1077 if (err) ··· 1352 1130 if (err) \n\ 1353 1131 goto err_out; \n\ 1354 1132 \n\ 1133 + ", obj_name); 1134 + 1135 + gen_st_ops_shadow_init(btf, obj); 1136 + 1137 + codegen("\ 1138 + \n\ 1355 1139 return obj; \n\ 1356 1140 err_out: \n\ 1357 1141 %1$s__destroy(obj); \n\ ··· 1667 1439 printf("\t} maps;\n"); 1668 1440 } 1669 1441 1442 + err = gen_st_ops_shadow(obj_name, btf, obj); 1443 + if (err) 1444 + goto out; 1445 + 1670 1446 if (prog_cnt) { 1671 1447 printf("\tstruct {\n"); 1672 1448 bpf_object__for_each_program(prog, obj) { ··· 1782 1550 if (err) \n\ 1783 1551 goto err; \n\ 1784 1552 \n\ 1553 + "); 1554 + 1555 + gen_st_ops_shadow_init(btf, obj); 1556 + 1557 + codegen("\ 1558 + \n\ 1785 1559 return obj; \n\ 1786 1560 err: \n\ 1787 1561 %1$s__destroy(obj); \n\
+56 -14
tools/bpf/resolve_btfids/main.c
··· 70 70 #include <sys/stat.h> 71 71 #include <fcntl.h> 72 72 #include <errno.h> 73 + #include <linux/btf_ids.h> 73 74 #include <linux/rbtree.h> 74 75 #include <linux/zalloc.h> 75 76 #include <linux/err.h> ··· 79 78 #include <subcmd/parse-options.h> 80 79 81 80 #define BTF_IDS_SECTION ".BTF_ids" 82 - #define BTF_ID "__BTF_ID__" 81 + #define BTF_ID_PREFIX "__BTF_ID__" 83 82 84 83 #define BTF_STRUCT "struct" 85 84 #define BTF_UNION "union" ··· 89 88 #define BTF_SET8 "set8" 90 89 91 90 #define ADDR_CNT 100 91 + 92 + #if __BYTE_ORDER == __LITTLE_ENDIAN 93 + # define ELFDATANATIVE ELFDATA2LSB 94 + #elif __BYTE_ORDER == __BIG_ENDIAN 95 + # define ELFDATANATIVE ELFDATA2MSB 96 + #else 97 + # error "Unknown machine endianness!" 98 + #endif 92 99 93 100 struct btf_id { 94 101 struct rb_node rb_node; ··· 125 116 int idlist_shndx; 126 117 size_t strtabidx; 127 118 unsigned long idlist_addr; 119 + int encoding; 128 120 } efile; 129 121 130 122 struct rb_root sets; ··· 171 161 172 162 static bool is_btf_id(const char *name) 173 163 { 174 - return name && !strncmp(name, BTF_ID, sizeof(BTF_ID) - 1); 164 + return name && !strncmp(name, BTF_ID_PREFIX, sizeof(BTF_ID_PREFIX) - 1); 175 165 } 176 166 177 167 static struct btf_id *btf_id__find(struct rb_root *root, const char *name) ··· 329 319 { 330 320 Elf_Scn *scn = NULL; 331 321 size_t shdrstrndx; 322 + GElf_Ehdr ehdr; 332 323 int idx = 0; 333 324 Elf *elf; 334 325 int fd; ··· 360 349 pr_err("FAILED cannot get shdr str ndx\n"); 361 350 return -1; 362 351 } 352 + 353 + if (gelf_getehdr(obj->efile.elf, &ehdr) == NULL) { 354 + pr_err("FAILED cannot get ELF header: %s\n", 355 + elf_errmsg(-1)); 356 + return -1; 357 + } 358 + obj->efile.encoding = ehdr.e_ident[EI_DATA]; 363 359 364 360 /* 365 361 * Scan all the elf sections and look for save data ··· 459 441 * __BTF_ID__TYPE__vfs_truncate__0 460 442 * prefix = ^ 461 443 */ 462 - prefix = name + sizeof(BTF_ID) - 1; 444 + prefix = name + sizeof(BTF_ID_PREFIX) - 1; 463 445 464 446 /* struct */ 465 447 if (!strncmp(prefix, BTF_STRUCT, sizeof(BTF_STRUCT) - 1)) { ··· 667 649 static int sets_patch(struct object *obj) 668 650 { 669 651 Elf_Data *data = obj->efile.idlist; 670 - int *ptr = data->d_buf; 671 652 struct rb_node *next; 672 653 673 654 next = rb_first(&obj->sets); 674 655 while (next) { 675 - unsigned long addr, idx; 656 + struct btf_id_set8 *set8; 657 + struct btf_id_set *set; 658 + unsigned long addr, off; 676 659 struct btf_id *id; 677 - int *base; 678 - int cnt; 679 660 680 661 id = rb_entry(next, struct btf_id, rb_node); 681 662 addr = id->addr[0]; 682 - idx = addr - obj->efile.idlist_addr; 663 + off = addr - obj->efile.idlist_addr; 683 664 684 665 /* sets are unique */ 685 666 if (id->addr_cnt != 1) { ··· 687 670 return -1; 688 671 } 689 672 690 - idx = idx / sizeof(int); 691 - base = &ptr[idx] + (id->is_set8 ? 2 : 1); 692 - cnt = ptr[idx]; 673 + if (id->is_set) { 674 + set = data->d_buf + off; 675 + qsort(set->ids, set->cnt, sizeof(set->ids[0]), cmp_id); 676 + } else { 677 + set8 = data->d_buf + off; 678 + /* 679 + * Make sure id is at the beginning of the pairs 680 + * struct, otherwise the below qsort would not work. 681 + */ 682 + BUILD_BUG_ON(set8->pairs != &set8->pairs[0].id); 683 + qsort(set8->pairs, set8->cnt, sizeof(set8->pairs[0]), cmp_id); 684 + 685 + /* 686 + * When ELF endianness does not match endianness of the 687 + * host, libelf will do the translation when updating 688 + * the ELF. This, however, corrupts SET8 flags which are 689 + * already in the target endianness. So, let's bswap 690 + * them to the host endianness and libelf will then 691 + * correctly translate everything. 692 + */ 693 + if (obj->efile.encoding != ELFDATANATIVE) { 694 + int i; 695 + 696 + set8->flags = bswap_32(set8->flags); 697 + for (i = 0; i < set8->cnt; i++) { 698 + set8->pairs[i].flags = 699 + bswap_32(set8->pairs[i].flags); 700 + } 701 + } 702 + } 693 703 694 704 pr_debug("sorting addr %5lu: cnt %6d [%s]\n", 695 - (idx + 1) * sizeof(int), cnt, id->name); 696 - 697 - qsort(base, cnt, id->is_set8 ? sizeof(uint64_t) : sizeof(int), cmp_id); 705 + off, id->is_set ? set->cnt : set8->cnt, id->name); 698 706 699 707 next = rb_next(next); 700 708 }
+9
tools/include/linux/btf_ids.h
··· 8 8 u32 ids[]; 9 9 }; 10 10 11 + struct btf_id_set8 { 12 + u32 cnt; 13 + u32 flags; 14 + struct { 15 + u32 id; 16 + u32 flags; 17 + } pairs[]; 18 + }; 19 + 11 20 #ifdef CONFIG_DEBUG_INFO_BTF 12 21 13 22 #include <linux/compiler.h> /* for __PASTE */
+23 -2
tools/include/uapi/linux/bpf.h
··· 77 77 __s32 imm; /* signed immediate constant */ 78 78 }; 79 79 80 - /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */ 80 + /* Deprecated: use struct bpf_lpm_trie_key_u8 (when the "data" member is needed for 81 + * byte access) or struct bpf_lpm_trie_key_hdr (when using an alternative type for 82 + * the trailing flexible array member) instead. 83 + */ 81 84 struct bpf_lpm_trie_key { 82 85 __u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */ 83 86 __u8 data[0]; /* Arbitrary size */ 87 + }; 88 + 89 + /* Header for bpf_lpm_trie_key structs */ 90 + struct bpf_lpm_trie_key_hdr { 91 + __u32 prefixlen; 92 + }; 93 + 94 + /* Key of an a BPF_MAP_TYPE_LPM_TRIE entry, with trailing byte array. */ 95 + struct bpf_lpm_trie_key_u8 { 96 + union { 97 + struct bpf_lpm_trie_key_hdr hdr; 98 + __u32 prefixlen; 99 + }; 100 + __u8 data[]; /* Arbitrary size */ 84 101 }; 85 102 86 103 struct bpf_cgroup_storage_key { ··· 634 617 * to NULL to begin the batched operation. After each subsequent 635 618 * **BPF_MAP_LOOKUP_BATCH**, the caller should pass the resultant 636 619 * *out_batch* as the *in_batch* for the next operation to 637 - * continue iteration from the current point. 620 + * continue iteration from the current point. Both *in_batch* and 621 + * *out_batch* must point to memory large enough to hold a key, 622 + * except for maps of type **BPF_MAP_TYPE_{HASH, PERCPU_HASH, 623 + * LRU_HASH, LRU_PERCPU_HASH}**, for which batch parameters 624 + * must be at least 4 bytes wide regardless of key size. 638 625 * 639 626 * The *keys* and *values* are output parameters which must point 640 627 * to memory large enough to hold *count* items based on the key
+30 -11
tools/lib/bpf/bpf.h
··· 35 35 extern "C" { 36 36 #endif 37 37 38 - int libbpf_set_memlock_rlim(size_t memlock_bytes); 38 + LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes); 39 39 40 40 struct bpf_map_create_opts { 41 41 size_t sz; /* size of this struct for forward/backward compatibility */ ··· 190 190 /** 191 191 * @brief **bpf_map_lookup_batch()** allows for batch lookup of BPF map elements. 192 192 * 193 - * The parameter *in_batch* is the address of the first element in the batch to read. 194 - * *out_batch* is an output parameter that should be passed as *in_batch* to subsequent 195 - * calls to **bpf_map_lookup_batch()**. NULL can be passed for *in_batch* to indicate 196 - * that the batched lookup starts from the beginning of the map. 193 + * The parameter *in_batch* is the address of the first element in the batch to 194 + * read. *out_batch* is an output parameter that should be passed as *in_batch* 195 + * to subsequent calls to **bpf_map_lookup_batch()**. NULL can be passed for 196 + * *in_batch* to indicate that the batched lookup starts from the beginning of 197 + * the map. Both *in_batch* and *out_batch* must point to memory large enough to 198 + * hold a single key, except for maps of type **BPF_MAP_TYPE_{HASH, PERCPU_HASH, 199 + * LRU_HASH, LRU_PERCPU_HASH}**, for which the memory size must be at 200 + * least 4 bytes wide regardless of key size. 197 201 * 198 202 * The *keys* and *values* are output parameters which must point to memory large enough to 199 203 * hold *count* items based on the key and value size of the map *map_fd*. The *keys* ··· 230 226 * 231 227 * @param fd BPF map file descriptor 232 228 * @param in_batch address of the first element in batch to read, can pass NULL to 233 - * get address of the first element in *out_batch* 229 + * get address of the first element in *out_batch*. If not NULL, must be large 230 + * enough to hold a key. For **BPF_MAP_TYPE_{HASH, PERCPU_HASH, LRU_HASH, 231 + * LRU_PERCPU_HASH}**, the memory size must be at least 4 bytes wide regardless 232 + * of key size. 234 233 * @param out_batch output parameter that should be passed to next call as *in_batch* 235 234 * @param keys pointer to an array of *count* keys 236 235 * @param values pointer to an array large enough for *count* values ··· 507 500 * program corresponding to *prog_fd*. 508 501 * 509 502 * Populates up to *info_len* bytes of *info* and updates *info_len* with the 510 - * actual number of bytes written to *info*. 503 + * actual number of bytes written to *info*. Note that *info* should be 504 + * zero-initialized or initialized as expected by the requested *info* 505 + * type. Failing to (zero-)initialize *info* under certain circumstances can 506 + * result in this helper returning an error. 511 507 * 512 508 * @param prog_fd BPF program file descriptor 513 509 * @param info pointer to **struct bpf_prog_info** that will be populated with ··· 527 517 * map corresponding to *map_fd*. 528 518 * 529 519 * Populates up to *info_len* bytes of *info* and updates *info_len* with the 530 - * actual number of bytes written to *info*. 520 + * actual number of bytes written to *info*. Note that *info* should be 521 + * zero-initialized or initialized as expected by the requested *info* 522 + * type. Failing to (zero-)initialize *info* under certain circumstances can 523 + * result in this helper returning an error. 531 524 * 532 525 * @param map_fd BPF map file descriptor 533 526 * @param info pointer to **struct bpf_map_info** that will be populated with ··· 543 530 LIBBPF_API int bpf_map_get_info_by_fd(int map_fd, struct bpf_map_info *info, __u32 *info_len); 544 531 545 532 /** 546 - * @brief **bpf_btf_get_info_by_fd()** obtains information about the 533 + * @brief **bpf_btf_get_info_by_fd()** obtains information about the 547 534 * BTF object corresponding to *btf_fd*. 548 535 * 549 536 * Populates up to *info_len* bytes of *info* and updates *info_len* with the 550 - * actual number of bytes written to *info*. 537 + * actual number of bytes written to *info*. Note that *info* should be 538 + * zero-initialized or initialized as expected by the requested *info* 539 + * type. Failing to (zero-)initialize *info* under certain circumstances can 540 + * result in this helper returning an error. 551 541 * 552 542 * @param btf_fd BTF object file descriptor 553 543 * @param info pointer to **struct bpf_btf_info** that will be populated with ··· 567 551 * link corresponding to *link_fd*. 568 552 * 569 553 * Populates up to *info_len* bytes of *info* and updates *info_len* with the 570 - * actual number of bytes written to *info*. 554 + * actual number of bytes written to *info*. Note that *info* should be 555 + * zero-initialized or initialized as expected by the requested *info* 556 + * type. Failing to (zero-)initialize *info* under certain circumstances can 557 + * result in this helper returning an error. 571 558 * 572 559 * @param link_fd BPF link file descriptor 573 560 * @param info pointer to **struct bpf_link_info** that will be populated with
+51 -7
tools/lib/bpf/bpf_core_read.h
··· 2 2 #ifndef __BPF_CORE_READ_H__ 3 3 #define __BPF_CORE_READ_H__ 4 4 5 + #include <bpf/bpf_helpers.h> 6 + 5 7 /* 6 8 * enum bpf_field_info_kind is passed as a second argument into 7 9 * __builtin_preserve_field_info() built-in to get a specific aspect of ··· 46 44 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 47 45 #define __CORE_BITFIELD_PROBE_READ(dst, src, fld) \ 48 46 bpf_probe_read_kernel( \ 49 - (void *)dst, \ 47 + (void *)dst, \ 50 48 __CORE_RELO(src, fld, BYTE_SIZE), \ 51 49 (const void *)src + __CORE_RELO(src, fld, BYTE_OFFSET)) 52 50 #else ··· 145 143 } \ 146 144 }) 147 145 146 + /* Differentiator between compilers builtin implementations. This is a 147 + * requirement due to the compiler parsing differences where GCC optimizes 148 + * early in parsing those constructs of type pointers to the builtin specific 149 + * type, resulting in not being possible to collect the required type 150 + * information in the builtin expansion. 151 + */ 152 + #ifdef __clang__ 153 + #define ___bpf_typeof(type) ((typeof(type) *) 0) 154 + #else 155 + #define ___bpf_typeof1(type, NR) ({ \ 156 + extern typeof(type) *___concat(bpf_type_tmp_, NR); \ 157 + ___concat(bpf_type_tmp_, NR); \ 158 + }) 159 + #define ___bpf_typeof(type) ___bpf_typeof1(type, __COUNTER__) 160 + #endif 161 + 162 + #ifdef __clang__ 148 163 #define ___bpf_field_ref1(field) (field) 149 - #define ___bpf_field_ref2(type, field) (((typeof(type) *)0)->field) 164 + #define ___bpf_field_ref2(type, field) (___bpf_typeof(type)->field) 165 + #else 166 + #define ___bpf_field_ref1(field) (&(field)) 167 + #define ___bpf_field_ref2(type, field) (&(___bpf_typeof(type)->field)) 168 + #endif 150 169 #define ___bpf_field_ref(args...) \ 151 170 ___bpf_apply(___bpf_field_ref, ___bpf_narg(args))(args) 152 171 ··· 217 194 * BTF. Always succeeds. 218 195 */ 219 196 #define bpf_core_type_id_local(type) \ 220 - __builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_LOCAL) 197 + __builtin_btf_type_id(*___bpf_typeof(type), BPF_TYPE_ID_LOCAL) 221 198 222 199 /* 223 200 * Convenience macro to get BTF type ID of a target kernel's type that matches ··· 227 204 * - 0, if no matching type was found in a target kernel BTF. 228 205 */ 229 206 #define bpf_core_type_id_kernel(type) \ 230 - __builtin_btf_type_id(*(typeof(type) *)0, BPF_TYPE_ID_TARGET) 207 + __builtin_btf_type_id(*___bpf_typeof(type), BPF_TYPE_ID_TARGET) 231 208 232 209 /* 233 210 * Convenience macro to check that provided named type ··· 237 214 * 0, if no matching type is found. 238 215 */ 239 216 #define bpf_core_type_exists(type) \ 240 - __builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_EXISTS) 217 + __builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_EXISTS) 241 218 242 219 /* 243 220 * Convenience macro to check that provided named type ··· 247 224 * 0, if the type does not match any in the target kernel 248 225 */ 249 226 #define bpf_core_type_matches(type) \ 250 - __builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_MATCHES) 227 + __builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_MATCHES) 251 228 252 229 /* 253 230 * Convenience macro to get the byte size of a provided named type ··· 257 234 * 0, if no matching type is found. 258 235 */ 259 236 #define bpf_core_type_size(type) \ 260 - __builtin_preserve_type_info(*(typeof(type) *)0, BPF_TYPE_SIZE) 237 + __builtin_preserve_type_info(*___bpf_typeof(type), BPF_TYPE_SIZE) 261 238 262 239 /* 263 240 * Convenience macro to check that provided enumerator value is defined in ··· 267 244 * kernel's BTF; 268 245 * 0, if no matching enum and/or enum value within that enum is found. 269 246 */ 247 + #ifdef __clang__ 270 248 #define bpf_core_enum_value_exists(enum_type, enum_value) \ 271 249 __builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_EXISTS) 250 + #else 251 + #define bpf_core_enum_value_exists(enum_type, enum_value) \ 252 + __builtin_preserve_enum_value(___bpf_typeof(enum_type), enum_value, BPF_ENUMVAL_EXISTS) 253 + #endif 272 254 273 255 /* 274 256 * Convenience macro to get the integer value of an enumerator value in ··· 283 255 * present in target kernel's BTF; 284 256 * 0, if no matching enum and/or enum value within that enum is found. 285 257 */ 258 + #ifdef __clang__ 286 259 #define bpf_core_enum_value(enum_type, enum_value) \ 287 260 __builtin_preserve_enum_value(*(typeof(enum_type) *)enum_value, BPF_ENUMVAL_VALUE) 261 + #else 262 + #define bpf_core_enum_value(enum_type, enum_value) \ 263 + __builtin_preserve_enum_value(___bpf_typeof(enum_type), enum_value, BPF_ENUMVAL_VALUE) 264 + #endif 288 265 289 266 /* 290 267 * bpf_core_read() abstracts away bpf_probe_read_kernel() call and captures ··· 324 291 /* NOTE: see comments for BPF_CORE_READ_USER() about the proper types use. */ 325 292 #define bpf_core_read_user_str(dst, sz, src) \ 326 293 bpf_probe_read_user_str(dst, sz, (const void *)__builtin_preserve_access_index(src)) 294 + 295 + extern void *bpf_rdonly_cast(const void *obj, __u32 btf_id) __ksym __weak; 296 + 297 + /* 298 + * Cast provided pointer *ptr* into a pointer to a specified *type* in such 299 + * a way that BPF verifier will become aware of associated kernel-side BTF 300 + * type. This allows to access members of kernel types directly without the 301 + * need to use BPF_CORE_READ() macros. 302 + */ 303 + #define bpf_core_cast(ptr, type) \ 304 + ((typeof(type) *)bpf_rdonly_cast((ptr), bpf_core_type_id_kernel(type))) 327 305 328 306 #define ___concat(a, b) a ## b 329 307 #define ___apply(fn, n) ___concat(fn, n)
+2
tools/lib/bpf/bpf_helpers.h
··· 190 190 191 191 #define __arg_ctx __attribute__((btf_decl_tag("arg:ctx"))) 192 192 #define __arg_nonnull __attribute((btf_decl_tag("arg:nonnull"))) 193 + #define __arg_nullable __attribute((btf_decl_tag("arg:nullable"))) 194 + #define __arg_trusted __attribute((btf_decl_tag("arg:trusted"))) 193 195 194 196 #ifndef ___bpf_concat 195 197 #define ___bpf_concat(a, b) a ## b
+28 -5
tools/lib/bpf/btf.c
··· 1079 1079 return libbpf_ptr(btf_new(data, size, NULL)); 1080 1080 } 1081 1081 1082 + struct btf *btf__new_split(const void *data, __u32 size, struct btf *base_btf) 1083 + { 1084 + return libbpf_ptr(btf_new(data, size, base_btf)); 1085 + } 1086 + 1082 1087 static struct btf *btf_parse_elf(const char *path, struct btf *base_btf, 1083 1088 struct btf_ext **btf_ext) 1084 1089 { ··· 3050 3045 return btf_ext; 3051 3046 } 3052 3047 3053 - const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size) 3048 + const void *btf_ext__raw_data(const struct btf_ext *btf_ext, __u32 *size) 3054 3049 { 3055 3050 *size = btf_ext->data_size; 3056 3051 return btf_ext->data; 3057 3052 } 3053 + 3054 + __attribute__((alias("btf_ext__raw_data"))) 3055 + const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size); 3056 + 3058 3057 3059 3058 struct btf_dedup; 3060 3059 ··· 4941 4932 */ 4942 4933 struct btf *btf__load_vmlinux_btf(void) 4943 4934 { 4935 + const char *sysfs_btf_path = "/sys/kernel/btf/vmlinux"; 4936 + /* fall back locations, trying to find vmlinux on disk */ 4944 4937 const char *locations[] = { 4945 - /* try canonical vmlinux BTF through sysfs first */ 4946 - "/sys/kernel/btf/vmlinux", 4947 - /* fall back to trying to find vmlinux on disk otherwise */ 4948 4938 "/boot/vmlinux-%1$s", 4949 4939 "/lib/modules/%1$s/vmlinux-%1$s", 4950 4940 "/lib/modules/%1$s/build/vmlinux", ··· 4957 4949 struct btf *btf; 4958 4950 int i, err; 4959 4951 4960 - uname(&buf); 4952 + /* is canonical sysfs location accessible? */ 4953 + if (faccessat(AT_FDCWD, sysfs_btf_path, F_OK, AT_EACCESS) < 0) { 4954 + pr_warn("kernel BTF is missing at '%s', was CONFIG_DEBUG_INFO_BTF enabled?\n", 4955 + sysfs_btf_path); 4956 + } else { 4957 + btf = btf__parse(sysfs_btf_path, NULL); 4958 + if (!btf) { 4959 + err = -errno; 4960 + pr_warn("failed to read kernel BTF from '%s': %d\n", sysfs_btf_path, err); 4961 + return libbpf_err_ptr(err); 4962 + } 4963 + pr_debug("loaded kernel BTF from '%s'\n", path); 4964 + return btf; 4965 + } 4961 4966 4967 + /* try fallback locations */ 4968 + uname(&buf); 4962 4969 for (i = 0; i < ARRAY_SIZE(locations); i++) { 4963 4970 snprintf(path, PATH_MAX, locations[i], buf.release); 4964 4971
+58
tools/lib/bpf/features.c
··· 407 407 strs, sizeof(strs), token_fd)); 408 408 } 409 409 410 + static int probe_kern_arg_ctx_tag(int token_fd) 411 + { 412 + static const char strs[] = "\0a\0b\0arg:ctx\0"; 413 + const __u32 types[] = { 414 + /* [1] INT */ 415 + BTF_TYPE_INT_ENC(1 /* "a" */, BTF_INT_SIGNED, 0, 32, 4), 416 + /* [2] PTR -> VOID */ 417 + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0), 418 + /* [3] FUNC_PROTO `int(void *a)` */ 419 + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 1), 420 + BTF_PARAM_ENC(1 /* "a" */, 2), 421 + /* [4] FUNC 'a' -> FUNC_PROTO (main prog) */ 422 + BTF_TYPE_ENC(1 /* "a" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 3), 423 + /* [5] FUNC_PROTO `int(void *b __arg_ctx)` */ 424 + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 1), 425 + BTF_PARAM_ENC(3 /* "b" */, 2), 426 + /* [6] FUNC 'b' -> FUNC_PROTO (subprog) */ 427 + BTF_TYPE_ENC(3 /* "b" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 5), 428 + /* [7] DECL_TAG 'arg:ctx' -> func 'b' arg 'b' */ 429 + BTF_TYPE_DECL_TAG_ENC(5 /* "arg:ctx" */, 6, 0), 430 + }; 431 + const struct bpf_insn insns[] = { 432 + /* main prog */ 433 + BPF_CALL_REL(+1), 434 + BPF_EXIT_INSN(), 435 + /* global subprog */ 436 + BPF_EMIT_CALL(BPF_FUNC_get_func_ip), /* needs PTR_TO_CTX */ 437 + BPF_EXIT_INSN(), 438 + }; 439 + const struct bpf_func_info_min func_infos[] = { 440 + { 0, 4 }, /* main prog -> FUNC 'a' */ 441 + { 2, 6 }, /* subprog -> FUNC 'b' */ 442 + }; 443 + LIBBPF_OPTS(bpf_prog_load_opts, opts, 444 + .token_fd = token_fd, 445 + .prog_flags = token_fd ? BPF_F_TOKEN_FD : 0, 446 + ); 447 + int prog_fd, btf_fd, insn_cnt = ARRAY_SIZE(insns); 448 + 449 + btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), token_fd); 450 + if (btf_fd < 0) 451 + return 0; 452 + 453 + opts.prog_btf_fd = btf_fd; 454 + opts.func_info = &func_infos; 455 + opts.func_info_cnt = ARRAY_SIZE(func_infos); 456 + opts.func_info_rec_size = sizeof(func_infos[0]); 457 + 458 + prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, "det_arg_ctx", 459 + "GPL", insns, insn_cnt, &opts); 460 + close(btf_fd); 461 + 462 + return probe_fd(prog_fd); 463 + } 464 + 410 465 typedef int (*feature_probe_fn)(int /* token_fd */); 411 466 412 467 static struct kern_feature_cache feature_cache; ··· 530 475 }, 531 476 [FEAT_UPROBE_MULTI_LINK] = { 532 477 "BPF multi-uprobe link support", probe_uprobe_multi_link, 478 + }, 479 + [FEAT_ARG_CTX_TAG] = { 480 + "kernel-side __arg_ctx tag", probe_kern_arg_ctx_tag, 533 481 }, 534 482 }; 535 483
+75 -69
tools/lib/bpf/libbpf.c
··· 33 33 #include <linux/filter.h> 34 34 #include <linux/limits.h> 35 35 #include <linux/perf_event.h> 36 + #include <linux/bpf_perf_event.h> 36 37 #include <linux/ring_buffer.h> 37 38 #include <sys/epoll.h> 38 39 #include <sys/ioctl.h> ··· 1014 1013 return map->def.type == BPF_MAP_TYPE_STRUCT_OPS; 1015 1014 } 1016 1015 1016 + static bool is_valid_st_ops_program(struct bpf_object *obj, 1017 + const struct bpf_program *prog) 1018 + { 1019 + int i; 1020 + 1021 + for (i = 0; i < obj->nr_programs; i++) { 1022 + if (&obj->programs[i] == prog) 1023 + return prog->type == BPF_PROG_TYPE_STRUCT_OPS; 1024 + } 1025 + 1026 + return false; 1027 + } 1028 + 1017 1029 /* Init the map's fields that depend on kern_btf */ 1018 1030 static int bpf_map__init_kern_struct_ops(struct bpf_map *map) 1019 1031 { ··· 1115 1101 if (btf_is_ptr(mtype)) { 1116 1102 struct bpf_program *prog; 1117 1103 1118 - prog = st_ops->progs[i]; 1104 + /* Update the value from the shadow type */ 1105 + prog = *(void **)mdata; 1106 + st_ops->progs[i] = prog; 1119 1107 if (!prog) 1120 1108 continue; 1109 + if (!is_valid_st_ops_program(obj, prog)) { 1110 + pr_warn("struct_ops init_kern %s: member %s is not a struct_ops program\n", 1111 + map->name, mname); 1112 + return -ENOTSUP; 1113 + } 1121 1114 1122 1115 kern_mtype = skip_mods_and_typedefs(kern_btf, 1123 1116 kern_mtype->type, ··· 1249 1228 map->name = strdup(var_name); 1250 1229 if (!map->name) 1251 1230 return -ENOMEM; 1231 + map->btf_value_type_id = type_id; 1252 1232 1253 1233 map->def.type = BPF_MAP_TYPE_STRUCT_OPS; 1254 1234 map->def.key_size = sizeof(int); ··· 1546 1524 return ERR_PTR(-ENOENT); 1547 1525 } 1548 1526 1527 + /* Some versions of Android don't provide memfd_create() in their libc 1528 + * implementation, so avoid complications and just go straight to Linux 1529 + * syscall. 1530 + */ 1531 + static int sys_memfd_create(const char *name, unsigned flags) 1532 + { 1533 + return syscall(__NR_memfd_create, name, flags); 1534 + } 1535 + 1549 1536 static int create_placeholder_fd(void) 1550 1537 { 1551 1538 int fd; 1552 1539 1553 - fd = ensure_good_fd(memfd_create("libbpf-placeholder-fd", MFD_CLOEXEC)); 1540 + fd = ensure_good_fd(sys_memfd_create("libbpf-placeholder-fd", MFD_CLOEXEC)); 1554 1541 if (fd < 0) 1555 1542 return -errno; 1556 1543 return fd; ··· 4691 4660 4692 4661 bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) 4693 4662 { 4694 - if (obj && obj->gen_loader) 4663 + if (obj->gen_loader) 4695 4664 /* To generate loader program assume the latest kernel 4696 4665 * to avoid doing extra prog_load, map_create syscalls. 4697 4666 */ ··· 4878 4847 create_attr.btf_value_type_id = 0; 4879 4848 map->btf_key_type_id = 0; 4880 4849 map->btf_value_type_id = 0; 4850 + break; 4851 + case BPF_MAP_TYPE_STRUCT_OPS: 4852 + create_attr.btf_value_type_id = 0; 4853 + break; 4881 4854 default: 4882 4855 break; 4883 4856 } ··· 6374 6339 /* all other program types don't have "named" context structs */ 6375 6340 }; 6376 6341 6342 + /* forward declarations for arch-specific underlying types of bpf_user_pt_regs_t typedef, 6343 + * for below __builtin_types_compatible_p() checks; 6344 + * with this approach we don't need any extra arch-specific #ifdef guards 6345 + */ 6346 + struct pt_regs; 6347 + struct user_pt_regs; 6348 + struct user_regs_struct; 6349 + 6377 6350 static bool need_func_arg_type_fixup(const struct btf *btf, const struct bpf_program *prog, 6378 6351 const char *subprog_name, int arg_idx, 6379 6352 int arg_type_id, const char *ctx_name) ··· 6422 6379 /* special cases */ 6423 6380 switch (prog->type) { 6424 6381 case BPF_PROG_TYPE_KPROBE: 6425 - case BPF_PROG_TYPE_PERF_EVENT: 6426 6382 /* `struct pt_regs *` is expected, but we need to fix up */ 6427 6383 if (btf_is_struct(t) && strcmp(tname, "pt_regs") == 0) 6384 + return true; 6385 + break; 6386 + case BPF_PROG_TYPE_PERF_EVENT: 6387 + if (__builtin_types_compatible_p(bpf_user_pt_regs_t, struct pt_regs) && 6388 + btf_is_struct(t) && strcmp(tname, "pt_regs") == 0) 6389 + return true; 6390 + if (__builtin_types_compatible_p(bpf_user_pt_regs_t, struct user_pt_regs) && 6391 + btf_is_struct(t) && strcmp(tname, "user_pt_regs") == 0) 6392 + return true; 6393 + if (__builtin_types_compatible_p(bpf_user_pt_regs_t, struct user_regs_struct) && 6394 + btf_is_struct(t) && strcmp(tname, "user_regs_struct") == 0) 6428 6395 return true; 6429 6396 break; 6430 6397 case BPF_PROG_TYPE_RAW_TRACEPOINT: ··· 6515 6462 return fn_id; 6516 6463 } 6517 6464 6518 - static int probe_kern_arg_ctx_tag(void) 6519 - { 6520 - /* To minimize merge conflicts with BPF token series that refactors 6521 - * feature detection code a lot, we don't integrate 6522 - * probe_kern_arg_ctx_tag() into kernel_supports() feature-detection 6523 - * framework yet, doing our own caching internally. 6524 - * This will be cleaned up a bit later when bpf/bpf-next trees settle. 6525 - */ 6526 - static int cached_result = -1; 6527 - static const char strs[] = "\0a\0b\0arg:ctx\0"; 6528 - const __u32 types[] = { 6529 - /* [1] INT */ 6530 - BTF_TYPE_INT_ENC(1 /* "a" */, BTF_INT_SIGNED, 0, 32, 4), 6531 - /* [2] PTR -> VOID */ 6532 - BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 0), 6533 - /* [3] FUNC_PROTO `int(void *a)` */ 6534 - BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 1), 6535 - BTF_PARAM_ENC(1 /* "a" */, 2), 6536 - /* [4] FUNC 'a' -> FUNC_PROTO (main prog) */ 6537 - BTF_TYPE_ENC(1 /* "a" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 3), 6538 - /* [5] FUNC_PROTO `int(void *b __arg_ctx)` */ 6539 - BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 1), 6540 - BTF_PARAM_ENC(3 /* "b" */, 2), 6541 - /* [6] FUNC 'b' -> FUNC_PROTO (subprog) */ 6542 - BTF_TYPE_ENC(3 /* "b" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 5), 6543 - /* [7] DECL_TAG 'arg:ctx' -> func 'b' arg 'b' */ 6544 - BTF_TYPE_DECL_TAG_ENC(5 /* "arg:ctx" */, 6, 0), 6545 - }; 6546 - const struct bpf_insn insns[] = { 6547 - /* main prog */ 6548 - BPF_CALL_REL(+1), 6549 - BPF_EXIT_INSN(), 6550 - /* global subprog */ 6551 - BPF_EMIT_CALL(BPF_FUNC_get_func_ip), /* needs PTR_TO_CTX */ 6552 - BPF_EXIT_INSN(), 6553 - }; 6554 - const struct bpf_func_info_min func_infos[] = { 6555 - { 0, 4 }, /* main prog -> FUNC 'a' */ 6556 - { 2, 6 }, /* subprog -> FUNC 'b' */ 6557 - }; 6558 - LIBBPF_OPTS(bpf_prog_load_opts, opts); 6559 - int prog_fd, btf_fd, insn_cnt = ARRAY_SIZE(insns); 6560 - 6561 - if (cached_result >= 0) 6562 - return cached_result; 6563 - 6564 - btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), 0); 6565 - if (btf_fd < 0) 6566 - return 0; 6567 - 6568 - opts.prog_btf_fd = btf_fd; 6569 - opts.func_info = &func_infos; 6570 - opts.func_info_cnt = ARRAY_SIZE(func_infos); 6571 - opts.func_info_rec_size = sizeof(func_infos[0]); 6572 - 6573 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, "det_arg_ctx", 6574 - "GPL", insns, insn_cnt, &opts); 6575 - close(btf_fd); 6576 - 6577 - cached_result = probe_fd(prog_fd); 6578 - return cached_result; 6579 - } 6580 - 6581 6465 /* Check if main program or global subprog's function prototype has `arg:ctx` 6582 6466 * argument tags, and, if necessary, substitute correct type to match what BPF 6583 6467 * verifier would expect, taking into account specific program type. This ··· 6539 6549 return 0; 6540 6550 6541 6551 /* don't do any fix ups if kernel natively supports __arg_ctx */ 6542 - if (probe_kern_arg_ctx_tag() > 0) 6552 + if (kernel_supports(obj, FEAT_ARG_CTX_TAG)) 6543 6553 return 0; 6544 6554 6545 6555 /* some BPF program types just don't have named context structs, so ··· 9330 9340 return NULL; 9331 9341 } 9332 9342 9333 - /* Collect the reloc from ELF and populate the st_ops->progs[] */ 9343 + /* Collect the reloc from ELF, populate the st_ops->progs[], and update 9344 + * st_ops->data for shadow type. 9345 + */ 9334 9346 static int bpf_object__collect_st_ops_relos(struct bpf_object *obj, 9335 9347 Elf64_Shdr *shdr, Elf_Data *data) 9336 9348 { ··· 9446 9454 } 9447 9455 9448 9456 st_ops->progs[member_idx] = prog; 9457 + 9458 + /* st_ops->data will be exposed to users, being returned by 9459 + * bpf_map__initial_value() as a pointer to the shadow 9460 + * type. All function pointers in the original struct type 9461 + * should be converted to a pointer to struct bpf_program 9462 + * in the shadow type. 9463 + */ 9464 + *((struct bpf_program **)(st_ops->data + moff)) = prog; 9449 9465 } 9450 9466 9451 9467 return 0; ··· 9912 9912 9913 9913 void *bpf_map__initial_value(struct bpf_map *map, size_t *psize) 9914 9914 { 9915 + if (bpf_map__is_struct_ops(map)) { 9916 + if (psize) 9917 + *psize = map->def.value_size; 9918 + return map->st_ops->data; 9919 + } 9920 + 9915 9921 if (!map->mmaped) 9916 9922 return NULL; 9917 9923 *psize = map->def.value_size;
+3 -2
tools/lib/bpf/libbpf.map
··· 245 245 btf__parse_raw_split; 246 246 btf__parse_split; 247 247 btf__new_empty_split; 248 - btf__new_split; 249 248 ring_buffer__epoll_fd; 250 249 } LIBBPF_0.2.0; 251 250 ··· 325 326 bpf_xdp_detach; 326 327 bpf_xdp_query; 327 328 bpf_xdp_query_id; 328 - btf_ext__raw_data; 329 329 libbpf_probe_bpf_helper; 330 330 libbpf_probe_bpf_map_type; 331 331 libbpf_probe_bpf_prog_type; ··· 409 411 } LIBBPF_1.2.0; 410 412 411 413 LIBBPF_1.4.0 { 414 + global: 412 415 bpf_token_create; 416 + btf__new_split; 417 + btf_ext__raw_data; 413 418 } LIBBPF_1.3.0;
+16
tools/lib/bpf/libbpf_internal.h
··· 19 19 #include <libelf.h> 20 20 #include "relo_core.h" 21 21 22 + /* Android's libc doesn't support AT_EACCESS in faccessat() implementation 23 + * ([0]), and just returns -EINVAL even if file exists and is accessible. 24 + * See [1] for issues caused by this. 25 + * 26 + * So just redefine it to 0 on Android. 27 + * 28 + * [0] https://android.googlesource.com/platform/bionic/+/refs/heads/android13-release/libc/bionic/faccessat.cpp#50 29 + * [1] https://github.com/libbpf/libbpf-bootstrap/issues/250#issuecomment-1911324250 30 + */ 31 + #ifdef __ANDROID__ 32 + #undef AT_EACCESS 33 + #define AT_EACCESS 0 34 + #endif 35 + 22 36 /* make sure libbpf doesn't use kernel-only integer typedefs */ 23 37 #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64 24 38 ··· 372 358 FEAT_SYSCALL_WRAPPER, 373 359 /* BPF multi-uprobe link support */ 374 360 FEAT_UPROBE_MULTI_LINK, 361 + /* Kernel supports arg:ctx tag (__arg_ctx) for global subprogs natively */ 362 + FEAT_ARG_CTX_TAG, 375 363 __FEAT_CNT, 376 364 }; 377 365
+1 -1
tools/lib/bpf/linker.c
··· 2732 2732 2733 2733 /* Emit .BTF.ext section */ 2734 2734 if (linker->btf_ext) { 2735 - raw_data = btf_ext__get_raw_data(linker->btf_ext, &raw_sz); 2735 + raw_data = btf_ext__raw_data(linker->btf_ext, &raw_sz); 2736 2736 if (!raw_data) 2737 2737 return -ENOMEM; 2738 2738
+2 -2
tools/lib/bpf/netlink.c
··· 496 496 if (err) 497 497 return libbpf_err(err); 498 498 499 - opts->feature_flags = md.flags; 500 - opts->xdp_zc_max_segs = md.xdp_zc_max_segs; 499 + OPTS_SET(opts, feature_flags, md.flags); 500 + OPTS_SET(opts, xdp_zc_max_segs, md.xdp_zc_max_segs); 501 501 502 502 skip_feature_flags: 503 503 return 0;
-1
tools/testing/selftests/bpf/DENYLIST.aarch64
··· 1 1 bpf_cookie/multi_kprobe_attach_api # kprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3 2 2 bpf_cookie/multi_kprobe_link_api # kprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3 3 - exceptions # JIT does not support calling kfunc bpf_throw: -524 4 3 fexit_sleep # The test never returns. The remaining tests cannot start. 5 4 kprobe_multi_bench_attach # needs CONFIG_FPROBE 6 5 kprobe_multi_test # needs CONFIG_FPROBE
+41 -8
tools/testing/selftests/bpf/Makefile
··· 41 41 LDFLAGS += $(SAN_LDFLAGS) 42 42 LDLIBS += $(LIBELF_LIBS) -lz -lrt -lpthread 43 43 44 + # The following tests perform type punning and they may break strict 45 + # aliasing rules, which are exploited by both GCC and clang by default 46 + # while optimizing. This can lead to broken programs. 47 + progs/bind4_prog.c-CFLAGS := -fno-strict-aliasing 48 + progs/bind6_prog.c-CFLAGS := -fno-strict-aliasing 49 + progs/dynptr_fail.c-CFLAGS := -fno-strict-aliasing 50 + progs/linked_list_fail.c-CFLAGS := -fno-strict-aliasing 51 + progs/map_kptr_fail.c-CFLAGS := -fno-strict-aliasing 52 + progs/syscall.c-CFLAGS := -fno-strict-aliasing 53 + progs/test_pkt_md_access.c-CFLAGS := -fno-strict-aliasing 54 + progs/test_sk_lookup.c-CFLAGS := -fno-strict-aliasing 55 + progs/timer_crash.c-CFLAGS := -fno-strict-aliasing 56 + 44 57 ifneq ($(LLVM),) 45 58 # Silence some warnings when compiled with clang 46 59 CFLAGS += -Wno-unused-command-line-argument ··· 77 64 ifneq ($(BPF_GCC),) 78 65 TEST_GEN_PROGS += test_progs-bpf_gcc 79 66 TEST_INST_SUBDIRS += bpf_gcc 67 + 68 + # The following tests contain C code that, although technically legal, 69 + # triggers GCC warnings that cannot be disabled: declaration of 70 + # anonymous struct types in function parameter lists. 71 + progs/btf_dump_test_case_bitfields.c-CFLAGS := -Wno-error 72 + progs/btf_dump_test_case_namespacing.c-CFLAGS := -Wno-error 73 + progs/btf_dump_test_case_packing.c-CFLAGS := -Wno-error 74 + progs/btf_dump_test_case_padding.c-CFLAGS := -Wno-error 75 + progs/btf_dump_test_case_syntax.c-CFLAGS := -Wno-error 80 76 endif 81 77 82 78 ifneq ($(CLANG_CPUV4),) ··· 132 110 flow_dissector_load test_flow_dissector test_tcp_check_syncookie_user \ 133 111 test_lirc_mode2_user xdping test_cpp runqslower bench bpf_testmod.ko \ 134 112 xskxceiver xdp_redirect_multi xdp_synproxy veristat xdp_hw_metadata \ 135 - xdp_features 113 + xdp_features bpf_test_no_cfi.ko 136 114 137 115 TEST_GEN_FILES += liburandom_read.so urandom_read sign-file uprobe_multi 138 116 ··· 197 175 # NOTE: Semicolon at the end is critical to override lib.mk's default static 198 176 # rule for binaries. 199 177 $(notdir $(TEST_GEN_PROGS) \ 200 - $(TEST_GEN_PROGS_EXTENDED) \ 201 - $(TEST_CUSTOM_PROGS)): %: $(OUTPUT)/% ; 178 + $(TEST_GEN_PROGS_EXTENDED)): %: $(OUTPUT)/% ; 202 179 203 180 # sort removes libbpf duplicates when not cross-building 204 181 MAKE_DIRS := $(sort $(BUILD_DIR)/libbpf $(HOST_BUILD_DIR)/libbpf \ ··· 253 232 $(Q)$(RM) bpf_testmod/bpf_testmod.ko # force re-compilation 254 233 $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_testmod 255 234 $(Q)cp bpf_testmod/bpf_testmod.ko $@ 235 + 236 + $(OUTPUT)/bpf_test_no_cfi.ko: $(VMLINUX_BTF) $(RESOLVE_BTFIDS) $(wildcard bpf_test_no_cfi/Makefile bpf_test_no_cfi/*.[ch]) 237 + $(call msg,MOD,,$@) 238 + $(Q)$(RM) bpf_test_no_cfi/bpf_test_no_cfi.ko # force re-compilation 239 + $(Q)$(MAKE) $(submake_extras) RESOLVE_BTFIDS=$(RESOLVE_BTFIDS) -C bpf_test_no_cfi 240 + $(Q)cp bpf_test_no_cfi/bpf_test_no_cfi.ko $@ 256 241 257 242 DEFAULT_BPFTOOL := $(HOST_SCRATCH_DIR)/sbin/bpftool 258 243 ifneq ($(CROSS_COMPILE),) ··· 409 382 CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG),$(CLANG_TARGET_ARCH)) 410 383 BPF_CFLAGS = -g -Wall -Werror -D__TARGET_ARCH_$(SRCARCH) $(MENDIAN) \ 411 384 -I$(INCLUDE_DIR) -I$(CURDIR) -I$(APIDIR) \ 412 - -I$(abspath $(OUTPUT)/../usr/include) 385 + -I$(abspath $(OUTPUT)/../usr/include) \ 386 + -Wno-compare-distinct-pointer-types 413 387 # TODO: enable me -Wsign-compare 414 388 415 - CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ 416 - -Wno-compare-distinct-pointer-types 389 + CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) 417 390 418 391 $(OUTPUT)/test_l4lb_noinline.o: BPF_CFLAGS += -fno-inline 419 392 $(OUTPUT)/test_xdp_noinline.o: BPF_CFLAGS += -fno-inline ··· 531 504 $(wildcard $(BPFDIR)/*.bpf.h) \ 532 505 | $(TRUNNER_OUTPUT) $$(BPFOBJ) 533 506 $$(call $(TRUNNER_BPF_BUILD_RULE),$$<,$$@, \ 534 - $(TRUNNER_BPF_CFLAGS)) 507 + $(TRUNNER_BPF_CFLAGS) \ 508 + $$($$<-CFLAGS)) 535 509 536 510 $(TRUNNER_BPF_SKELS): %.skel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT) 537 511 $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) ··· 542 514 $(Q)diff $$(<:.o=.linked2.o) $$(<:.o=.linked3.o) 543 515 $(Q)$$(BPFTOOL) gen skeleton $$(<:.o=.linked3.o) name $$(notdir $$(<:.bpf.o=)) > $$@ 544 516 $(Q)$$(BPFTOOL) gen subskeleton $$(<:.o=.linked3.o) name $$(notdir $$(<:.bpf.o=)) > $$(@:.skel.h=.subskel.h) 517 + $(Q)rm -f $$(<:.o=.linked1.o) $$(<:.o=.linked2.o) $$(<:.o=.linked3.o) 545 518 546 519 $(TRUNNER_BPF_LSKELS): %.lskel.h: %.bpf.o $(BPFTOOL) | $(TRUNNER_OUTPUT) 547 520 $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) ··· 551 522 $(Q)$$(BPFTOOL) gen object $$(<:.o=.llinked3.o) $$(<:.o=.llinked2.o) 552 523 $(Q)diff $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) 553 524 $(Q)$$(BPFTOOL) gen skeleton -L $$(<:.o=.llinked3.o) name $$(notdir $$(<:.bpf.o=_lskel)) > $$@ 525 + $(Q)rm -f $$(<:.o=.llinked1.o) $$(<:.o=.llinked2.o) $$(<:.o=.llinked3.o) 554 526 555 527 $(TRUNNER_BPF_SKELS_LINKED): $(TRUNNER_BPF_OBJS) $(BPFTOOL) | $(TRUNNER_OUTPUT) 556 528 $$(call msg,LINK-BPF,$(TRUNNER_BINARY),$$(@:.skel.h=.bpf.o)) ··· 562 532 $$(call msg,GEN-SKEL,$(TRUNNER_BINARY),$$@) 563 533 $(Q)$$(BPFTOOL) gen skeleton $$(@:.skel.h=.linked3.o) name $$(notdir $$(@:.skel.h=)) > $$@ 564 534 $(Q)$$(BPFTOOL) gen subskeleton $$(@:.skel.h=.linked3.o) name $$(notdir $$(@:.skel.h=)) > $$(@:.skel.h=.subskel.h) 535 + $(Q)rm -f $$(@:.skel.h=.linked1.o) $$(@:.skel.h=.linked2.o) $$(@:.skel.h=.linked3.o) 565 536 endif 566 537 567 538 # ensure we set up tests.h header generation rule just once ··· 637 606 flow_dissector_load.h \ 638 607 ip_check_defrag_frags.h 639 608 TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ 609 + $(OUTPUT)/bpf_test_no_cfi.ko \ 640 610 $(OUTPUT)/liburandom_read.so \ 641 611 $(OUTPUT)/xdp_synproxy \ 642 612 $(OUTPUT)/sign-file \ ··· 761 729 $(call msg,BINARY,,$@) 762 730 $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ 763 731 764 - EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ 732 + EXTRA_CLEAN := $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ 765 733 prog_tests/tests.h map_tests/tests.h verifier/tests.h \ 766 734 feature bpftool \ 767 735 $(addprefix $(OUTPUT)/,*.o *.skel.h *.lskel.h *.subskel.h \ 768 736 no_alu32 cpuv4 bpf_gcc bpf_testmod.ko \ 737 + bpf_test_no_cfi.ko \ 769 738 liburandom_read.so) 770 739 771 740 .PHONY: docs docs-clean
+10 -2
tools/testing/selftests/bpf/bench.c
··· 323 323 break; 324 324 case 'p': 325 325 env.producer_cnt = strtol(arg, NULL, 10); 326 - if (env.producer_cnt <= 0) { 326 + if (env.producer_cnt < 0) { 327 327 fprintf(stderr, "Invalid producer count: %s\n", arg); 328 328 argp_usage(state); 329 329 } 330 330 break; 331 331 case 'c': 332 332 env.consumer_cnt = strtol(arg, NULL, 10); 333 - if (env.consumer_cnt <= 0) { 333 + if (env.consumer_cnt < 0) { 334 334 fprintf(stderr, "Invalid consumer count: %s\n", arg); 335 335 argp_usage(state); 336 336 } ··· 607 607 bench->setup(); 608 608 609 609 for (i = 0; i < env.consumer_cnt; i++) { 610 + if (!bench->consumer_thread) { 611 + fprintf(stderr, "benchmark doesn't support consumers!\n"); 612 + exit(1); 613 + } 610 614 err = pthread_create(&state.consumers[i], NULL, 611 615 bench->consumer_thread, (void *)(long)i); 612 616 if (err) { ··· 630 626 env.prod_cpus.next_cpu = env.cons_cpus.next_cpu; 631 627 632 628 for (i = 0; i < env.producer_cnt; i++) { 629 + if (!bench->producer_thread) { 630 + fprintf(stderr, "benchmark doesn't support producers!\n"); 631 + exit(1); 632 + } 633 633 err = pthread_create(&state.producers[i], NULL, 634 634 bench->producer_thread, (void *)(long)i); 635 635 if (err) {
+10 -10
tools/testing/selftests/bpf/bpf_kfuncs.h
··· 9 9 * Error code 10 10 */ 11 11 extern int bpf_dynptr_from_skb(struct __sk_buff *skb, __u64 flags, 12 - struct bpf_dynptr *ptr__uninit) __ksym; 12 + struct bpf_dynptr *ptr__uninit) __ksym __weak; 13 13 14 14 /* Description 15 15 * Initializes an xdp-type dynptr ··· 17 17 * Error code 18 18 */ 19 19 extern int bpf_dynptr_from_xdp(struct xdp_md *xdp, __u64 flags, 20 - struct bpf_dynptr *ptr__uninit) __ksym; 20 + struct bpf_dynptr *ptr__uninit) __ksym __weak; 21 21 22 22 /* Description 23 23 * Obtain a read-only pointer to the dynptr's data ··· 26 26 * buffer if unable to obtain a direct pointer 27 27 */ 28 28 extern void *bpf_dynptr_slice(const struct bpf_dynptr *ptr, __u32 offset, 29 - void *buffer, __u32 buffer__szk) __ksym; 29 + void *buffer, __u32 buffer__szk) __ksym __weak; 30 30 31 31 /* Description 32 32 * Obtain a read-write pointer to the dynptr's data ··· 35 35 * buffer if unable to obtain a direct pointer 36 36 */ 37 37 extern void *bpf_dynptr_slice_rdwr(const struct bpf_dynptr *ptr, __u32 offset, 38 - void *buffer, __u32 buffer__szk) __ksym; 38 + void *buffer, __u32 buffer__szk) __ksym __weak; 39 39 40 - extern int bpf_dynptr_adjust(const struct bpf_dynptr *ptr, __u32 start, __u32 end) __ksym; 41 - extern bool bpf_dynptr_is_null(const struct bpf_dynptr *ptr) __ksym; 42 - extern bool bpf_dynptr_is_rdonly(const struct bpf_dynptr *ptr) __ksym; 43 - extern __u32 bpf_dynptr_size(const struct bpf_dynptr *ptr) __ksym; 44 - extern int bpf_dynptr_clone(const struct bpf_dynptr *ptr, struct bpf_dynptr *clone__init) __ksym; 40 + extern int bpf_dynptr_adjust(const struct bpf_dynptr *ptr, __u32 start, __u32 end) __ksym __weak; 41 + extern bool bpf_dynptr_is_null(const struct bpf_dynptr *ptr) __ksym __weak; 42 + extern bool bpf_dynptr_is_rdonly(const struct bpf_dynptr *ptr) __ksym __weak; 43 + extern __u32 bpf_dynptr_size(const struct bpf_dynptr *ptr) __ksym __weak; 44 + extern int bpf_dynptr_clone(const struct bpf_dynptr *ptr, struct bpf_dynptr *clone__init) __ksym __weak; 45 45 46 46 /* Description 47 47 * Modify the address of a AF_UNIX sockaddr. ··· 63 63 64 64 void *bpf_cast_to_kern_ctx(void *) __ksym; 65 65 66 - void *bpf_rdonly_cast(void *obj, __u32 btf_id) __ksym; 66 + extern void *bpf_rdonly_cast(const void *obj, __u32 btf_id) __ksym __weak; 67 67 68 68 extern int bpf_get_file_xattr(struct file *file, const char *name, 69 69 struct bpf_dynptr *value_ptr) __ksym;
+19
tools/testing/selftests/bpf/bpf_test_no_cfi/Makefile
··· 1 + BPF_TEST_NO_CFI_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) 2 + KDIR ?= $(abspath $(BPF_TEST_NO_CFI_DIR)/../../../../..) 3 + 4 + ifeq ($(V),1) 5 + Q = 6 + else 7 + Q = @ 8 + endif 9 + 10 + MODULES = bpf_test_no_cfi.ko 11 + 12 + obj-m += bpf_test_no_cfi.o 13 + 14 + all: 15 + +$(Q)make -C $(KDIR) M=$(BPF_TEST_NO_CFI_DIR) modules 16 + 17 + clean: 18 + +$(Q)make -C $(KDIR) M=$(BPF_TEST_NO_CFI_DIR) clean 19 +
+84
tools/testing/selftests/bpf/bpf_test_no_cfi/bpf_test_no_cfi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <linux/bpf.h> 4 + #include <linux/btf.h> 5 + #include <linux/init.h> 6 + #include <linux/module.h> 7 + 8 + struct bpf_test_no_cfi_ops { 9 + void (*fn_1)(void); 10 + void (*fn_2)(void); 11 + }; 12 + 13 + static int dummy_init(struct btf *btf) 14 + { 15 + return 0; 16 + } 17 + 18 + static int dummy_init_member(const struct btf_type *t, 19 + const struct btf_member *member, 20 + void *kdata, const void *udata) 21 + { 22 + return 0; 23 + } 24 + 25 + static int dummy_reg(void *kdata) 26 + { 27 + return 0; 28 + } 29 + 30 + static void dummy_unreg(void *kdata) 31 + { 32 + } 33 + 34 + static const struct bpf_verifier_ops dummy_verifier_ops; 35 + 36 + static void bpf_test_no_cfi_ops__fn_1(void) 37 + { 38 + } 39 + 40 + static void bpf_test_no_cfi_ops__fn_2(void) 41 + { 42 + } 43 + 44 + static struct bpf_test_no_cfi_ops __test_no_cif_ops = { 45 + .fn_1 = bpf_test_no_cfi_ops__fn_1, 46 + .fn_2 = bpf_test_no_cfi_ops__fn_2, 47 + }; 48 + 49 + static struct bpf_struct_ops test_no_cif_ops = { 50 + .verifier_ops = &dummy_verifier_ops, 51 + .init = dummy_init, 52 + .init_member = dummy_init_member, 53 + .reg = dummy_reg, 54 + .unreg = dummy_unreg, 55 + .name = "bpf_test_no_cfi_ops", 56 + .owner = THIS_MODULE, 57 + }; 58 + 59 + static int bpf_test_no_cfi_init(void) 60 + { 61 + int ret; 62 + 63 + ret = register_bpf_struct_ops(&test_no_cif_ops, 64 + bpf_test_no_cfi_ops); 65 + if (!ret) 66 + return -EINVAL; 67 + 68 + test_no_cif_ops.cfi_stubs = &__test_no_cif_ops; 69 + ret = register_bpf_struct_ops(&test_no_cif_ops, 70 + bpf_test_no_cfi_ops); 71 + return ret; 72 + } 73 + 74 + static void bpf_test_no_cfi_exit(void) 75 + { 76 + } 77 + 78 + module_init(bpf_test_no_cfi_init); 79 + module_exit(bpf_test_no_cfi_exit); 80 + 81 + MODULE_AUTHOR("Kuifeng Lee"); 82 + MODULE_DESCRIPTION("BPF no cfi_stubs test module"); 83 + MODULE_LICENSE("Dual BSD/GPL"); 84 +
+26 -8
tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
··· 343 343 .write = bpf_testmod_test_write, 344 344 }; 345 345 346 - BTF_SET8_START(bpf_testmod_common_kfunc_ids) 346 + BTF_KFUNCS_START(bpf_testmod_common_kfunc_ids) 347 347 BTF_ID_FLAGS(func, bpf_iter_testmod_seq_new, KF_ITER_NEW) 348 348 BTF_ID_FLAGS(func, bpf_iter_testmod_seq_next, KF_ITER_NEXT | KF_RET_NULL) 349 349 BTF_ID_FLAGS(func, bpf_iter_testmod_seq_destroy, KF_ITER_DESTROY) 350 350 BTF_ID_FLAGS(func, bpf_kfunc_common_test) 351 - BTF_SET8_END(bpf_testmod_common_kfunc_ids) 351 + BTF_KFUNCS_END(bpf_testmod_common_kfunc_ids) 352 352 353 353 static const struct btf_kfunc_id_set bpf_testmod_common_kfunc_set = { 354 354 .owner = THIS_MODULE, ··· 494 494 return arg; 495 495 } 496 496 497 - BTF_SET8_START(bpf_testmod_check_kfunc_ids) 497 + BTF_KFUNCS_START(bpf_testmod_check_kfunc_ids) 498 498 BTF_ID_FLAGS(func, bpf_testmod_test_mod_kfunc) 499 499 BTF_ID_FLAGS(func, bpf_kfunc_call_test1) 500 500 BTF_ID_FLAGS(func, bpf_kfunc_call_test2) ··· 520 520 BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE) 521 521 BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg) 522 522 BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset) 523 - BTF_SET8_END(bpf_testmod_check_kfunc_ids) 523 + BTF_KFUNCS_END(bpf_testmod_check_kfunc_ids) 524 524 525 525 static int bpf_testmod_ops_init(struct btf *btf) 526 526 { ··· 539 539 const struct btf_member *member, 540 540 void *kdata, const void *udata) 541 541 { 542 + if (member->offset == offsetof(struct bpf_testmod_ops, data) * 8) { 543 + /* For data fields, this function has to copy it and return 544 + * 1 to indicate that the data has been handled by the 545 + * struct_ops type, or the verifier will reject the map if 546 + * the value of the data field is not zero. 547 + */ 548 + ((struct bpf_testmod_ops *)kdata)->data = ((struct bpf_testmod_ops *)udata)->data; 549 + return 1; 550 + } 542 551 return 0; 543 552 } 544 553 ··· 563 554 static int bpf_dummy_reg(void *kdata) 564 555 { 565 556 struct bpf_testmod_ops *ops = kdata; 566 - int r; 567 557 568 - r = ops->test_2(4, 3); 558 + /* Some test cases (ex. struct_ops_maybe_null) may not have test_2 559 + * initialized, so we need to check for NULL. 560 + */ 561 + if (ops->test_2) 562 + ops->test_2(4, ops->data); 569 563 570 564 return 0; 571 565 } ··· 582 570 return 0; 583 571 } 584 572 585 - static int bpf_testmod_test_2(int a, int b) 573 + static void bpf_testmod_test_2(int a, int b) 574 + { 575 + } 576 + 577 + static int bpf_testmod_ops__test_maybe_null(int dummy, 578 + struct task_struct *task__nullable) 586 579 { 587 580 return 0; 588 581 } ··· 595 578 static struct bpf_testmod_ops __bpf_testmod_ops = { 596 579 .test_1 = bpf_testmod_test_1, 597 580 .test_2 = bpf_testmod_test_2, 581 + .test_maybe_null = bpf_testmod_ops__test_maybe_null, 598 582 }; 599 583 600 584 struct bpf_struct_ops bpf_bpf_testmod_ops = { ··· 637 619 while (refcount_read(&prog_test_struct.cnt) > 1) 638 620 msleep(20); 639 621 640 - return sysfs_remove_bin_file(kernel_kobj, &bin_attr_bpf_testmod_file); 622 + sysfs_remove_bin_file(kernel_kobj, &bin_attr_bpf_testmod_file); 641 623 } 642 624 643 625 module_init(bpf_testmod_init);
+13 -1
tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.h
··· 5 5 6 6 #include <linux/types.h> 7 7 8 + struct task_struct; 9 + 8 10 struct bpf_testmod_test_read_ctx { 9 11 char *buf; 10 12 loff_t off; ··· 32 30 33 31 struct bpf_testmod_ops { 34 32 int (*test_1)(void); 35 - int (*test_2)(int a, int b); 33 + void (*test_2)(int a, int b); 34 + /* Used to test nullable arguments. */ 35 + int (*test_maybe_null)(int dummy, struct task_struct *task); 36 + 37 + /* The following fields are used to test shadow copies. */ 38 + char onebyte; 39 + struct { 40 + int a; 41 + int b; 42 + } unsupported; 43 + int data; 36 44 }; 37 45 38 46 #endif /* _BPF_TESTMOD_H */
+3 -3
tools/testing/selftests/bpf/prog_tests/cpumask.c
··· 27 27 struct bpf_program *prog; 28 28 struct bpf_link *link = NULL; 29 29 pid_t child_pid; 30 - int status; 30 + int status, err; 31 31 32 32 skel = cpumask_success__open(); 33 33 if (!ASSERT_OK_PTR(skel, "cpumask_success__open")) ··· 36 36 skel->bss->pid = getpid(); 37 37 skel->bss->nr_cpus = libbpf_num_possible_cpus(); 38 38 39 - cpumask_success__load(skel); 40 - if (!ASSERT_OK_PTR(skel, "cpumask_success__load")) 39 + err = cpumask_success__load(skel); 40 + if (!ASSERT_OK(err, "cpumask_success__load")) 41 41 goto cleanup; 42 42 43 43 prog = bpf_object__find_program_by_name(skel->obj, prog_name);
+1 -1
tools/testing/selftests/bpf/prog_tests/decap_sanity.c
··· 72 72 bpf_tc_hook_destroy(&qdisc_hook); 73 73 close_netns(nstoken); 74 74 } 75 - SYS_NOFAIL("ip netns del " NS_TEST " &> /dev/null"); 75 + SYS_NOFAIL("ip netns del " NS_TEST); 76 76 decap_sanity__destroy(skel); 77 77 }
+1 -1
tools/testing/selftests/bpf/prog_tests/fib_lookup.c
··· 298 298 fail: 299 299 if (nstoken) 300 300 close_netns(nstoken); 301 - SYS_NOFAIL("ip netns del " NS_TEST " &> /dev/null"); 301 + SYS_NOFAIL("ip netns del " NS_TEST); 302 302 fib_lookup__destroy(skel); 303 303 }
+2 -2
tools/testing/selftests/bpf/prog_tests/ip_check_defrag.c
··· 59 59 /* Wait for up to 5s for links to come up */ 60 60 for (i = 0; i < 5; ++i) { 61 61 if (ipv6) 62 - up = !system("ip netns exec " NS0 " ping -6 -c 1 -W 1 " VETH1_ADDR6 " &>/dev/null"); 62 + up = !SYS_NOFAIL("ip netns exec " NS0 " ping -6 -c 1 -W 1 " VETH1_ADDR6); 63 63 else 64 - up = !system("ip netns exec " NS0 " ping -c 1 -W 1 " VETH1_ADDR " &>/dev/null"); 64 + up = !SYS_NOFAIL("ip netns exec " NS0 " ping -c 1 -W 1 " VETH1_ADDR); 65 65 66 66 if (up) 67 67 break;
+2 -1
tools/testing/selftests/bpf/prog_tests/kptr_xchg_inline.c
··· 13 13 unsigned int cnt; 14 14 int err; 15 15 16 - #if !(defined(__x86_64__) || defined(__aarch64__)) 16 + #if !(defined(__x86_64__) || defined(__aarch64__) || \ 17 + (defined(__riscv) && __riscv_xlen == 64)) 17 18 test__skip(); 18 19 return; 19 20 #endif
+2 -2
tools/testing/selftests/bpf/prog_tests/log_fixup.c
··· 169 169 if (test__start_subtest("bad_core_relo_trunc_none")) 170 170 bad_core_relo(0, TRUNC_NONE /* full buf */); 171 171 if (test__start_subtest("bad_core_relo_trunc_partial")) 172 - bad_core_relo(280, TRUNC_PARTIAL /* truncate original log a bit */); 172 + bad_core_relo(300, TRUNC_PARTIAL /* truncate original log a bit */); 173 173 if (test__start_subtest("bad_core_relo_trunc_full")) 174 - bad_core_relo(220, TRUNC_FULL /* truncate also libbpf's message patch */); 174 + bad_core_relo(240, TRUNC_FULL /* truncate also libbpf's message patch */); 175 175 if (test__start_subtest("bad_core_relo_subprog")) 176 176 bad_core_relo_subprog(); 177 177 if (test__start_subtest("missing_map"))
-2
tools/testing/selftests/bpf/prog_tests/lwt_helpers.h
··· 27 27 } \ 28 28 }) 29 29 30 - #define NETNS "ns_lwt" 31 - 32 30 static inline int netns_create(void) 33 31 { 34 32 return system("ip netns add " NETNS);
+3 -1
tools/testing/selftests/bpf/prog_tests/lwt_redirect.c
··· 54 54 #include <stdbool.h> 55 55 #include <stdlib.h> 56 56 57 + #define NETNS "ns_lwt_redirect" 57 58 #include "lwt_helpers.h" 58 59 #include "test_progs.h" 59 60 #include "network_helpers.h" ··· 86 85 snprintf(ip, sizeof(ip), "20.0.0.%d", link_index); 87 86 88 87 /* We won't get a reply. Don't fail here */ 89 - SYS_NOFAIL("ping %s -c1 -W1 -s %d >/dev/null 2>&1", 88 + SYS_NOFAIL("ping %s -c1 -W1 -s %d", 90 89 ip, ICMP_PAYLOAD_SIZE); 91 90 } 92 91 ··· 204 203 if (!ASSERT_GE(target_index, 0, "if_nametoindex")) 205 204 goto fail; 206 205 206 + SYS(fail, "sysctl -w net.ipv6.conf.all.disable_ipv6=1"); 207 207 SYS(fail, "ip link add link_err type dummy"); 208 208 SYS(fail, "ip link set lo up"); 209 209 SYS(fail, "ip addr add dev lo " LOCAL_SRC "/32");
+2 -1
tools/testing/selftests/bpf/prog_tests/lwt_reroute.c
··· 48 48 * For case 2, force UDP packets to overflow fq limit. As long as kernel 49 49 * is not crashed, it is considered successful. 50 50 */ 51 + #define NETNS "ns_lwt_reroute" 51 52 #include "lwt_helpers.h" 52 53 #include "network_helpers.h" 53 54 #include <linux/net_tstamp.h> ··· 64 63 static void ping_once(const char *ip) 65 64 { 66 65 /* We won't get a reply. Don't fail here */ 67 - SYS_NOFAIL("ping %s -c1 -W1 -s %d >/dev/null 2>&1", 66 + SYS_NOFAIL("ping %s -c1 -W1 -s %d", 68 67 ip, ICMP_PAYLOAD_SIZE); 69 68 } 70 69
+1 -1
tools/testing/selftests/bpf/prog_tests/mptcp.c
··· 79 79 if (nstoken) 80 80 close_netns(nstoken); 81 81 82 - SYS_NOFAIL("ip netns del %s &> /dev/null", NS_TEST); 82 + SYS_NOFAIL("ip netns del %s", NS_TEST); 83 83 } 84 84 85 85 static int verify_tsk(int map_fd, int client_fd)
+6
tools/testing/selftests/bpf/prog_tests/rcu_read_lock.c
··· 29 29 bpf_program__set_autoload(skel->progs.non_sleepable_1, true); 30 30 bpf_program__set_autoload(skel->progs.non_sleepable_2, true); 31 31 bpf_program__set_autoload(skel->progs.task_trusted_non_rcuptr, true); 32 + bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog, true); 33 + bpf_program__set_autoload(skel->progs.rcu_read_lock_global_subprog, true); 34 + bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog_lock, true); 35 + bpf_program__set_autoload(skel->progs.rcu_read_lock_subprog_unlock, true); 32 36 err = rcu_read_lock__load(skel); 33 37 if (!ASSERT_OK(err, "skel_load")) 34 38 goto out; ··· 79 75 "inproper_sleepable_helper", 80 76 "inproper_sleepable_kfunc", 81 77 "nested_rcu_region", 78 + "rcu_read_lock_global_subprog_lock", 79 + "rcu_read_lock_global_subprog_unlock", 82 80 }; 83 81 84 82 static void test_inproper_region(void)
+1 -1
tools/testing/selftests/bpf/prog_tests/sock_destroy.c
··· 214 214 cleanup: 215 215 if (nstoken) 216 216 close_netns(nstoken); 217 - SYS_NOFAIL("ip netns del " TEST_NS " &> /dev/null"); 217 + SYS_NOFAIL("ip netns del " TEST_NS); 218 218 if (cgroup_fd >= 0) 219 219 close(cgroup_fd); 220 220 sock_destroy_prog__destroy(skel);
+2 -2
tools/testing/selftests/bpf/prog_tests/sock_iter_batch.c
··· 112 112 { 113 113 struct nstoken *nstoken = NULL; 114 114 115 - SYS_NOFAIL("ip netns del " TEST_NS " &> /dev/null"); 115 + SYS_NOFAIL("ip netns del " TEST_NS); 116 116 SYS(done, "ip netns add %s", TEST_NS); 117 117 SYS(done, "ip -net %s link set dev lo up", TEST_NS); 118 118 ··· 131 131 close_netns(nstoken); 132 132 133 133 done: 134 - SYS_NOFAIL("ip netns del " TEST_NS " &> /dev/null"); 134 + SYS_NOFAIL("ip netns del " TEST_NS); 135 135 }
+2
tools/testing/selftests/bpf/prog_tests/spin_lock.c
··· 48 48 { "lock_id_mismatch_innermapval_kptr", "bpf_spin_unlock of different lock" }, 49 49 { "lock_id_mismatch_innermapval_global", "bpf_spin_unlock of different lock" }, 50 50 { "lock_id_mismatch_innermapval_mapval", "bpf_spin_unlock of different lock" }, 51 + { "lock_global_subprog_call1", "global function calls are not allowed while holding a lock" }, 52 + { "lock_global_subprog_call2", "global function calls are not allowed while holding a lock" }, 51 53 }; 52 54 53 55 static int match_regex(const char *pattern, const char *string)
-6
tools/testing/selftests/bpf/prog_tests/task_local_storage.c
··· 117 117 ASSERT_OK(err, "lookup map_b"); 118 118 ASSERT_EQ(value, 100, "map_b value"); 119 119 120 - prog_fd = bpf_program__fd(skel->progs.on_lookup); 121 - memset(&info, 0, sizeof(info)); 122 - err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len); 123 - ASSERT_OK(err, "get prog info"); 124 - ASSERT_GT(info.recursion_misses, 0, "on_lookup prog recursion"); 125 - 126 120 prog_fd = bpf_program__fd(skel->progs.on_update); 127 121 memset(&info, 0, sizeof(info)); 128 122 err = bpf_prog_get_info_by_fd(prog_fd, &info, &info_len);
+46
tools/testing/selftests/bpf/prog_tests/test_struct_ops_maybe_null.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <test_progs.h> 4 + 5 + #include "struct_ops_maybe_null.skel.h" 6 + #include "struct_ops_maybe_null_fail.skel.h" 7 + 8 + /* Test that the verifier accepts a program that access a nullable pointer 9 + * with a proper check. 10 + */ 11 + static void maybe_null(void) 12 + { 13 + struct struct_ops_maybe_null *skel; 14 + 15 + skel = struct_ops_maybe_null__open_and_load(); 16 + if (!ASSERT_OK_PTR(skel, "struct_ops_module_open_and_load")) 17 + return; 18 + 19 + struct_ops_maybe_null__destroy(skel); 20 + } 21 + 22 + /* Test that the verifier rejects a program that access a nullable pointer 23 + * without a check beforehand. 24 + */ 25 + static void maybe_null_fail(void) 26 + { 27 + struct struct_ops_maybe_null_fail *skel; 28 + 29 + skel = struct_ops_maybe_null_fail__open_and_load(); 30 + if (ASSERT_ERR_PTR(skel, "struct_ops_module_fail__open_and_load")) 31 + return; 32 + 33 + struct_ops_maybe_null_fail__destroy(skel); 34 + } 35 + 36 + void test_struct_ops_maybe_null(void) 37 + { 38 + /* The verifier verifies the programs at load time, so testing both 39 + * programs in the same compile-unit is complicated. We run them in 40 + * separate objects to simplify the testing. 41 + */ 42 + if (test__start_subtest("maybe_null")) 43 + maybe_null(); 44 + if (test__start_subtest("maybe_null_fail")) 45 + maybe_null_fail(); 46 + }
+15 -4
tools/testing/selftests/bpf/prog_tests/test_struct_ops_module.c
··· 32 32 33 33 static void test_struct_ops_load(void) 34 34 { 35 - DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); 36 35 struct struct_ops_module *skel; 37 36 struct bpf_map_info info = {}; 38 37 struct bpf_link *link; 39 38 int err; 40 39 u32 len; 41 40 42 - skel = struct_ops_module__open_opts(&opts); 41 + skel = struct_ops_module__open(); 43 42 if (!ASSERT_OK_PTR(skel, "struct_ops_module_open")) 44 43 return; 44 + 45 + skel->struct_ops.testmod_1->data = 13; 46 + skel->struct_ops.testmod_1->test_2 = skel->progs.test_3; 47 + /* Since test_2() is not being used, it should be disabled from 48 + * auto-loading, or it will fail to load. 49 + */ 50 + bpf_program__set_autoload(skel->progs.test_2, false); 45 51 46 52 err = struct_ops_module__load(skel); 47 53 if (!ASSERT_OK(err, "struct_ops_module_load")) ··· 62 56 link = bpf_map__attach_struct_ops(skel->maps.testmod_1); 63 57 ASSERT_OK_PTR(link, "attach_test_mod_1"); 64 58 65 - /* test_2() will be called from bpf_dummy_reg() in bpf_testmod.c */ 66 - ASSERT_EQ(skel->bss->test_2_result, 7, "test_2_result"); 59 + /* test_3() will be called from bpf_dummy_reg() in bpf_testmod.c 60 + * 61 + * In bpf_testmod.c it will pass 4 and 13 (the value of data) to 62 + * .test_2. So, the value of test_2_result should be 20 (4 + 13 + 63 + * 3). 64 + */ 65 + ASSERT_EQ(skel->bss->test_2_result, 20, "check_shadow_variables"); 67 66 68 67 bpf_link__destroy(link); 69 68
+35
tools/testing/selftests/bpf/prog_tests/test_struct_ops_no_cfi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <test_progs.h> 4 + #include <testing_helpers.h> 5 + 6 + static void load_bpf_test_no_cfi(void) 7 + { 8 + int fd; 9 + int err; 10 + 11 + fd = open("bpf_test_no_cfi.ko", O_RDONLY); 12 + if (!ASSERT_GE(fd, 0, "open")) 13 + return; 14 + 15 + /* The module will try to register a struct_ops type without 16 + * cfi_stubs and with cfi_stubs. 17 + * 18 + * The one without cfi_stub should fail. The module will be loaded 19 + * successfully only if the result of the registration is as 20 + * expected, or it fails. 21 + */ 22 + err = finit_module(fd, "", 0); 23 + close(fd); 24 + if (!ASSERT_OK(err, "finit_module")) 25 + return; 26 + 27 + err = delete_module("bpf_test_no_cfi", 0); 28 + ASSERT_OK(err, "delete_module"); 29 + } 30 + 31 + void test_struct_ops_no_cfi(void) 32 + { 33 + if (test__start_subtest("load_bpf_test_no_cfi")) 34 + load_bpf_test_no_cfi(); 35 + }
+9 -9
tools/testing/selftests/bpf/prog_tests/test_tunnel.c
··· 118 118 static void cleanup(void) 119 119 { 120 120 SYS_NOFAIL("test -f /var/run/netns/at_ns0 && ip netns delete at_ns0"); 121 - SYS_NOFAIL("ip link del veth1 2> /dev/null"); 122 - SYS_NOFAIL("ip link del %s 2> /dev/null", VXLAN_TUNL_DEV1); 123 - SYS_NOFAIL("ip link del %s 2> /dev/null", IP6VXLAN_TUNL_DEV1); 121 + SYS_NOFAIL("ip link del veth1"); 122 + SYS_NOFAIL("ip link del %s", VXLAN_TUNL_DEV1); 123 + SYS_NOFAIL("ip link del %s", IP6VXLAN_TUNL_DEV1); 124 124 } 125 125 126 126 static int add_vxlan_tunnel(void) ··· 265 265 static void delete_ipip_tunnel(void) 266 266 { 267 267 SYS_NOFAIL("ip -n at_ns0 link delete dev %s", IPIP_TUNL_DEV0); 268 - SYS_NOFAIL("ip -n at_ns0 fou del port 5555 2> /dev/null"); 268 + SYS_NOFAIL("ip -n at_ns0 fou del port 5555"); 269 269 SYS_NOFAIL("ip link delete dev %s", IPIP_TUNL_DEV1); 270 - SYS_NOFAIL("ip fou del port 5555 2> /dev/null"); 270 + SYS_NOFAIL("ip fou del port 5555"); 271 271 } 272 272 273 273 static int add_xfrm_tunnel(void) ··· 346 346 347 347 static void delete_xfrm_tunnel(void) 348 348 { 349 - SYS_NOFAIL("ip xfrm policy delete dir out src %s/32 dst %s/32 2> /dev/null", 349 + SYS_NOFAIL("ip xfrm policy delete dir out src %s/32 dst %s/32", 350 350 IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0); 351 - SYS_NOFAIL("ip xfrm policy delete dir in src %s/32 dst %s/32 2> /dev/null", 351 + SYS_NOFAIL("ip xfrm policy delete dir in src %s/32 dst %s/32", 352 352 IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1); 353 - SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d 2> /dev/null", 353 + SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d", 354 354 IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT); 355 - SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d 2> /dev/null", 355 + SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d", 356 356 IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN); 357 357 } 358 358
+37
tools/testing/selftests/bpf/prog_tests/tracing_failure.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <test_progs.h> 4 + #include "tracing_failure.skel.h" 5 + 6 + static void test_bpf_spin_lock(bool is_spin_lock) 7 + { 8 + struct tracing_failure *skel; 9 + int err; 10 + 11 + skel = tracing_failure__open(); 12 + if (!ASSERT_OK_PTR(skel, "tracing_failure__open")) 13 + return; 14 + 15 + if (is_spin_lock) 16 + bpf_program__set_autoload(skel->progs.test_spin_lock, true); 17 + else 18 + bpf_program__set_autoload(skel->progs.test_spin_unlock, true); 19 + 20 + err = tracing_failure__load(skel); 21 + if (!ASSERT_OK(err, "tracing_failure__load")) 22 + goto out; 23 + 24 + err = tracing_failure__attach(skel); 25 + ASSERT_ERR(err, "tracing_failure__attach"); 26 + 27 + out: 28 + tracing_failure__destroy(skel); 29 + } 30 + 31 + void test_tracing_failure(void) 32 + { 33 + if (test__start_subtest("bpf_spin_lock")) 34 + test_bpf_spin_lock(true); 35 + if (test__start_subtest("bpf_spin_unlock")) 36 + test_bpf_spin_lock(false); 37 + }
+2
tools/testing/selftests/bpf/prog_tests/verifier.c
··· 28 28 #include "verifier_div0.skel.h" 29 29 #include "verifier_div_overflow.skel.h" 30 30 #include "verifier_global_subprogs.skel.h" 31 + #include "verifier_global_ptr_args.skel.h" 31 32 #include "verifier_gotol.skel.h" 32 33 #include "verifier_helper_access_var_len.skel.h" 33 34 #include "verifier_helper_packet_access.skel.h" ··· 141 140 void test_verifier_div0(void) { RUN(verifier_div0); } 142 141 void test_verifier_div_overflow(void) { RUN(verifier_div_overflow); } 143 142 void test_verifier_global_subprogs(void) { RUN(verifier_global_subprogs); } 143 + void test_verifier_global_ptr_args(void) { RUN(verifier_global_ptr_args); } 144 144 void test_verifier_gotol(void) { RUN(verifier_gotol); } 145 145 void test_verifier_helper_access_var_len(void) { RUN(verifier_helper_access_var_len); } 146 146 void test_verifier_helper_packet_access(void) { RUN(verifier_helper_packet_access); }
+2 -2
tools/testing/selftests/bpf/progs/async_stack_depth.c
··· 30 30 } 31 31 32 32 SEC("tc") 33 - __failure __msg("combined stack size of 2 calls is 576. Too large") 33 + __failure __msg("combined stack size of 2 calls is") 34 34 int pseudo_call_check(struct __sk_buff *ctx) 35 35 { 36 36 struct hmap_elem *elem; ··· 45 45 } 46 46 47 47 SEC("tc") 48 - __failure __msg("combined stack size of 2 calls is 608. Too large") 48 + __failure __msg("combined stack size of 2 calls is") 49 49 int async_call_root_check(struct __sk_buff *ctx) 50 50 { 51 51 struct hmap_elem *elem;
+33
tools/testing/selftests/bpf/progs/bpf_compiler.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __BPF_COMPILER_H__ 3 + #define __BPF_COMPILER_H__ 4 + 5 + #define DO_PRAGMA_(X) _Pragma(#X) 6 + 7 + #if __clang__ 8 + #define __pragma_loop_unroll DO_PRAGMA_(clang loop unroll(enable)) 9 + #else 10 + /* In GCC -funroll-loops, which is enabled with -O2, should have the 11 + same impact than the loop-unroll-enable pragma above. */ 12 + #define __pragma_loop_unroll 13 + #endif 14 + 15 + #if __clang__ 16 + #define __pragma_loop_unroll_count(N) DO_PRAGMA_(clang loop unroll_count(N)) 17 + #else 18 + #define __pragma_loop_unroll_count(N) DO_PRAGMA_(GCC unroll N) 19 + #endif 20 + 21 + #if __clang__ 22 + #define __pragma_loop_unroll_full DO_PRAGMA_(clang loop unroll(full)) 23 + #else 24 + #define __pragma_loop_unroll_full DO_PRAGMA_(GCC unroll 65534) 25 + #endif 26 + 27 + #if __clang__ 28 + #define __pragma_loop_no_unroll DO_PRAGMA_(clang loop unroll(disable)) 29 + #else 30 + #define __pragma_loop_no_unroll DO_PRAGMA_(GCC unroll 1) 31 + #endif 32 + 33 + #endif
-26
tools/testing/selftests/bpf/progs/cgrp_ls_recursion.c
··· 27 27 struct cgroup *bpf_task_get_cgroup1(struct task_struct *task, int hierarchy_id) __ksym; 28 28 void bpf_cgroup_release(struct cgroup *cgrp) __ksym; 29 29 30 - static void __on_lookup(struct cgroup *cgrp) 31 - { 32 - bpf_cgrp_storage_delete(&map_a, cgrp); 33 - bpf_cgrp_storage_delete(&map_b, cgrp); 34 - } 35 - 36 - SEC("fentry/bpf_local_storage_lookup") 37 - int BPF_PROG(on_lookup) 38 - { 39 - struct task_struct *task = bpf_get_current_task_btf(); 40 - struct cgroup *cgrp; 41 - 42 - if (is_cgroup1) { 43 - cgrp = bpf_task_get_cgroup1(task, target_hid); 44 - if (!cgrp) 45 - return 0; 46 - 47 - __on_lookup(cgrp); 48 - bpf_cgroup_release(cgrp); 49 - return 0; 50 - } 51 - 52 - __on_lookup(task->cgroups->dfl_cgrp); 53 - return 0; 54 - } 55 - 56 30 static void __on_update(struct cgroup *cgrp) 57 31 { 58 32 long *ptr;
+1 -2
tools/testing/selftests/bpf/progs/connect_unix_prog.c
··· 28 28 if (sa_kern->uaddrlen != unaddrlen) 29 29 return 0; 30 30 31 - sa_kern_unaddr = bpf_rdonly_cast(sa_kern->uaddr, 32 - bpf_core_type_id_kernel(struct sockaddr_un)); 31 + sa_kern_unaddr = bpf_core_cast(sa_kern->uaddr, struct sockaddr_un); 33 32 if (memcmp(sa_kern_unaddr->sun_path, SERVUN_REWRITE_ADDRESS, 34 33 sizeof(SERVUN_REWRITE_ADDRESS) - 1) != 0) 35 34 return 0;
+28 -27
tools/testing/selftests/bpf/progs/cpumask_common.h
··· 23 23 __uint(max_entries, 1); 24 24 } __cpumask_map SEC(".maps"); 25 25 26 - struct bpf_cpumask *bpf_cpumask_create(void) __ksym; 27 - void bpf_cpumask_release(struct bpf_cpumask *cpumask) __ksym; 28 - struct bpf_cpumask *bpf_cpumask_acquire(struct bpf_cpumask *cpumask) __ksym; 29 - u32 bpf_cpumask_first(const struct cpumask *cpumask) __ksym; 30 - u32 bpf_cpumask_first_zero(const struct cpumask *cpumask) __ksym; 26 + struct bpf_cpumask *bpf_cpumask_create(void) __ksym __weak; 27 + void bpf_cpumask_release(struct bpf_cpumask *cpumask) __ksym __weak; 28 + struct bpf_cpumask *bpf_cpumask_acquire(struct bpf_cpumask *cpumask) __ksym __weak; 29 + u32 bpf_cpumask_first(const struct cpumask *cpumask) __ksym __weak; 30 + u32 bpf_cpumask_first_zero(const struct cpumask *cpumask) __ksym __weak; 31 31 u32 bpf_cpumask_first_and(const struct cpumask *src1, 32 - const struct cpumask *src2) __ksym; 33 - void bpf_cpumask_set_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym; 34 - void bpf_cpumask_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym; 35 - bool bpf_cpumask_test_cpu(u32 cpu, const struct cpumask *cpumask) __ksym; 36 - bool bpf_cpumask_test_and_set_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym; 37 - bool bpf_cpumask_test_and_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym; 38 - void bpf_cpumask_setall(struct bpf_cpumask *cpumask) __ksym; 39 - void bpf_cpumask_clear(struct bpf_cpumask *cpumask) __ksym; 32 + const struct cpumask *src2) __ksym __weak; 33 + void bpf_cpumask_set_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym __weak; 34 + void bpf_cpumask_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym __weak; 35 + bool bpf_cpumask_test_cpu(u32 cpu, const struct cpumask *cpumask) __ksym __weak; 36 + bool bpf_cpumask_test_and_set_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym __weak; 37 + bool bpf_cpumask_test_and_clear_cpu(u32 cpu, struct bpf_cpumask *cpumask) __ksym __weak; 38 + void bpf_cpumask_setall(struct bpf_cpumask *cpumask) __ksym __weak; 39 + void bpf_cpumask_clear(struct bpf_cpumask *cpumask) __ksym __weak; 40 40 bool bpf_cpumask_and(struct bpf_cpumask *cpumask, 41 41 const struct cpumask *src1, 42 - const struct cpumask *src2) __ksym; 42 + const struct cpumask *src2) __ksym __weak; 43 43 void bpf_cpumask_or(struct bpf_cpumask *cpumask, 44 44 const struct cpumask *src1, 45 - const struct cpumask *src2) __ksym; 45 + const struct cpumask *src2) __ksym __weak; 46 46 void bpf_cpumask_xor(struct bpf_cpumask *cpumask, 47 47 const struct cpumask *src1, 48 - const struct cpumask *src2) __ksym; 49 - bool bpf_cpumask_equal(const struct cpumask *src1, const struct cpumask *src2) __ksym; 50 - bool bpf_cpumask_intersects(const struct cpumask *src1, const struct cpumask *src2) __ksym; 51 - bool bpf_cpumask_subset(const struct cpumask *src1, const struct cpumask *src2) __ksym; 52 - bool bpf_cpumask_empty(const struct cpumask *cpumask) __ksym; 53 - bool bpf_cpumask_full(const struct cpumask *cpumask) __ksym; 54 - void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym; 55 - u32 bpf_cpumask_any_distribute(const struct cpumask *src) __ksym; 56 - u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1, const struct cpumask *src2) __ksym; 57 - u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym; 48 + const struct cpumask *src2) __ksym __weak; 49 + bool bpf_cpumask_equal(const struct cpumask *src1, const struct cpumask *src2) __ksym __weak; 50 + bool bpf_cpumask_intersects(const struct cpumask *src1, const struct cpumask *src2) __ksym __weak; 51 + bool bpf_cpumask_subset(const struct cpumask *src1, const struct cpumask *src2) __ksym __weak; 52 + bool bpf_cpumask_empty(const struct cpumask *cpumask) __ksym __weak; 53 + bool bpf_cpumask_full(const struct cpumask *cpumask) __ksym __weak; 54 + void bpf_cpumask_copy(struct bpf_cpumask *dst, const struct cpumask *src) __ksym __weak; 55 + u32 bpf_cpumask_any_distribute(const struct cpumask *src) __ksym __weak; 56 + u32 bpf_cpumask_any_and_distribute(const struct cpumask *src1, 57 + const struct cpumask *src2) __ksym __weak; 58 + u32 bpf_cpumask_weight(const struct cpumask *cpumask) __ksym __weak; 58 59 59 - void bpf_rcu_read_lock(void) __ksym; 60 - void bpf_rcu_read_unlock(void) __ksym; 60 + void bpf_rcu_read_lock(void) __ksym __weak; 61 + void bpf_rcu_read_unlock(void) __ksym __weak; 61 62 62 63 static inline const struct cpumask *cast(struct bpf_cpumask *cpumask) 63 64 {
+1 -2
tools/testing/selftests/bpf/progs/getpeername_unix_prog.c
··· 27 27 if (sa_kern->uaddrlen != unaddrlen) 28 28 return 1; 29 29 30 - sa_kern_unaddr = bpf_rdonly_cast(sa_kern->uaddr, 31 - bpf_core_type_id_kernel(struct sockaddr_un)); 30 + sa_kern_unaddr = bpf_core_cast(sa_kern->uaddr, struct sockaddr_un); 32 31 if (memcmp(sa_kern_unaddr->sun_path, SERVUN_REWRITE_ADDRESS, 33 32 sizeof(SERVUN_REWRITE_ADDRESS) - 1) != 0) 34 33 return 1;
+1 -2
tools/testing/selftests/bpf/progs/getsockname_unix_prog.c
··· 27 27 if (sa_kern->uaddrlen != unaddrlen) 28 28 return 1; 29 29 30 - sa_kern_unaddr = bpf_rdonly_cast(sa_kern->uaddr, 31 - bpf_core_type_id_kernel(struct sockaddr_un)); 30 + sa_kern_unaddr = bpf_core_cast(sa_kern->uaddr, struct sockaddr_un); 32 31 if (memcmp(sa_kern_unaddr->sun_path, SERVUN_REWRITE_ADDRESS, 33 32 sizeof(SERVUN_REWRITE_ADDRESS) - 1) != 0) 34 33 return 1;
+3 -2
tools/testing/selftests/bpf/progs/iters.c
··· 5 5 #include <linux/bpf.h> 6 6 #include <bpf/bpf_helpers.h> 7 7 #include "bpf_misc.h" 8 + #include "bpf_compiler.h" 8 9 9 10 #define ARRAY_SIZE(x) (int)(sizeof(x) / sizeof((x)[0])) 10 11 ··· 184 183 MY_PID_GUARD(); 185 184 186 185 bpf_iter_num_new(&it, 0, 2); 187 - #pragma nounroll 186 + __pragma_loop_no_unroll 188 187 for (i = 0; i < 3; i++) { 189 188 v = bpf_iter_num_next(&it); 190 189 bpf_printk("ITER_BASIC: E3 VAL: i=%d v=%d", i, v ? *v : -1); ··· 239 238 bpf_iter_num_destroy(&it); 240 239 241 240 bpf_iter_num_new(&it, 0, 2); 242 - #pragma nounroll 241 + __pragma_loop_no_unroll 243 242 for (i = 0; i < 3; i++) { 244 243 v = bpf_iter_num_next(&it); 245 244 bpf_printk("ITER_BASIC: E3 VAL: i=%d v=%d", i, v ? *v : -1);
+3 -1
tools/testing/selftests/bpf/progs/loop4.c
··· 3 3 #include <linux/bpf.h> 4 4 #include <bpf/bpf_helpers.h> 5 5 6 + #include "bpf_compiler.h" 7 + 6 8 char _license[] SEC("license") = "GPL"; 7 9 8 10 SEC("socket") ··· 12 10 { 13 11 int ret = 0, i; 14 12 15 - #pragma nounroll 13 + __pragma_loop_no_unroll 16 14 for (i = 0; i < 20; i++) 17 15 if (skb->len) 18 16 ret |= 1 << i;
+1 -1
tools/testing/selftests/bpf/progs/map_ptr_kern.c
··· 316 316 } __attribute__((preserve_access_index)); 317 317 318 318 struct lpm_key { 319 - struct bpf_lpm_trie_key trie_key; 319 + struct bpf_lpm_trie_key_hdr trie_key; 320 320 __u32 data; 321 321 }; 322 322
+9 -8
tools/testing/selftests/bpf/progs/profiler.inc.h
··· 8 8 #include "profiler.h" 9 9 #include "err.h" 10 10 #include "bpf_experimental.h" 11 + #include "bpf_compiler.h" 11 12 12 13 #ifndef NULL 13 14 #define NULL 0 ··· 170 169 int spid) 171 170 { 172 171 #ifdef UNROLL 173 - #pragma unroll 172 + __pragma_loop_unroll 174 173 #endif 175 174 for (int i = 0; i < ARRAY_SIZE(arr_struct->array); i++) 176 175 if (arr_struct->array[i].meta.pid == spid) ··· 186 185 187 186 ancestors_data->num_ancestors = 0; 188 187 #ifdef UNROLL 189 - #pragma unroll 188 + __pragma_loop_unroll 190 189 #endif 191 190 for (num_ancestors = 0; num_ancestors < MAX_ANCESTORS; num_ancestors++) { 192 191 parent = BPF_CORE_READ(parent, real_parent); ··· 213 212 size_t filepart_length; 214 213 215 214 #ifdef UNROLL 216 - #pragma unroll 215 + __pragma_loop_unroll 217 216 #endif 218 217 for (int i = 0; i < MAX_CGROUPS_PATH_DEPTH; i++) { 219 218 filepart_length = ··· 262 261 int cgrp_id = bpf_core_enum_value(enum cgroup_subsys_id___local, 263 262 pids_cgrp_id___local); 264 263 #ifdef UNROLL 265 - #pragma unroll 264 + __pragma_loop_unroll 266 265 #endif 267 266 for (int i = 0; i < CGROUP_SUBSYS_COUNT; i++) { 268 267 struct cgroup_subsys_state* subsys = ··· 403 402 if (kill_data == NULL) 404 403 return 0; 405 404 #ifdef UNROLL 406 - #pragma unroll 405 + __pragma_loop_unroll 407 406 #endif 408 407 for (int i = 0; i < ARRAY_SIZE(arr_struct->array); i++) 409 408 if (arr_struct->array[i].meta.pid == 0) { ··· 483 482 struct dentry* parent_dentry; 484 483 485 484 #ifdef UNROLL 486 - #pragma unroll 485 + __pragma_loop_unroll 487 486 #endif 488 487 for (int i = 0; i < MAX_PATH_DEPTH; i++) { 489 488 filepart_length = ··· 509 508 { 510 509 struct dentry* parent_dentry; 511 510 #ifdef UNROLL 512 - #pragma unroll 511 + __pragma_loop_unroll 513 512 #endif 514 513 for (int i = 0; i < MAX_PATH_DEPTH; i++) { 515 514 u64 dir_ino = BPF_CORE_READ(filp_dentry, d_inode, i_ino); ··· 630 629 struct kernfs_node* proc_kernfs = BPF_CORE_READ(task, cgroups, dfl_cgrp, kn); 631 630 632 631 #ifdef UNROLL 633 - #pragma unroll 632 + __pragma_loop_unroll 634 633 #endif 635 634 for (int i = 0; i < ARRAY_SIZE(arr_struct->array); i++) { 636 635 struct var_kill_data_t* past_kill_data = &arr_struct->array[i];
+4 -3
tools/testing/selftests/bpf/progs/pyperf.h
··· 8 8 #include <linux/bpf.h> 9 9 #include <bpf/bpf_helpers.h> 10 10 #include "bpf_misc.h" 11 + #include "bpf_compiler.h" 11 12 12 13 #define FUNCTION_NAME_LEN 64 13 14 #define FILE_NAME_LEN 128 ··· 299 298 #if defined(USE_ITER) 300 299 /* no for loop, no unrolling */ 301 300 #elif defined(NO_UNROLL) 302 - #pragma clang loop unroll(disable) 301 + __pragma_loop_no_unroll 303 302 #elif defined(UNROLL_COUNT) 304 - #pragma clang loop unroll_count(UNROLL_COUNT) 303 + __pragma_loop_unroll_count(UNROLL_COUNT) 305 304 #else 306 - #pragma clang loop unroll(full) 305 + __pragma_loop_unroll_full 307 306 #endif /* NO_UNROLL */ 308 307 /* Unwind python stack */ 309 308 #ifdef USE_ITER
+120
tools/testing/selftests/bpf/progs/rcu_read_lock.c
··· 319 319 bpf_rcu_read_unlock(); 320 320 return 0; 321 321 } 322 + 323 + __noinline 324 + static int static_subprog(void *ctx) 325 + { 326 + volatile int ret = 0; 327 + 328 + if (bpf_get_prandom_u32()) 329 + return ret + 42; 330 + return ret + bpf_get_prandom_u32(); 331 + } 332 + 333 + __noinline 334 + int global_subprog(u64 a) 335 + { 336 + volatile int ret = a; 337 + 338 + return ret + static_subprog(NULL); 339 + } 340 + 341 + __noinline 342 + static int static_subprog_lock(void *ctx) 343 + { 344 + volatile int ret = 0; 345 + 346 + bpf_rcu_read_lock(); 347 + if (bpf_get_prandom_u32()) 348 + return ret + 42; 349 + return ret + bpf_get_prandom_u32(); 350 + } 351 + 352 + __noinline 353 + int global_subprog_lock(u64 a) 354 + { 355 + volatile int ret = a; 356 + 357 + return ret + static_subprog_lock(NULL); 358 + } 359 + 360 + __noinline 361 + static int static_subprog_unlock(void *ctx) 362 + { 363 + volatile int ret = 0; 364 + 365 + bpf_rcu_read_unlock(); 366 + if (bpf_get_prandom_u32()) 367 + return ret + 42; 368 + return ret + bpf_get_prandom_u32(); 369 + } 370 + 371 + __noinline 372 + int global_subprog_unlock(u64 a) 373 + { 374 + volatile int ret = a; 375 + 376 + return ret + static_subprog_unlock(NULL); 377 + } 378 + 379 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 380 + int rcu_read_lock_subprog(void *ctx) 381 + { 382 + volatile int ret = 0; 383 + 384 + bpf_rcu_read_lock(); 385 + if (bpf_get_prandom_u32()) 386 + ret += static_subprog(ctx); 387 + bpf_rcu_read_unlock(); 388 + return 0; 389 + } 390 + 391 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 392 + int rcu_read_lock_global_subprog(void *ctx) 393 + { 394 + volatile int ret = 0; 395 + 396 + bpf_rcu_read_lock(); 397 + if (bpf_get_prandom_u32()) 398 + ret += global_subprog(ret); 399 + bpf_rcu_read_unlock(); 400 + return 0; 401 + } 402 + 403 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 404 + int rcu_read_lock_subprog_lock(void *ctx) 405 + { 406 + volatile int ret = 0; 407 + 408 + ret += static_subprog_lock(ctx); 409 + bpf_rcu_read_unlock(); 410 + return 0; 411 + } 412 + 413 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 414 + int rcu_read_lock_global_subprog_lock(void *ctx) 415 + { 416 + volatile int ret = 0; 417 + 418 + ret += global_subprog_lock(ret); 419 + bpf_rcu_read_unlock(); 420 + return 0; 421 + } 422 + 423 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 424 + int rcu_read_lock_subprog_unlock(void *ctx) 425 + { 426 + volatile int ret = 0; 427 + 428 + bpf_rcu_read_lock(); 429 + ret += static_subprog_unlock(ctx); 430 + return 0; 431 + } 432 + 433 + SEC("?fentry.s/" SYS_PREFIX "sys_getpgid") 434 + int rcu_read_lock_global_subprog_unlock(void *ctx) 435 + { 436 + volatile int ret = 0; 437 + 438 + bpf_rcu_read_lock(); 439 + ret += global_subprog_unlock(ret); 440 + return 0; 441 + }
+1 -2
tools/testing/selftests/bpf/progs/recvmsg_unix_prog.c
··· 27 27 if (sa_kern->uaddrlen != unaddrlen) 28 28 return 1; 29 29 30 - sa_kern_unaddr = bpf_rdonly_cast(sa_kern->uaddr, 31 - bpf_core_type_id_kernel(struct sockaddr_un)); 30 + sa_kern_unaddr = bpf_core_cast(sa_kern->uaddr, struct sockaddr_un); 32 31 if (memcmp(sa_kern_unaddr->sun_path, SERVUN_ADDRESS, 33 32 sizeof(SERVUN_ADDRESS) - 1) != 0) 34 33 return 1;
+1 -2
tools/testing/selftests/bpf/progs/sendmsg_unix_prog.c
··· 28 28 if (sa_kern->uaddrlen != unaddrlen) 29 29 return 0; 30 30 31 - sa_kern_unaddr = bpf_rdonly_cast(sa_kern->uaddr, 32 - bpf_core_type_id_kernel(struct sockaddr_un)); 31 + sa_kern_unaddr = bpf_core_cast(sa_kern->uaddr, struct sockaddr_un); 33 32 if (memcmp(sa_kern_unaddr->sun_path, SERVUN_REWRITE_ADDRESS, 34 33 sizeof(SERVUN_REWRITE_ADDRESS) - 1) != 0) 35 34 return 0;
+1 -3
tools/testing/selftests/bpf/progs/sk_storage_omem_uncharge.c
··· 12 12 __u64 cookie = 0; 13 13 __u32 omem = 0; 14 14 15 - void *bpf_rdonly_cast(void *, __u32) __ksym; 16 - 17 15 struct { 18 16 __uint(type, BPF_MAP_TYPE_SK_STORAGE); 19 17 __uint(map_flags, BPF_F_NO_PREALLOC); ··· 27 29 if (local_storage_ptr != local_storage) 28 30 return 0; 29 31 30 - sk = bpf_rdonly_cast(sk_ptr, bpf_core_type_id_kernel(struct sock)); 32 + sk = bpf_core_cast(sk_ptr, struct sock); 31 33 if (sk->sk_cookie.counter != cookie) 32 34 return 0; 33 35
+2 -2
tools/testing/selftests/bpf/progs/sock_iter_batch.c
··· 32 32 if (!sk) 33 33 return 0; 34 34 35 - sk = bpf_rdonly_cast(sk, bpf_core_type_id_kernel(struct sock)); 35 + sk = bpf_core_cast(sk, struct sock); 36 36 if (sk->sk_family != AF_INET6 || 37 37 sk->sk_state != TCP_LISTEN || 38 38 !ipv6_addr_loopback(&sk->sk_v6_rcv_saddr)) ··· 68 68 if (!sk) 69 69 return 0; 70 70 71 - sk = bpf_rdonly_cast(sk, bpf_core_type_id_kernel(struct sock)); 71 + sk = bpf_core_cast(sk, struct sock); 72 72 if (sk->sk_family != AF_INET6 || 73 73 !ipv6_addr_loopback(&sk->sk_v6_rcv_saddr)) 74 74 return 0;
+10 -8
tools/testing/selftests/bpf/progs/strobemeta.h
··· 10 10 #include <linux/types.h> 11 11 #include <bpf/bpf_helpers.h> 12 12 13 + #include "bpf_compiler.h" 14 + 13 15 typedef uint32_t pid_t; 14 16 struct task_struct {}; 15 17 ··· 421 419 } 422 420 423 421 #ifdef NO_UNROLL 424 - #pragma clang loop unroll(disable) 422 + __pragma_loop_no_unroll 425 423 #else 426 - #pragma unroll 424 + __pragma_loop_unroll 427 425 #endif 428 426 for (int i = 0; i < STROBE_MAX_MAP_ENTRIES; ++i) { 429 427 if (i >= map.cnt) ··· 562 560 payload_off = sizeof(data->payload); 563 561 #else 564 562 #ifdef NO_UNROLL 565 - #pragma clang loop unroll(disable) 563 + __pragma_loop_no_unroll 566 564 #else 567 - #pragma unroll 565 + __pragma_loop_unroll 568 566 #endif /* NO_UNROLL */ 569 567 for (int i = 0; i < STROBE_MAX_INTS; ++i) { 570 568 read_int_var(cfg, i, tls_base, &value, data); 571 569 } 572 570 #ifdef NO_UNROLL 573 - #pragma clang loop unroll(disable) 571 + __pragma_loop_no_unroll 574 572 #else 575 - #pragma unroll 573 + __pragma_loop_unroll 576 574 #endif /* NO_UNROLL */ 577 575 for (int i = 0; i < STROBE_MAX_STRS; ++i) { 578 576 payload_off = read_str_var(cfg, i, tls_base, &value, data, payload_off); 579 577 } 580 578 #ifdef NO_UNROLL 581 - #pragma clang loop unroll(disable) 579 + __pragma_loop_no_unroll 582 580 #else 583 - #pragma unroll 581 + __pragma_loop_unroll 584 582 #endif /* NO_UNROLL */ 585 583 for (int i = 0; i < STROBE_MAX_MAPS; ++i) { 586 584 payload_off = read_map_var(cfg, i, tls_base, &value, data, payload_off);
+29
tools/testing/selftests/bpf/progs/struct_ops_maybe_null.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <vmlinux.h> 4 + #include <bpf/bpf_tracing.h> 5 + #include "../bpf_testmod/bpf_testmod.h" 6 + 7 + char _license[] SEC("license") = "GPL"; 8 + 9 + pid_t tgid = 0; 10 + 11 + /* This is a test BPF program that uses struct_ops to access an argument 12 + * that may be NULL. This is a test for the verifier to ensure that it can 13 + * rip PTR_MAYBE_NULL correctly. 14 + */ 15 + SEC("struct_ops/test_maybe_null") 16 + int BPF_PROG(test_maybe_null, int dummy, 17 + struct task_struct *task) 18 + { 19 + if (task) 20 + tgid = task->tgid; 21 + 22 + return 0; 23 + } 24 + 25 + SEC(".struct_ops.link") 26 + struct bpf_testmod_ops testmod_1 = { 27 + .test_maybe_null = (void *)test_maybe_null, 28 + }; 29 +
+24
tools/testing/selftests/bpf/progs/struct_ops_maybe_null_fail.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + #include <vmlinux.h> 4 + #include <bpf/bpf_tracing.h> 5 + #include "../bpf_testmod/bpf_testmod.h" 6 + 7 + char _license[] SEC("license") = "GPL"; 8 + 9 + pid_t tgid = 0; 10 + 11 + SEC("struct_ops/test_maybe_null_struct_ptr") 12 + int BPF_PROG(test_maybe_null_struct_ptr, int dummy, 13 + struct task_struct *task) 14 + { 15 + tgid = task->tgid; 16 + 17 + return 0; 18 + } 19 + 20 + SEC(".struct_ops.link") 21 + struct bpf_testmod_ops testmod_struct_ptr = { 22 + .test_maybe_null = (void *)test_maybe_null_struct_ptr, 23 + }; 24 +
+9 -2
tools/testing/selftests/bpf/progs/struct_ops_module.c
··· 16 16 } 17 17 18 18 SEC("struct_ops/test_2") 19 - int BPF_PROG(test_2, int a, int b) 19 + void BPF_PROG(test_2, int a, int b) 20 20 { 21 21 test_2_result = a + b; 22 - return a + b; 22 + } 23 + 24 + SEC("struct_ops/test_3") 25 + int BPF_PROG(test_3, int a, int b) 26 + { 27 + test_2_result = a + b + 3; 28 + return a + b + 3; 23 29 } 24 30 25 31 SEC(".struct_ops.link") 26 32 struct bpf_testmod_ops testmod_1 = { 27 33 .test_1 = (void *)test_1, 28 34 .test_2 = (void *)test_2, 35 + .data = 0x1, 29 36 }; 30 37
-17
tools/testing/selftests/bpf/progs/task_ls_recursion.c
··· 27 27 __type(value, long); 28 28 } map_b SEC(".maps"); 29 29 30 - SEC("fentry/bpf_local_storage_lookup") 31 - int BPF_PROG(on_lookup) 32 - { 33 - struct task_struct *task = bpf_get_current_task_btf(); 34 - 35 - if (!test_pid || task->pid != test_pid) 36 - return 0; 37 - 38 - /* The bpf_task_storage_delete will call 39 - * bpf_local_storage_lookup. The prog->active will 40 - * stop the recursion. 41 - */ 42 - bpf_task_storage_delete(&map_a, task); 43 - bpf_task_storage_delete(&map_b, task); 44 - return 0; 45 - } 46 - 47 30 SEC("fentry/bpf_local_storage_update") 48 31 int BPF_PROG(on_update) 49 32 {
+5 -2
tools/testing/selftests/bpf/progs/test_cls_redirect.c
··· 20 20 #include <bpf/bpf_helpers.h> 21 21 #include <bpf/bpf_endian.h> 22 22 23 + #include "bpf_compiler.h" 23 24 #include "test_cls_redirect.h" 25 + 26 + #pragma GCC diagnostic ignored "-Waddress-of-packed-member" 24 27 25 28 #ifdef SUBPROGS 26 29 #define INLINING __noinline ··· 270 267 uint32_t acc = 0; 271 268 uint16_t *ipw = (uint16_t *)iph; 272 269 273 - #pragma clang loop unroll(full) 270 + __pragma_loop_unroll_full 274 271 for (size_t i = 0; i < sizeof(struct iphdr) / 2; i++) { 275 272 acc += ipw[i]; 276 273 } ··· 297 294 }; 298 295 *is_fragment = false; 299 296 300 - #pragma clang loop unroll(full) 297 + __pragma_loop_unroll_full 301 298 for (int i = 0; i < 6; i++) { 302 299 switch (exthdr.next) { 303 300 case IPPROTO_FRAGMENT:
+2
tools/testing/selftests/bpf/progs/test_cls_redirect_dynptr.c
··· 23 23 #include "test_cls_redirect.h" 24 24 #include "bpf_kfuncs.h" 25 25 26 + #pragma GCC diagnostic ignored "-Waddress-of-packed-member" 27 + 26 28 #define offsetofend(TYPE, MEMBER) \ 27 29 (offsetof(TYPE, MEMBER) + sizeof((((TYPE *)0)->MEMBER))) 28 30
+6 -2
tools/testing/selftests/bpf/progs/test_global_func1.c
··· 5 5 #include <bpf/bpf_helpers.h> 6 6 #include "bpf_misc.h" 7 7 8 - #define MAX_STACK (512 - 3 * 32 + 8) 8 + #define MAX_STACK 260 9 9 10 10 static __attribute__ ((noinline)) 11 11 int f0(int var, struct __sk_buff *skb) ··· 30 30 __attribute__ ((noinline)) 31 31 int f2(int val, struct __sk_buff *skb) 32 32 { 33 + volatile char buf[MAX_STACK] = {}; 34 + 35 + __sink(buf[MAX_STACK - 1]); 36 + 33 37 return f1(skb) + f3(val, skb, 1); 34 38 } 35 39 ··· 48 44 } 49 45 50 46 SEC("tc") 51 - __failure __msg("combined stack size of 4 calls is 544") 47 + __failure __msg("combined stack size of 3 calls is") 52 48 int global_func1(struct __sk_buff *skb) 53 49 { 54 50 return f0(1, skb) + f1(skb) + f2(2, skb) + f3(3, skb, 4);
+19
tools/testing/selftests/bpf/progs/test_global_func_ctx_args.c
··· 26 26 return kprobe_typedef_ctx_subprog(ctx); 27 27 } 28 28 29 + /* s390x defines: 30 + * 31 + * typedef user_pt_regs bpf_user_pt_regs_t; 32 + * typedef struct { ... } user_pt_regs; 33 + * 34 + * And so "canonical" underlying struct type is anonymous. 35 + * So on s390x only valid ways to have PTR_TO_CTX argument in global subprogs 36 + * are: 37 + * - bpf_user_pt_regs_t *ctx (typedef); 38 + * - struct bpf_user_pt_regs_t *ctx (backwards compatible struct hack); 39 + * - void *ctx __arg_ctx (arg:ctx tag) 40 + * 41 + * Other architectures also allow using underlying struct types (e.g., 42 + * `struct pt_regs *ctx` for x86-64) 43 + */ 44 + #ifndef bpf_target_s390 45 + 29 46 #define pt_regs_struct_t typeof(*(__PT_REGS_CAST((struct pt_regs *)NULL))) 30 47 31 48 __weak int kprobe_struct_ctx_subprog(pt_regs_struct_t *ctx) ··· 56 39 { 57 40 return kprobe_struct_ctx_subprog(ctx); 58 41 } 42 + 43 + #endif 59 44 60 45 /* this is current hack to make this work on old kernels */ 61 46 struct bpf_user_pt_regs_t {};
+4 -2
tools/testing/selftests/bpf/progs/test_lwt_seg6local.c
··· 6 6 #include <bpf/bpf_helpers.h> 7 7 #include <bpf/bpf_endian.h> 8 8 9 + #include "bpf_compiler.h" 10 + 9 11 /* Packet parsing state machine helpers. */ 10 12 #define cursor_advance(_cursor, _len) \ 11 13 ({ void *_tmp = _cursor; _cursor += _len; _tmp; }) ··· 133 131 *pad_off = 0; 134 132 135 133 // we can only go as far as ~10 TLVs due to the BPF max stack size 136 - #pragma clang loop unroll(full) 134 + __pragma_loop_unroll_full 137 135 for (int i = 0; i < 10; i++) { 138 136 struct sr6_tlv_t tlv; 139 137 ··· 304 302 305 303 seg = (struct ip6_addr_t *)((char *)srh + sizeof(*srh)); 306 304 307 - #pragma clang loop unroll(full) 305 + __pragma_loop_unroll_full 308 306 for (unsigned long long lo = 0; lo < 4; lo++) { 309 307 seg->lo = bpf_cpu_to_be64(4 - lo); 310 308 seg->hi = bpf_cpu_to_be64(hi);
+3 -3
tools/testing/selftests/bpf/progs/test_ptr_untrusted.c
··· 6 6 7 7 char tp_name[128]; 8 8 9 - SEC("lsm/bpf") 9 + SEC("lsm.s/bpf") 10 10 int BPF_PROG(lsm_run, int cmd, union bpf_attr *attr, unsigned int size) 11 11 { 12 12 switch (cmd) { 13 13 case BPF_RAW_TRACEPOINT_OPEN: 14 - bpf_probe_read_user_str(tp_name, sizeof(tp_name) - 1, 15 - (void *)attr->raw_tracepoint.name); 14 + bpf_copy_from_user(tp_name, sizeof(tp_name) - 1, 15 + (void *)attr->raw_tracepoint.name); 16 16 break; 17 17 default: 18 18 break;
+3 -1
tools/testing/selftests/bpf/progs/test_seg6_loop.c
··· 6 6 #include <bpf/bpf_helpers.h> 7 7 #include <bpf/bpf_endian.h> 8 8 9 + #include "bpf_compiler.h" 10 + 9 11 /* Packet parsing state machine helpers. */ 10 12 #define cursor_advance(_cursor, _len) \ 11 13 ({ void *_tmp = _cursor; _cursor += _len; _tmp; }) ··· 136 134 // we can only go as far as ~10 TLVs due to the BPF max stack size 137 135 // workaround: define induction variable "i" as "long" instead 138 136 // of "int" to prevent alu32 sub-register spilling. 139 - #pragma clang loop unroll(disable) 137 + __pragma_loop_no_unroll 140 138 for (long i = 0; i < 100; i++) { 141 139 struct sr6_tlv_t tlv; 142 140
+3 -1
tools/testing/selftests/bpf/progs/test_skb_ctx.c
··· 3 3 #include <linux/bpf.h> 4 4 #include <bpf/bpf_helpers.h> 5 5 6 + #include "bpf_compiler.h" 7 + 6 8 char _license[] SEC("license") = "GPL"; 7 9 8 10 SEC("tc") 9 11 int process(struct __sk_buff *skb) 10 12 { 11 - #pragma clang loop unroll(full) 13 + __pragma_loop_unroll_full 12 14 for (int i = 0; i < 5; i++) { 13 15 if (skb->cb[i] != i + 1) 14 16 return 1;
+65
tools/testing/selftests/bpf/progs/test_spin_lock.c
··· 101 101 err: 102 102 return err; 103 103 } 104 + 105 + struct bpf_spin_lock lockA __hidden SEC(".data.A"); 106 + 107 + __noinline 108 + static int static_subprog(struct __sk_buff *ctx) 109 + { 110 + volatile int ret = 0; 111 + 112 + if (ctx->protocol) 113 + return ret; 114 + return ret + ctx->len; 115 + } 116 + 117 + __noinline 118 + static int static_subprog_lock(struct __sk_buff *ctx) 119 + { 120 + volatile int ret = 0; 121 + 122 + ret = static_subprog(ctx); 123 + bpf_spin_lock(&lockA); 124 + return ret + ctx->len; 125 + } 126 + 127 + __noinline 128 + static int static_subprog_unlock(struct __sk_buff *ctx) 129 + { 130 + volatile int ret = 0; 131 + 132 + ret = static_subprog(ctx); 133 + bpf_spin_unlock(&lockA); 134 + return ret + ctx->len; 135 + } 136 + 137 + SEC("tc") 138 + int lock_static_subprog_call(struct __sk_buff *ctx) 139 + { 140 + int ret = 0; 141 + 142 + bpf_spin_lock(&lockA); 143 + if (ctx->mark == 42) 144 + ret = static_subprog(ctx); 145 + bpf_spin_unlock(&lockA); 146 + return ret; 147 + } 148 + 149 + SEC("tc") 150 + int lock_static_subprog_lock(struct __sk_buff *ctx) 151 + { 152 + int ret = 0; 153 + 154 + ret = static_subprog_lock(ctx); 155 + bpf_spin_unlock(&lockA); 156 + return ret; 157 + } 158 + 159 + SEC("tc") 160 + int lock_static_subprog_unlock(struct __sk_buff *ctx) 161 + { 162 + int ret = 0; 163 + 164 + bpf_spin_lock(&lockA); 165 + ret = static_subprog_unlock(ctx); 166 + return ret; 167 + } 168 + 104 169 char _license[] SEC("license") = "GPL";
+44
tools/testing/selftests/bpf/progs/test_spin_lock_fail.c
··· 201 201 202 202 #undef CHECK 203 203 204 + __noinline 205 + int global_subprog(struct __sk_buff *ctx) 206 + { 207 + volatile int ret = 0; 208 + 209 + if (ctx->protocol) 210 + ret += ctx->protocol; 211 + return ret + ctx->mark; 212 + } 213 + 214 + __noinline 215 + static int static_subprog_call_global(struct __sk_buff *ctx) 216 + { 217 + volatile int ret = 0; 218 + 219 + if (ctx->protocol) 220 + return ret; 221 + return ret + ctx->len + global_subprog(ctx); 222 + } 223 + 224 + SEC("?tc") 225 + int lock_global_subprog_call1(struct __sk_buff *ctx) 226 + { 227 + int ret = 0; 228 + 229 + bpf_spin_lock(&lockA); 230 + if (ctx->mark == 42) 231 + ret = global_subprog(ctx); 232 + bpf_spin_unlock(&lockA); 233 + return ret; 234 + } 235 + 236 + SEC("?tc") 237 + int lock_global_subprog_call2(struct __sk_buff *ctx) 238 + { 239 + int ret = 0; 240 + 241 + bpf_spin_lock(&lockA); 242 + if (ctx->mark == 42) 243 + ret = static_subprog_call_global(ctx); 244 + bpf_spin_unlock(&lockA); 245 + return ret; 246 + } 247 + 204 248 char _license[] SEC("license") = "GPL";
+4 -2
tools/testing/selftests/bpf/progs/test_sysctl_loop1.c
··· 9 9 10 10 #include <bpf/bpf_helpers.h> 11 11 12 + #include "bpf_compiler.h" 13 + 12 14 #ifndef ARRAY_SIZE 13 15 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 14 16 #endif ··· 32 30 if (ret < 0 || ret != sizeof(tcp_mem_name) - 1) 33 31 return 0; 34 32 35 - #pragma clang loop unroll(disable) 33 + __pragma_loop_no_unroll 36 34 for (i = 0; i < sizeof(tcp_mem_name); ++i) 37 35 if (name[i] != tcp_mem_name[i]) 38 36 return 0; ··· 61 59 if (ret < 0 || ret >= MAX_VALUE_STR_LEN) 62 60 return 0; 63 61 64 - #pragma clang loop unroll(disable) 62 + __pragma_loop_no_unroll 65 63 for (i = 0; i < ARRAY_SIZE(tcp_mem); ++i) { 66 64 ret = bpf_strtoul(value + off, MAX_ULONG_STR_LEN, 0, 67 65 tcp_mem + i);
+4 -2
tools/testing/selftests/bpf/progs/test_sysctl_loop2.c
··· 9 9 10 10 #include <bpf/bpf_helpers.h> 11 11 12 + #include "bpf_compiler.h" 13 + 12 14 #ifndef ARRAY_SIZE 13 15 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 14 16 #endif ··· 32 30 if (ret < 0 || ret != sizeof(tcp_mem_name) - 1) 33 31 return 0; 34 32 35 - #pragma clang loop unroll(disable) 33 + __pragma_loop_no_unroll 36 34 for (i = 0; i < sizeof(tcp_mem_name); ++i) 37 35 if (name[i] != tcp_mem_name[i]) 38 36 return 0; ··· 59 57 if (ret < 0 || ret >= MAX_VALUE_STR_LEN) 60 58 return 0; 61 59 62 - #pragma clang loop unroll(disable) 60 + __pragma_loop_no_unroll 63 61 for (i = 0; i < ARRAY_SIZE(tcp_mem); ++i) { 64 62 ret = bpf_strtoul(value + off, MAX_ULONG_STR_LEN, 0, 65 63 tcp_mem + i);
+4 -2
tools/testing/selftests/bpf/progs/test_sysctl_prog.c
··· 9 9 10 10 #include <bpf/bpf_helpers.h> 11 11 12 + #include "bpf_compiler.h" 13 + 12 14 /* Max supported length of a string with unsigned long in base 10 (pow2 - 1). */ 13 15 #define MAX_ULONG_STR_LEN 0xF 14 16 ··· 33 31 if (ret < 0 || ret != sizeof(tcp_mem_name) - 1) 34 32 return 0; 35 33 36 - #pragma clang loop unroll(full) 34 + __pragma_loop_unroll_full 37 35 for (i = 0; i < sizeof(tcp_mem_name); ++i) 38 36 if (name[i] != tcp_mem_name[i]) 39 37 return 0; ··· 59 57 if (ret < 0 || ret >= MAX_VALUE_STR_LEN) 60 58 return 0; 61 59 62 - #pragma clang loop unroll(full) 60 + __pragma_loop_unroll_full 63 61 for (i = 0; i < ARRAY_SIZE(tcp_mem); ++i) { 64 62 ret = bpf_strtoul(value + off, MAX_ULONG_STR_LEN, 0, 65 63 tcp_mem + i);
+4 -1
tools/testing/selftests/bpf/progs/test_tc_tunnel.c
··· 19 19 20 20 #include <bpf/bpf_endian.h> 21 21 #include <bpf/bpf_helpers.h> 22 + #include "bpf_compiler.h" 23 + 24 + #pragma GCC diagnostic ignored "-Waddress-of-packed-member" 22 25 23 26 static const int cfg_port = 8000; 24 27 ··· 84 81 85 82 iph->check = 0; 86 83 87 - #pragma clang loop unroll(full) 84 + __pragma_loop_unroll_full 88 85 for (i = 0, csum = 0; i < sizeof(*iph) >> 1; i++) 89 86 csum += *iph16++; 90 87
+52 -29
tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c
··· 10 10 #include "test_siphash.h" 11 11 #include "test_tcp_custom_syncookie.h" 12 12 13 + #define MAX_PACKET_OFF 0xffff 14 + 13 15 /* Hash is calculated for each client and split into ISN and TS. 14 16 * 15 17 * MSB LSB ··· 54 52 55 53 struct tcp_syncookie { 56 54 struct __sk_buff *skb; 55 + void *data; 57 56 void *data_end; 58 57 struct ethhdr *eth; 59 58 struct iphdr *ipv4; 60 59 struct ipv6hdr *ipv6; 61 60 struct tcphdr *tcp; 62 - union { 63 - char *ptr; 64 - __be32 *ptr32; 65 - }; 61 + __be32 *ptr32; 66 62 struct bpf_tcp_req_attrs attrs; 63 + u32 off; 67 64 u32 cookie; 68 65 u64 first; 69 66 }; ··· 71 70 72 71 static int tcp_load_headers(struct tcp_syncookie *ctx) 73 72 { 73 + ctx->data = (void *)(long)ctx->skb->data; 74 74 ctx->data_end = (void *)(long)ctx->skb->data_end; 75 75 ctx->eth = (struct ethhdr *)(long)ctx->skb->data; 76 76 ··· 136 134 if (bpf_skb_change_tail(ctx->skb, data_len + 60 - ctx->tcp->doff * 4, 0)) 137 135 goto err; 138 136 137 + ctx->data = (void *)(long)ctx->skb->data; 139 138 ctx->data_end = (void *)(long)ctx->skb->data_end; 140 139 ctx->eth = (struct ethhdr *)(long)ctx->skb->data; 141 140 if (ctx->ipv4) { ··· 198 195 return -1; 199 196 } 200 197 198 + static __always_inline void *next(struct tcp_syncookie *ctx, __u32 sz) 199 + { 200 + __u64 off = ctx->off; 201 + __u8 *data; 202 + 203 + /* Verifier forbids access to packet when offset exceeds MAX_PACKET_OFF */ 204 + if (off > MAX_PACKET_OFF - sz) 205 + return NULL; 206 + 207 + data = ctx->data + off; 208 + barrier_var(data); 209 + if (data + sz >= ctx->data_end) 210 + return NULL; 211 + 212 + ctx->off += sz; 213 + return data; 214 + } 215 + 201 216 static int tcp_parse_option(__u32 index, struct tcp_syncookie *ctx) 202 217 { 203 - char opcode, opsize; 218 + __u8 *opcode, *opsize, *wscale; 219 + __u32 *tsval, *tsecr; 220 + __u16 *mss; 221 + __u32 off; 204 222 205 - if (ctx->ptr + 1 > ctx->data_end) 223 + off = ctx->off; 224 + opcode = next(ctx, 1); 225 + if (!opcode) 206 226 goto stop; 207 227 208 - opcode = *ctx->ptr++; 209 - 210 - if (opcode == TCPOPT_EOL) 228 + if (*opcode == TCPOPT_EOL) 211 229 goto stop; 212 230 213 - if (opcode == TCPOPT_NOP) 231 + if (*opcode == TCPOPT_NOP) 214 232 goto next; 215 233 216 - if (ctx->ptr + 1 > ctx->data_end) 234 + opsize = next(ctx, 1); 235 + if (!opsize) 217 236 goto stop; 218 237 219 - opsize = *ctx->ptr++; 220 - 221 - if (opsize < 2) 238 + if (*opsize < 2) 222 239 goto stop; 223 240 224 - switch (opcode) { 241 + switch (*opcode) { 225 242 case TCPOPT_MSS: 226 - if (opsize == TCPOLEN_MSS && ctx->tcp->syn && 227 - ctx->ptr + (TCPOLEN_MSS - 2) < ctx->data_end) 228 - ctx->attrs.mss = get_unaligned_be16(ctx->ptr); 243 + mss = next(ctx, 2); 244 + if (*opsize == TCPOLEN_MSS && ctx->tcp->syn && mss) 245 + ctx->attrs.mss = get_unaligned_be16(mss); 229 246 break; 230 247 case TCPOPT_WINDOW: 231 - if (opsize == TCPOLEN_WINDOW && ctx->tcp->syn && 232 - ctx->ptr + (TCPOLEN_WINDOW - 2) < ctx->data_end) { 248 + wscale = next(ctx, 1); 249 + if (*opsize == TCPOLEN_WINDOW && ctx->tcp->syn && wscale) { 233 250 ctx->attrs.wscale_ok = 1; 234 - ctx->attrs.snd_wscale = *ctx->ptr; 251 + ctx->attrs.snd_wscale = *wscale; 235 252 } 236 253 break; 237 254 case TCPOPT_TIMESTAMP: 238 - if (opsize == TCPOLEN_TIMESTAMP && 239 - ctx->ptr + (TCPOLEN_TIMESTAMP - 2) < ctx->data_end) { 240 - ctx->attrs.rcv_tsval = get_unaligned_be32(ctx->ptr); 241 - ctx->attrs.rcv_tsecr = get_unaligned_be32(ctx->ptr + 4); 255 + tsval = next(ctx, 4); 256 + tsecr = next(ctx, 4); 257 + if (*opsize == TCPOLEN_TIMESTAMP && tsval && tsecr) { 258 + ctx->attrs.rcv_tsval = get_unaligned_be32(tsval); 259 + ctx->attrs.rcv_tsecr = get_unaligned_be32(tsecr); 242 260 243 261 if (ctx->tcp->syn && ctx->attrs.rcv_tsecr) 244 262 ctx->attrs.tstamp_ok = 0; ··· 268 244 } 269 245 break; 270 246 case TCPOPT_SACK_PERM: 271 - if (opsize == TCPOLEN_SACK_PERM && ctx->tcp->syn && 272 - ctx->ptr + (TCPOLEN_SACK_PERM - 2) < ctx->data_end) 247 + if (*opsize == TCPOLEN_SACK_PERM && ctx->tcp->syn) 273 248 ctx->attrs.sack_ok = 1; 274 249 break; 275 250 } 276 251 277 - ctx->ptr += opsize - 2; 252 + ctx->off = off + *opsize; 278 253 next: 279 254 return 0; 280 255 stop: ··· 282 259 283 260 static void tcp_parse_options(struct tcp_syncookie *ctx) 284 261 { 285 - ctx->ptr = (char *)(ctx->tcp + 1); 262 + ctx->off = (__u8 *)(ctx->tcp + 1) - (__u8 *)ctx->data, 286 263 287 264 bpf_loop(40, tcp_parse_option, ctx, 0); 288 265 }
+2 -1
tools/testing/selftests/bpf/progs/test_xdp.c
··· 19 19 #include <bpf/bpf_helpers.h> 20 20 #include <bpf/bpf_endian.h> 21 21 #include "test_iptunnel_common.h" 22 + #include "bpf_compiler.h" 22 23 23 24 struct { 24 25 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); ··· 138 137 iph->ttl = 8; 139 138 140 139 next_iph = (__u16 *)iph; 141 - #pragma clang loop unroll(full) 140 + __pragma_loop_unroll_full 142 141 for (i = 0; i < sizeof(*iph) >> 1; i++) 143 142 csum += *next_iph++; 144 143
+2 -1
tools/testing/selftests/bpf/progs/test_xdp_loop.c
··· 15 15 #include <bpf/bpf_helpers.h> 16 16 #include <bpf/bpf_endian.h> 17 17 #include "test_iptunnel_common.h" 18 + #include "bpf_compiler.h" 18 19 19 20 struct { 20 21 __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); ··· 134 133 iph->ttl = 8; 135 134 136 135 next_iph = (__u16 *)iph; 137 - #pragma clang loop unroll(disable) 136 + __pragma_loop_no_unroll 138 137 for (i = 0; i < sizeof(*iph) >> 1; i++) 139 138 csum += *next_iph++; 140 139
+3 -2
tools/testing/selftests/bpf/progs/test_xdp_noinline.c
··· 15 15 #include <linux/udp.h> 16 16 #include <bpf/bpf_helpers.h> 17 17 #include <bpf/bpf_endian.h> 18 + #include "bpf_compiler.h" 18 19 19 20 static __always_inline __u32 rol32(__u32 word, unsigned int shift) 20 21 { ··· 363 362 iph->ttl = 4; 364 363 365 364 next_iph_u16 = (__u16 *) iph; 366 - #pragma clang loop unroll(full) 365 + __pragma_loop_unroll_full 367 366 for (int i = 0; i < sizeof(struct iphdr) >> 1; i++) 368 367 csum += *next_iph_u16++; 369 368 iph->check = ~((csum & 0xffff) + (csum >> 16)); ··· 410 409 iph->saddr = tmp_addr; 411 410 iph->check = 0; 412 411 next_iph_u16 = (__u16 *) iph; 413 - #pragma clang loop unroll(full) 412 + __pragma_loop_unroll_full 414 413 for (int i = 0; i < sizeof(struct iphdr) >> 1; i++) 415 414 csum += *next_iph_u16++; 416 415 iph->check = ~((csum & 0xffff) + (csum >> 16));
+20
tools/testing/selftests/bpf/progs/tracing_failure.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include "vmlinux.h" 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + 8 + char _license[] SEC("license") = "GPL"; 9 + 10 + SEC("?fentry/bpf_spin_lock") 11 + int BPF_PROG(test_spin_lock, struct bpf_spin_lock *lock) 12 + { 13 + return 0; 14 + } 15 + 16 + SEC("?fentry/bpf_spin_unlock") 17 + int BPF_PROG(test_spin_unlock, struct bpf_spin_lock *lock) 18 + { 19 + return 0; 20 + }
+5 -8
tools/testing/selftests/bpf/progs/type_cast.c
··· 4 4 #include <bpf/bpf_helpers.h> 5 5 #include <bpf/bpf_tracing.h> 6 6 #include <bpf/bpf_core_read.h> 7 + #include "bpf_kfuncs.h" 7 8 8 9 struct { 9 10 __uint(type, BPF_MAP_TYPE_TASK_STORAGE); ··· 19 18 char name[IFNAMSIZ]; 20 19 unsigned int inum; 21 20 unsigned int meta_len, frag0_len, kskb_len, kskb2_len; 22 - 23 - void *bpf_cast_to_kern_ctx(void *) __ksym; 24 - void *bpf_rdonly_cast(void *, __u32) __ksym; 25 21 26 22 SEC("?xdp") 27 23 int md_xdp(struct xdp_md *ctx) ··· 46 48 /* Simulate the following kernel macro: 47 49 * #define skb_shinfo(SKB) ((struct skb_shared_info *)(skb_end_pointer(SKB))) 48 50 */ 49 - shared_info = bpf_rdonly_cast(kskb->head + kskb->end, 50 - bpf_core_type_id_kernel(struct skb_shared_info)); 51 + shared_info = bpf_core_cast(kskb->head + kskb->end, struct skb_shared_info); 51 52 meta_len = shared_info->meta_len; 52 53 frag0_len = shared_info->frag_list->len; 53 54 54 55 /* kskb2 should be equal to kskb */ 55 - kskb2 = bpf_rdonly_cast(kskb, bpf_core_type_id_kernel(struct sk_buff)); 56 + kskb2 = bpf_core_cast(kskb, typeof(*kskb2)); 56 57 kskb2_len = kskb2->len; 57 58 return 0; 58 59 } ··· 62 65 struct task_struct *task, *task_dup; 63 66 64 67 task = bpf_get_current_task_btf(); 65 - task_dup = bpf_rdonly_cast(task, bpf_core_type_id_kernel(struct task_struct)); 68 + task_dup = bpf_core_cast(task, struct task_struct); 66 69 (void)bpf_task_storage_get(&enter_id, task_dup, 0, 0); 67 70 return 0; 68 71 } ··· 70 73 SEC("?tracepoint/syscalls/sys_enter_nanosleep") 71 74 int kctx_u64(void *ctx) 72 75 { 73 - u64 *kctx = bpf_rdonly_cast(ctx, bpf_core_type_id_kernel(u64)); 76 + u64 *kctx = bpf_core_cast(ctx, u64); 74 77 75 78 (void)kctx; 76 79 return 0;
+182
tools/testing/selftests/bpf/progs/verifier_global_ptr_args.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ 3 + 4 + #include <vmlinux.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + #include <bpf/bpf_core_read.h> 8 + #include "bpf_misc.h" 9 + #include "xdp_metadata.h" 10 + #include "bpf_kfuncs.h" 11 + 12 + extern struct task_struct *bpf_task_acquire(struct task_struct *p) __ksym __weak; 13 + extern void bpf_task_release(struct task_struct *p) __ksym __weak; 14 + 15 + __weak int subprog_trusted_task_nullable(struct task_struct *task __arg_trusted __arg_nullable) 16 + { 17 + if (!task) 18 + return 0; 19 + return task->pid + task->tgid; 20 + } 21 + 22 + __weak int subprog_trusted_task_nullable_extra_layer(struct task_struct *task __arg_trusted __arg_nullable) 23 + { 24 + return subprog_trusted_task_nullable(task) + subprog_trusted_task_nullable(NULL); 25 + } 26 + 27 + SEC("?tp_btf/task_newtask") 28 + __success __log_level(2) 29 + __msg("Validating subprog_trusted_task_nullable() func#1...") 30 + __msg(": R1=trusted_ptr_or_null_task_struct(") 31 + int trusted_task_arg_nullable(void *ctx) 32 + { 33 + struct task_struct *t1 = bpf_get_current_task_btf(); 34 + struct task_struct *t2 = bpf_task_acquire(t1); 35 + int res = 0; 36 + 37 + /* known NULL */ 38 + res += subprog_trusted_task_nullable(NULL); 39 + 40 + /* known non-NULL */ 41 + res += subprog_trusted_task_nullable(t1); 42 + res += subprog_trusted_task_nullable_extra_layer(t1); 43 + 44 + /* unknown if NULL or not */ 45 + res += subprog_trusted_task_nullable(t2); 46 + res += subprog_trusted_task_nullable_extra_layer(t2); 47 + 48 + if (t2) { 49 + /* known non-NULL after explicit NULL check, just in case */ 50 + res += subprog_trusted_task_nullable(t2); 51 + res += subprog_trusted_task_nullable_extra_layer(t2); 52 + 53 + bpf_task_release(t2); 54 + } 55 + 56 + return res; 57 + } 58 + 59 + __weak int subprog_trusted_task_nonnull(struct task_struct *task __arg_trusted) 60 + { 61 + return task->pid + task->tgid; 62 + } 63 + 64 + SEC("?kprobe") 65 + __failure __log_level(2) 66 + __msg("R1 type=scalar expected=ptr_, trusted_ptr_, rcu_ptr_") 67 + __msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')") 68 + int trusted_task_arg_nonnull_fail1(void *ctx) 69 + { 70 + return subprog_trusted_task_nonnull(NULL); 71 + } 72 + 73 + SEC("?tp_btf/task_newtask") 74 + __failure __log_level(2) 75 + __msg("R1 type=ptr_or_null_ expected=ptr_, trusted_ptr_, rcu_ptr_") 76 + __msg("Caller passes invalid args into func#1 ('subprog_trusted_task_nonnull')") 77 + int trusted_task_arg_nonnull_fail2(void *ctx) 78 + { 79 + struct task_struct *t = bpf_get_current_task_btf(); 80 + struct task_struct *nullable; 81 + int res; 82 + 83 + nullable = bpf_task_acquire(t); 84 + 85 + /* should fail, PTR_TO_BTF_ID_OR_NULL */ 86 + res = subprog_trusted_task_nonnull(nullable); 87 + 88 + if (nullable) 89 + bpf_task_release(nullable); 90 + 91 + return res; 92 + } 93 + 94 + SEC("?kprobe") 95 + __success __log_level(2) 96 + __msg("Validating subprog_trusted_task_nonnull() func#1...") 97 + __msg(": R1=trusted_ptr_task_struct(") 98 + int trusted_task_arg_nonnull(void *ctx) 99 + { 100 + struct task_struct *t = bpf_get_current_task_btf(); 101 + 102 + return subprog_trusted_task_nonnull(t); 103 + } 104 + 105 + struct task_struct___local {} __attribute__((preserve_access_index)); 106 + 107 + __weak int subprog_nullable_task_flavor( 108 + struct task_struct___local *task __arg_trusted __arg_nullable) 109 + { 110 + char buf[16]; 111 + 112 + if (!task) 113 + return 0; 114 + 115 + return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0); 116 + } 117 + 118 + SEC("?uprobe.s") 119 + __success __log_level(2) 120 + __msg("Validating subprog_nullable_task_flavor() func#1...") 121 + __msg(": R1=trusted_ptr_or_null_task_struct(") 122 + int flavor_ptr_nullable(void *ctx) 123 + { 124 + struct task_struct___local *t = (void *)bpf_get_current_task_btf(); 125 + 126 + return subprog_nullable_task_flavor(t); 127 + } 128 + 129 + __weak int subprog_nonnull_task_flavor(struct task_struct___local *task __arg_trusted) 130 + { 131 + char buf[16]; 132 + 133 + return bpf_copy_from_user_task(&buf, sizeof(buf), NULL, (void *)task, 0); 134 + } 135 + 136 + SEC("?uprobe.s") 137 + __success __log_level(2) 138 + __msg("Validating subprog_nonnull_task_flavor() func#1...") 139 + __msg(": R1=trusted_ptr_task_struct(") 140 + int flavor_ptr_nonnull(void *ctx) 141 + { 142 + struct task_struct *t = bpf_get_current_task_btf(); 143 + 144 + return subprog_nonnull_task_flavor((void *)t); 145 + } 146 + 147 + __weak int subprog_trusted_destroy(struct task_struct *task __arg_trusted) 148 + { 149 + bpf_task_release(task); /* should be rejected */ 150 + 151 + return 0; 152 + } 153 + 154 + SEC("?tp_btf/task_newtask") 155 + __failure __log_level(2) 156 + __msg("release kernel function bpf_task_release expects refcounted PTR_TO_BTF_ID") 157 + int BPF_PROG(trusted_destroy_fail, struct task_struct *task, u64 clone_flags) 158 + { 159 + return subprog_trusted_destroy(task); 160 + } 161 + 162 + __weak int subprog_trusted_acq_rel(struct task_struct *task __arg_trusted) 163 + { 164 + struct task_struct *owned; 165 + 166 + owned = bpf_task_acquire(task); 167 + if (!owned) 168 + return 0; 169 + 170 + bpf_task_release(owned); /* this one is OK, we acquired it locally */ 171 + 172 + return 0; 173 + } 174 + 175 + SEC("?tp_btf/task_newtask") 176 + __success __log_level(2) 177 + int BPF_PROG(trusted_acq_rel, struct task_struct *task, u64 clone_flags) 178 + { 179 + return subprog_trusted_acq_rel(task); 180 + } 181 + 182 + char _license[] SEC("license") = "GPL";
+29
tools/testing/selftests/bpf/progs/verifier_global_subprogs.c
··· 115 115 return subprog_nullable_ptr_bad(&x); 116 116 } 117 117 118 + typedef struct { 119 + int x; 120 + } user_struct_t; 121 + 122 + __noinline __weak int subprog_user_anon_mem(user_struct_t *t) 123 + { 124 + return t ? t->x : 0; 125 + } 126 + 127 + SEC("?tracepoint") 128 + __failure __log_level(2) 129 + __msg("invalid bpf_context access") 130 + __msg("Caller passes invalid args into func#1 ('subprog_user_anon_mem')") 131 + int anon_user_mem_invalid(void *ctx) 132 + { 133 + /* can't pass PTR_TO_CTX as user memory */ 134 + return subprog_user_anon_mem(ctx); 135 + } 136 + 137 + SEC("?tracepoint") 138 + __success __log_level(2) 139 + __msg("Func#1 ('subprog_user_anon_mem') is safe for any args that match its prototype") 140 + int anon_user_mem_valid(void *ctx) 141 + { 142 + user_struct_t t = { .x = 42 }; 143 + 144 + return subprog_user_anon_mem(&t); 145 + } 146 + 118 147 __noinline __weak int subprog_nonnull_ptr_good(int *p1 __arg_nonnull, int *p2 __arg_nonnull) 119 148 { 120 149 return (*p1) * (*p2); /* good, no need for NULL checks */
+314 -10
tools/testing/selftests/bpf/progs/verifier_spill_fill.c
··· 217 217 218 218 SEC("tc") 219 219 __description("Spill a u32 const scalar. Refill as u16. Offset to skb->data") 220 - __failure __msg("invalid access to packet") 220 + __success __retval(0) 221 221 __naked void u16_offset_to_skb_data(void) 222 222 { 223 223 asm volatile (" \ ··· 225 225 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 226 226 w4 = 20; \ 227 227 *(u32*)(r10 - 8) = r4; \ 228 - r4 = *(u16*)(r10 - 8); \ 228 + " 229 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 230 + "r4 = *(u16*)(r10 - 8);" 231 + #else 232 + "r4 = *(u16*)(r10 - 6);" 233 + #endif 234 + " \ 229 235 r0 = r2; \ 230 - /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=umax=65535 */\ 236 + /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=20 */\ 231 237 r0 += r4; \ 232 - /* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=umax=65535 */\ 238 + /* if (r0 > r3) R0=pkt,off=20 R2=pkt R3=pkt_end R4=20 */\ 233 239 if r0 > r3 goto l0_%=; \ 234 - /* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=20 */\ 240 + /* r0 = *(u32 *)r2 R0=pkt,off=20 R2=pkt R3=pkt_end R4=20 */\ 235 241 r0 = *(u32*)(r2 + 0); \ 236 242 l0_%=: r0 = 0; \ 237 243 exit; \ ··· 274 268 } 275 269 276 270 SEC("tc") 277 - __description("Spill a u32 const scalar. Refill as u16 from fp-6. Offset to skb->data") 271 + __description("Spill a u32 const scalar. Refill as u16 from MSB. Offset to skb->data") 278 272 __failure __msg("invalid access to packet") 279 273 __naked void _6_offset_to_skb_data(void) 280 274 { ··· 283 277 r3 = *(u32*)(r1 + %[__sk_buff_data_end]); \ 284 278 w4 = 20; \ 285 279 *(u32*)(r10 - 8) = r4; \ 286 - r4 = *(u16*)(r10 - 6); \ 280 + " 281 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 282 + "r4 = *(u16*)(r10 - 6);" 283 + #else 284 + "r4 = *(u16*)(r10 - 8);" 285 + #endif 286 + " \ 287 287 r0 = r2; \ 288 288 /* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=umax=65535 */\ 289 289 r0 += r4; \ ··· 464 452 SEC("raw_tp") 465 453 __log_level(2) 466 454 __success 467 - __msg("fp-8=0m??mmmm") 468 - __msg("fp-16=00mm??mm") 469 - __msg("fp-24=00mm???m") 455 + __msg("fp-8=0m??scalar()") 456 + __msg("fp-16=00mm??scalar()") 457 + __msg("fp-24=00mm???scalar()") 470 458 __naked void spill_subregs_preserve_stack_zero(void) 471 459 { 472 460 asm volatile ( ··· 949 937 exit; \ 950 938 " : 951 939 : __imm(bpf_get_prandom_u32) 940 + : __clobber_all); 941 + } 942 + 943 + SEC("xdp") 944 + __description("spill unbounded reg, then range check src") 945 + __success __retval(0) 946 + __naked void spill_unbounded(void) 947 + { 948 + asm volatile (" \ 949 + /* Produce an unbounded scalar. */ \ 950 + call %[bpf_get_prandom_u32]; \ 951 + /* Spill r0 to stack. */ \ 952 + *(u64*)(r10 - 8) = r0; \ 953 + /* Boundary check on r0. */ \ 954 + if r0 > 16 goto l0_%=; \ 955 + /* Fill r0 from stack. */ \ 956 + r0 = *(u64*)(r10 - 8); \ 957 + /* Boundary check on r0 with predetermined result. */\ 958 + if r0 <= 16 goto l0_%=; \ 959 + /* Dead branch: the verifier should prune it. Do an invalid memory\ 960 + * access if the verifier follows it. \ 961 + */ \ 962 + r0 = *(u64*)(r9 + 0); \ 963 + l0_%=: r0 = 0; \ 964 + exit; \ 965 + " : 966 + : __imm(bpf_get_prandom_u32) 967 + : __clobber_all); 968 + } 969 + 970 + SEC("xdp") 971 + __description("32-bit fill after 64-bit spill") 972 + __success __retval(0) 973 + __naked void fill_32bit_after_spill_64bit(void) 974 + { 975 + asm volatile(" \ 976 + /* Randomize the upper 32 bits. */ \ 977 + call %[bpf_get_prandom_u32]; \ 978 + r0 <<= 32; \ 979 + /* 64-bit spill r0 to stack. */ \ 980 + *(u64*)(r10 - 8) = r0; \ 981 + /* 32-bit fill r0 from stack. */ \ 982 + " 983 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 984 + "r0 = *(u32*)(r10 - 8);" 985 + #else 986 + "r0 = *(u32*)(r10 - 4);" 987 + #endif 988 + " \ 989 + /* Boundary check on r0 with predetermined result. */\ 990 + if r0 == 0 goto l0_%=; \ 991 + /* Dead branch: the verifier should prune it. Do an invalid memory\ 992 + * access if the verifier follows it. \ 993 + */ \ 994 + r0 = *(u64*)(r9 + 0); \ 995 + l0_%=: exit; \ 996 + " : 997 + : __imm(bpf_get_prandom_u32) 998 + : __clobber_all); 999 + } 1000 + 1001 + SEC("xdp") 1002 + __description("32-bit fill after 64-bit spill of 32-bit value should preserve ID") 1003 + __success __retval(0) 1004 + __naked void fill_32bit_after_spill_64bit_preserve_id(void) 1005 + { 1006 + asm volatile (" \ 1007 + /* Randomize the lower 32 bits. */ \ 1008 + call %[bpf_get_prandom_u32]; \ 1009 + w0 &= 0xffffffff; \ 1010 + /* 64-bit spill r0 to stack - should assign an ID. */\ 1011 + *(u64*)(r10 - 8) = r0; \ 1012 + /* 32-bit fill r1 from stack - should preserve the ID. */\ 1013 + " 1014 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 1015 + "r1 = *(u32*)(r10 - 8);" 1016 + #else 1017 + "r1 = *(u32*)(r10 - 4);" 1018 + #endif 1019 + " \ 1020 + /* Compare r1 with another register to trigger find_equal_scalars. */\ 1021 + r2 = 0; \ 1022 + if r1 != r2 goto l0_%=; \ 1023 + /* The result of this comparison is predefined. */\ 1024 + if r0 == r2 goto l0_%=; \ 1025 + /* Dead branch: the verifier should prune it. Do an invalid memory\ 1026 + * access if the verifier follows it. \ 1027 + */ \ 1028 + r0 = *(u64*)(r9 + 0); \ 1029 + exit; \ 1030 + l0_%=: r0 = 0; \ 1031 + exit; \ 1032 + " : 1033 + : __imm(bpf_get_prandom_u32) 1034 + : __clobber_all); 1035 + } 1036 + 1037 + SEC("xdp") 1038 + __description("32-bit fill after 64-bit spill should clear ID") 1039 + __failure __msg("math between ctx pointer and 4294967295 is not allowed") 1040 + __naked void fill_32bit_after_spill_64bit_clear_id(void) 1041 + { 1042 + asm volatile (" \ 1043 + r6 = r1; \ 1044 + /* Roll one bit to force the verifier to track both branches. */\ 1045 + call %[bpf_get_prandom_u32]; \ 1046 + r0 &= 0x8; \ 1047 + /* Put a large number into r1. */ \ 1048 + r1 = 0xffffffff; \ 1049 + r1 <<= 32; \ 1050 + r1 += r0; \ 1051 + /* 64-bit spill r1 to stack - should assign an ID. */\ 1052 + *(u64*)(r10 - 8) = r1; \ 1053 + /* 32-bit fill r2 from stack - should clear the ID. */\ 1054 + " 1055 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 1056 + "r2 = *(u32*)(r10 - 8);" 1057 + #else 1058 + "r2 = *(u32*)(r10 - 4);" 1059 + #endif 1060 + " \ 1061 + /* Compare r2 with another register to trigger find_equal_scalars.\ 1062 + * Having one random bit is important here, otherwise the verifier cuts\ 1063 + * the corners. If the ID was mistakenly preserved on fill, this would\ 1064 + * cause the verifier to think that r1 is also equal to zero in one of\ 1065 + * the branches, and equal to eight on the other branch.\ 1066 + */ \ 1067 + r3 = 0; \ 1068 + if r2 != r3 goto l0_%=; \ 1069 + l0_%=: r1 >>= 32; \ 1070 + /* The verifier shouldn't propagate r2's range to r1, so it should\ 1071 + * still remember r1 = 0xffffffff and reject the below.\ 1072 + */ \ 1073 + r6 += r1; \ 1074 + r0 = *(u32*)(r6 + 0); \ 1075 + exit; \ 1076 + " : 1077 + : __imm(bpf_get_prandom_u32) 1078 + : __clobber_all); 1079 + } 1080 + 1081 + /* stacksafe(): check if stack spill of an imprecise scalar in old state 1082 + * is considered equivalent to STACK_{MISC,INVALID} in cur state. 1083 + */ 1084 + SEC("socket") 1085 + __success __log_level(2) 1086 + __msg("8: (79) r1 = *(u64 *)(r10 -8)") 1087 + __msg("8: safe") 1088 + __msg("processed 11 insns") 1089 + /* STACK_INVALID should prevent verifier in unpriv mode from 1090 + * considering states equivalent and force an error on second 1091 + * verification path (entry - label 1 - label 2). 1092 + */ 1093 + __failure_unpriv 1094 + __msg_unpriv("8: (79) r1 = *(u64 *)(r10 -8)") 1095 + __msg_unpriv("9: (95) exit") 1096 + __msg_unpriv("8: (79) r1 = *(u64 *)(r10 -8)") 1097 + __msg_unpriv("invalid read from stack off -8+2 size 8") 1098 + __flag(BPF_F_TEST_STATE_FREQ) 1099 + __naked void old_imprecise_scalar_vs_cur_stack_misc(void) 1100 + { 1101 + asm volatile( 1102 + /* get a random value for branching */ 1103 + "call %[bpf_ktime_get_ns];" 1104 + "if r0 == 0 goto 1f;" 1105 + /* conjure scalar at fp-8 */ 1106 + "r0 = 42;" 1107 + "*(u64*)(r10 - 8) = r0;" 1108 + "goto 2f;" 1109 + "1:" 1110 + /* conjure STACK_{MISC,INVALID} at fp-8 */ 1111 + "call %[bpf_ktime_get_ns];" 1112 + "*(u16*)(r10 - 8) = r0;" 1113 + "*(u16*)(r10 - 4) = r0;" 1114 + "2:" 1115 + /* read fp-8, should be considered safe on second visit */ 1116 + "r1 = *(u64*)(r10 - 8);" 1117 + "exit;" 1118 + : 1119 + : __imm(bpf_ktime_get_ns) 1120 + : __clobber_all); 1121 + } 1122 + 1123 + /* stacksafe(): check that stack spill of a precise scalar in old state 1124 + * is not considered equivalent to STACK_MISC in cur state. 1125 + */ 1126 + SEC("socket") 1127 + __success __log_level(2) 1128 + /* verifier should visit 'if r1 == 0x2a ...' two times: 1129 + * - once for path entry - label 2; 1130 + * - once for path entry - label 1 - label 2. 1131 + */ 1132 + __msg("if r1 == 0x2a goto pc+0") 1133 + __msg("if r1 == 0x2a goto pc+0") 1134 + __msg("processed 15 insns") 1135 + __flag(BPF_F_TEST_STATE_FREQ) 1136 + __naked void old_precise_scalar_vs_cur_stack_misc(void) 1137 + { 1138 + asm volatile( 1139 + /* get a random value for branching */ 1140 + "call %[bpf_ktime_get_ns];" 1141 + "if r0 == 0 goto 1f;" 1142 + /* conjure scalar at fp-8 */ 1143 + "r0 = 42;" 1144 + "*(u64*)(r10 - 8) = r0;" 1145 + "goto 2f;" 1146 + "1:" 1147 + /* conjure STACK_MISC at fp-8 */ 1148 + "call %[bpf_ktime_get_ns];" 1149 + "*(u64*)(r10 - 8) = r0;" 1150 + "*(u32*)(r10 - 4) = r0;" 1151 + "2:" 1152 + /* read fp-8, should not be considered safe on second visit */ 1153 + "r1 = *(u64*)(r10 - 8);" 1154 + /* use r1 in precise context */ 1155 + "if r1 == 42 goto +0;" 1156 + "exit;" 1157 + : 1158 + : __imm(bpf_ktime_get_ns) 1159 + : __clobber_all); 1160 + } 1161 + 1162 + /* stacksafe(): check if STACK_MISC in old state is considered 1163 + * equivalent to stack spill of a scalar in cur state. 1164 + */ 1165 + SEC("socket") 1166 + __success __log_level(2) 1167 + __msg("8: (79) r0 = *(u64 *)(r10 -8)") 1168 + __msg("8: safe") 1169 + __msg("processed 11 insns") 1170 + __flag(BPF_F_TEST_STATE_FREQ) 1171 + __naked void old_stack_misc_vs_cur_scalar(void) 1172 + { 1173 + asm volatile( 1174 + /* get a random value for branching */ 1175 + "call %[bpf_ktime_get_ns];" 1176 + "if r0 == 0 goto 1f;" 1177 + /* conjure STACK_{MISC,INVALID} at fp-8 */ 1178 + "call %[bpf_ktime_get_ns];" 1179 + "*(u16*)(r10 - 8) = r0;" 1180 + "*(u16*)(r10 - 4) = r0;" 1181 + "goto 2f;" 1182 + "1:" 1183 + /* conjure scalar at fp-8 */ 1184 + "r0 = 42;" 1185 + "*(u64*)(r10 - 8) = r0;" 1186 + "2:" 1187 + /* read fp-8, should be considered safe on second visit */ 1188 + "r0 = *(u64*)(r10 - 8);" 1189 + "exit;" 1190 + : 1191 + : __imm(bpf_ktime_get_ns) 1192 + : __clobber_all); 1193 + } 1194 + 1195 + /* stacksafe(): check that STACK_MISC in old state is not considered 1196 + * equivalent to stack spill of a non-scalar in cur state. 1197 + */ 1198 + SEC("socket") 1199 + __success __log_level(2) 1200 + /* verifier should process exit instructions twice: 1201 + * - once for path entry - label 2; 1202 + * - once for path entry - label 1 - label 2. 1203 + */ 1204 + __msg("r1 = *(u64 *)(r10 -8)") 1205 + __msg("exit") 1206 + __msg("r1 = *(u64 *)(r10 -8)") 1207 + __msg("exit") 1208 + __msg("processed 11 insns") 1209 + __flag(BPF_F_TEST_STATE_FREQ) 1210 + __naked void old_stack_misc_vs_cur_ctx_ptr(void) 1211 + { 1212 + asm volatile( 1213 + /* remember context pointer in r9 */ 1214 + "r9 = r1;" 1215 + /* get a random value for branching */ 1216 + "call %[bpf_ktime_get_ns];" 1217 + "if r0 == 0 goto 1f;" 1218 + /* conjure STACK_MISC at fp-8 */ 1219 + "call %[bpf_ktime_get_ns];" 1220 + "*(u64*)(r10 - 8) = r0;" 1221 + "*(u32*)(r10 - 4) = r0;" 1222 + "goto 2f;" 1223 + "1:" 1224 + /* conjure context pointer in fp-8 */ 1225 + "*(u64*)(r10 - 8) = r9;" 1226 + "2:" 1227 + /* read fp-8, should not be considered safe on second visit */ 1228 + "r1 = *(u64*)(r10 - 8);" 1229 + "exit;" 1230 + : 1231 + : __imm(bpf_ktime_get_ns) 952 1232 : __clobber_all); 953 1233 } 954 1234
+1 -1
tools/testing/selftests/bpf/progs/verifier_spin_lock.c
··· 330 330 331 331 SEC("cgroup/skb") 332 332 __description("spin_lock: test10 lock in subprog without unlock") 333 - __failure __msg("unlock is missing") 333 + __success 334 334 __failure_unpriv __msg_unpriv("") 335 335 __naked void lock_in_subprog_without_unlock(void) 336 336 {
+4 -2
tools/testing/selftests/bpf/progs/xdp_synproxy_kern.c
··· 7 7 #include <bpf/bpf_endian.h> 8 8 #include <asm/errno.h> 9 9 10 + #include "bpf_compiler.h" 11 + 10 12 #define TC_ACT_OK 0 11 13 #define TC_ACT_SHOT 2 12 14 ··· 153 151 __u64 sum = csum; 154 152 int i; 155 153 156 - #pragma unroll 154 + __pragma_loop_unroll 157 155 for (i = 0; i < 4; i++) 158 156 sum += (__u32)saddr->in6_u.u6_addr32[i]; 159 157 160 - #pragma unroll 158 + __pragma_loop_unroll 161 159 for (i = 0; i < 4; i++) 162 160 sum += (__u32)daddr->in6_u.u6_addr32[i]; 163 161
+2 -1
tools/testing/selftests/bpf/progs/xdping_kern.c
··· 15 15 #include <bpf/bpf_helpers.h> 16 16 #include <bpf/bpf_endian.h> 17 17 18 + #include "bpf_compiler.h" 18 19 #include "xdping.h" 19 20 20 21 struct { ··· 117 116 return XDP_PASS; 118 117 119 118 if (pinginfo->start) { 120 - #pragma clang loop unroll(full) 119 + __pragma_loop_unroll_full 121 120 for (i = 0; i < XDPING_MAX_COUNT; i++) { 122 121 if (pinginfo->times[i] == 0) 123 122 break;
+9 -9
tools/testing/selftests/bpf/test_lpm_map.c
··· 211 211 volatile size_t n_matches, n_matches_after_delete; 212 212 size_t i, j, n_nodes, n_lookups; 213 213 struct tlpm_node *t, *list = NULL; 214 - struct bpf_lpm_trie_key *key; 214 + struct bpf_lpm_trie_key_u8 *key; 215 215 uint8_t *data, *value; 216 216 int r, map; 217 217 ··· 331 331 static void test_lpm_ipaddr(void) 332 332 { 333 333 LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_NO_PREALLOC); 334 - struct bpf_lpm_trie_key *key_ipv4; 335 - struct bpf_lpm_trie_key *key_ipv6; 334 + struct bpf_lpm_trie_key_u8 *key_ipv4; 335 + struct bpf_lpm_trie_key_u8 *key_ipv6; 336 336 size_t key_size_ipv4; 337 337 size_t key_size_ipv6; 338 338 int map_fd_ipv4; ··· 423 423 static void test_lpm_delete(void) 424 424 { 425 425 LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_NO_PREALLOC); 426 - struct bpf_lpm_trie_key *key; 426 + struct bpf_lpm_trie_key_u8 *key; 427 427 size_t key_size; 428 428 int map_fd; 429 429 __u64 value; ··· 532 532 static void test_lpm_get_next_key(void) 533 533 { 534 534 LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_NO_PREALLOC); 535 - struct bpf_lpm_trie_key *key_p, *next_key_p; 535 + struct bpf_lpm_trie_key_u8 *key_p, *next_key_p; 536 536 size_t key_size; 537 537 __u32 value = 0; 538 538 int map_fd; ··· 693 693 { 694 694 int i, j, ret, iter, key_size; 695 695 struct lpm_mt_test_info *info = arg; 696 - struct bpf_lpm_trie_key *key_p; 696 + struct bpf_lpm_trie_key_u8 *key_p; 697 697 698 - key_size = sizeof(struct bpf_lpm_trie_key) + sizeof(__u32); 698 + key_size = sizeof(*key_p) + sizeof(__u32); 699 699 key_p = alloca(key_size); 700 700 for (iter = 0; iter < info->iter; iter++) 701 701 for (i = 0; i < MAX_TEST_KEYS; i++) { ··· 717 717 ret = bpf_map_lookup_elem(info->map_fd, key_p, &value); 718 718 assert(ret == 0 || errno == ENOENT); 719 719 } else { 720 - struct bpf_lpm_trie_key *next_key_p = alloca(key_size); 720 + struct bpf_lpm_trie_key_u8 *next_key_p = alloca(key_size); 721 721 ret = bpf_map_get_next_key(info->map_fd, key_p, next_key_p); 722 722 assert(ret == 0 || errno == ENOENT || errno == ENOMEM); 723 723 } ··· 752 752 753 753 /* create a trie */ 754 754 value_size = sizeof(__u32); 755 - key_size = sizeof(struct bpf_lpm_trie_key) + value_size; 755 + key_size = sizeof(struct bpf_lpm_trie_key_hdr) + value_size; 756 756 map_fd = bpf_map_create(BPF_MAP_TYPE_LPM_TRIE, NULL, key_size, value_size, 100, &opts); 757 757 758 758 /* create 4 threads to test update, delete, lookup and get_next_key */
+6 -1
tools/testing/selftests/bpf/test_progs.h
··· 385 385 goto goto_label; \ 386 386 }) 387 387 388 + #define ALL_TO_DEV_NULL " >/dev/null 2>&1" 389 + 388 390 #define SYS_NOFAIL(fmt, ...) \ 389 391 ({ \ 390 392 char cmd[1024]; \ 391 - snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ 393 + int n; \ 394 + n = snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \ 395 + if (n < sizeof(cmd) && sizeof(cmd) - n >= sizeof(ALL_TO_DEV_NULL)) \ 396 + strcat(cmd, ALL_TO_DEV_NULL); \ 392 397 system(cmd); \ 393 398 }) 394 399
+2 -2
tools/testing/selftests/bpf/testing_helpers.c
··· 356 356 return sample_freq; 357 357 } 358 358 359 - static int finit_module(int fd, const char *param_values, int flags) 359 + int finit_module(int fd, const char *param_values, int flags) 360 360 { 361 361 return syscall(__NR_finit_module, fd, param_values, flags); 362 362 } 363 363 364 - static int delete_module(const char *name, int flags) 364 + int delete_module(const char *name, int flags) 365 365 { 366 366 return syscall(__NR_delete_module, name, flags); 367 367 }
+2
tools/testing/selftests/bpf/testing_helpers.h
··· 36 36 int load_bpf_testmod(bool verbose); 37 37 int unload_bpf_testmod(bool verbose); 38 38 int kern_sync_rcu(void); 39 + int finit_module(int fd, const char *param_values, int flags); 40 + int delete_module(const char *name, int flags); 39 41 40 42 static inline __u64 get_time_ns(void) 41 43 {
+1 -1
tools/testing/selftests/bpf/trace_helpers.c
··· 271 271 * addi r2,r2,XXXX 272 272 */ 273 273 { 274 - const u32 *insn = (const u32 *)(uintptr_t)addr; 274 + const __u32 *insn = (const __u32 *)(uintptr_t)addr; 275 275 276 276 if ((((*insn & OP_RT_RA_MASK) == ADDIS_R2_R12) || 277 277 ((*insn & OP_RT_RA_MASK) == LIS_R2)) &&