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

selftests/bpf: allow BTF specs and func infos in test_verifier tests

The BTF and func_info specification for test_verifier tests follows
the same notation as in prog_tests/btf.c tests. E.g.:

...
.func_info = { { 0, 6 }, { 8, 7 } },
.func_info_cnt = 2,
.btf_strings = "\0int\0",
.btf_types = {
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4),
BTF_PTR_ENC(1),
},
...

The BTF specification is loaded only when specified.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
Link: https://lore.kernel.org/r/20220620235344.569325-3-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Eduard Zingerman and committed by
Alexei Starovoitov
7a42008c 933ff531

+79 -18
-1
tools/testing/selftests/bpf/prog_tests/btf.c
··· 34 34 #undef CHECK 35 35 #define CHECK(condition, format...) _CHECK(condition, "check", duration, format) 36 36 37 - #define BTF_END_RAW 0xdeadbeef 38 37 #define NAME_TBD 0xdeadb33f 39 38 40 39 #define NAME_NTH(N) (0xfffe0000 | N)
+2
tools/testing/selftests/bpf/test_btf.h
··· 4 4 #ifndef _TEST_BTF_H 5 5 #define _TEST_BTF_H 6 6 7 + #define BTF_END_RAW 0xdeadbeef 8 + 7 9 #define BTF_INFO_ENC(kind, kind_flag, vlen) \ 8 10 ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN)) 9 11
+77 -17
tools/testing/selftests/bpf/test_verifier.c
··· 59 59 #define MAX_TEST_RUNS 8 60 60 #define POINTER_VALUE 0xcafe4all 61 61 #define TEST_DATA_LEN 64 62 + #define MAX_FUNC_INFOS 8 63 + #define MAX_BTF_STRINGS 256 64 + #define MAX_BTF_TYPES 256 62 65 63 66 #define INSN_OFF_MASK ((__s16)0xFFFF) 64 67 #define INSN_IMM_MASK ((__s32)0xFFFFFFFF) 65 68 #define SKIP_INSNS() BPF_RAW_INSN(0xde, 0xa, 0xd, 0xbeef, 0xdeadbeef) 69 + 70 + #define DEFAULT_LIBBPF_LOG_LEVEL 4 71 + #define VERBOSE_LIBBPF_LOG_LEVEL 1 66 72 67 73 #define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0) 68 74 #define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1) ··· 164 158 }; 165 159 enum bpf_attach_type expected_attach_type; 166 160 const char *kfunc; 161 + struct bpf_func_info func_info[MAX_FUNC_INFOS]; 162 + int func_info_cnt; 163 + char btf_strings[MAX_BTF_STRINGS]; 164 + /* A set of BTF types to load when specified, 165 + * use macro definitions from test_btf.h, 166 + * must end with BTF_END_RAW 167 + */ 168 + __u32 btf_types[MAX_BTF_TYPES]; 167 169 }; 168 170 169 171 /* Note we want this to be 64 bit aligned so that the end of our array is ··· 701 687 BTF_MEMBER_ENC(71, 13, 128), /* struct prog_test_member __kptr_ref *ptr; */ 702 688 }; 703 689 704 - static int load_btf(void) 690 + static char bpf_vlog[UINT_MAX >> 8]; 691 + 692 + static int load_btf_spec(__u32 *types, int types_len, 693 + const char *strings, int strings_len) 705 694 { 706 695 struct btf_header hdr = { 707 696 .magic = BTF_MAGIC, 708 697 .version = BTF_VERSION, 709 698 .hdr_len = sizeof(struct btf_header), 710 - .type_len = sizeof(btf_raw_types), 711 - .str_off = sizeof(btf_raw_types), 712 - .str_len = sizeof(btf_str_sec), 699 + .type_len = types_len, 700 + .str_off = types_len, 701 + .str_len = strings_len, 713 702 }; 714 703 void *ptr, *raw_btf; 715 704 int btf_fd; 705 + LIBBPF_OPTS(bpf_btf_load_opts, opts, 706 + .log_buf = bpf_vlog, 707 + .log_size = sizeof(bpf_vlog), 708 + .log_level = (verbose 709 + ? VERBOSE_LIBBPF_LOG_LEVEL 710 + : DEFAULT_LIBBPF_LOG_LEVEL), 711 + ); 716 712 717 - ptr = raw_btf = malloc(sizeof(hdr) + sizeof(btf_raw_types) + 718 - sizeof(btf_str_sec)); 713 + raw_btf = malloc(sizeof(hdr) + types_len + strings_len); 719 714 715 + ptr = raw_btf; 720 716 memcpy(ptr, &hdr, sizeof(hdr)); 721 717 ptr += sizeof(hdr); 722 - memcpy(ptr, btf_raw_types, hdr.type_len); 718 + memcpy(ptr, types, hdr.type_len); 723 719 ptr += hdr.type_len; 724 - memcpy(ptr, btf_str_sec, hdr.str_len); 720 + memcpy(ptr, strings, hdr.str_len); 725 721 ptr += hdr.str_len; 726 722 727 - btf_fd = bpf_btf_load(raw_btf, ptr - raw_btf, NULL); 728 - free(raw_btf); 723 + btf_fd = bpf_btf_load(raw_btf, ptr - raw_btf, &opts); 729 724 if (btf_fd < 0) 730 - return -1; 731 - return btf_fd; 725 + printf("Failed to load BTF spec: '%s'\n", strerror(errno)); 726 + 727 + free(raw_btf); 728 + 729 + return btf_fd < 0 ? -1 : btf_fd; 730 + } 731 + 732 + static int load_btf(void) 733 + { 734 + return load_btf_spec(btf_raw_types, sizeof(btf_raw_types), 735 + btf_str_sec, sizeof(btf_str_sec)); 736 + } 737 + 738 + static int load_btf_for_test(struct bpf_test *test) 739 + { 740 + int types_num = 0; 741 + 742 + while (types_num < MAX_BTF_TYPES && 743 + test->btf_types[types_num] != BTF_END_RAW) 744 + ++types_num; 745 + 746 + int types_len = types_num * sizeof(test->btf_types[0]); 747 + 748 + return load_btf_spec(test->btf_types, types_len, 749 + test->btf_strings, sizeof(test->btf_strings)); 732 750 } 733 751 734 752 static int create_map_spin_lock(void) ··· 838 792 printf("Failed to create map with btf_id pointer\n"); 839 793 return fd; 840 794 } 841 - 842 - static char bpf_vlog[UINT_MAX >> 8]; 843 795 844 796 static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type, 845 797 struct bpf_insn *prog, int *map_fds) ··· 1404 1360 static void do_test_single(struct bpf_test *test, bool unpriv, 1405 1361 int *passes, int *errors) 1406 1362 { 1407 - int fd_prog, expected_ret, alignment_prevented_execution; 1363 + int fd_prog, btf_fd, expected_ret, alignment_prevented_execution; 1408 1364 int prog_len, prog_type = test->prog_type; 1409 1365 struct bpf_insn *prog = test->insns; 1410 1366 LIBBPF_OPTS(bpf_prog_load_opts, opts); ··· 1416 1372 __u32 pflags; 1417 1373 int i, err; 1418 1374 1375 + fd_prog = -1; 1419 1376 for (i = 0; i < MAX_NR_MAPS; i++) 1420 1377 map_fds[i] = -1; 1378 + btf_fd = -1; 1421 1379 1422 1380 if (!prog_type) 1423 1381 prog_type = BPF_PROG_TYPE_SOCKET_FILTER; ··· 1452 1406 1453 1407 opts.expected_attach_type = test->expected_attach_type; 1454 1408 if (verbose) 1455 - opts.log_level = 1; 1409 + opts.log_level = VERBOSE_LIBBPF_LOG_LEVEL; 1456 1410 else if (expected_ret == VERBOSE_ACCEPT) 1457 1411 opts.log_level = 2; 1458 1412 else 1459 - opts.log_level = 4; 1413 + opts.log_level = DEFAULT_LIBBPF_LOG_LEVEL; 1460 1414 opts.prog_flags = pflags; 1461 1415 1462 1416 if (prog_type == BPF_PROG_TYPE_TRACING && test->kfunc) { ··· 1472 1426 } 1473 1427 1474 1428 opts.attach_btf_id = attach_btf_id; 1429 + } 1430 + 1431 + if (test->btf_types[0] != 0) { 1432 + btf_fd = load_btf_for_test(test); 1433 + if (btf_fd < 0) 1434 + goto fail_log; 1435 + opts.prog_btf_fd = btf_fd; 1436 + } 1437 + 1438 + if (test->func_info_cnt != 0) { 1439 + opts.func_info = test->func_info; 1440 + opts.func_info_cnt = test->func_info_cnt; 1441 + opts.func_info_rec_size = sizeof(test->func_info[0]); 1475 1442 } 1476 1443 1477 1444 opts.log_buf = bpf_vlog; ··· 1598 1539 if (test->fill_insns) 1599 1540 free(test->fill_insns); 1600 1541 close(fd_prog); 1542 + close(btf_fd); 1601 1543 for (i = 0; i < MAX_NR_MAPS; i++) 1602 1544 close(map_fds[i]); 1603 1545 sched_yield();