Skip to content

Commit 7a42008

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
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 <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 933ff53 commit 7a42008

File tree

3 files changed

+79
-18
lines changed

3 files changed

+79
-18
lines changed

tools/testing/selftests/bpf/prog_tests/btf.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ static bool always_log;
3434
#undef CHECK
3535
#define CHECK(condition, format...) _CHECK(condition, "check", duration, format)
3636

37-
#define BTF_END_RAW 0xdeadbeef
3837
#define NAME_TBD 0xdeadb33f
3938

4039
#define NAME_NTH(N) (0xfffe0000 | N)

tools/testing/selftests/bpf/test_btf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#ifndef _TEST_BTF_H
55
#define _TEST_BTF_H
66

7+
#define BTF_END_RAW 0xdeadbeef
8+
79
#define BTF_INFO_ENC(kind, kind_flag, vlen) \
810
((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
911

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,17 @@
5959
#define MAX_TEST_RUNS 8
6060
#define POINTER_VALUE 0xcafe4all
6161
#define TEST_DATA_LEN 64
62+
#define MAX_FUNC_INFOS 8
63+
#define MAX_BTF_STRINGS 256
64+
#define MAX_BTF_TYPES 256
6265

6366
#define INSN_OFF_MASK ((__s16)0xFFFF)
6467
#define INSN_IMM_MASK ((__s32)0xFFFFFFFF)
6568
#define SKIP_INSNS() BPF_RAW_INSN(0xde, 0xa, 0xd, 0xbeef, 0xdeadbeef)
6669

70+
#define DEFAULT_LIBBPF_LOG_LEVEL 4
71+
#define VERBOSE_LIBBPF_LOG_LEVEL 1
72+
6773
#define F_NEEDS_EFFICIENT_UNALIGNED_ACCESS (1 << 0)
6874
#define F_LOAD_WITH_STRICT_ALIGNMENT (1 << 1)
6975

@@ -158,6 +164,14 @@ struct bpf_test {
158164
};
159165
enum bpf_attach_type expected_attach_type;
160166
const char *kfunc;
167+
struct bpf_func_info func_info[MAX_FUNC_INFOS];
168+
int func_info_cnt;
169+
char btf_strings[MAX_BTF_STRINGS];
170+
/* A set of BTF types to load when specified,
171+
* use macro definitions from test_btf.h,
172+
* must end with BTF_END_RAW
173+
*/
174+
__u32 btf_types[MAX_BTF_TYPES];
161175
};
162176

163177
/* Note we want this to be 64 bit aligned so that the end of our array is
@@ -687,34 +701,66 @@ static __u32 btf_raw_types[] = {
687701
BTF_MEMBER_ENC(71, 13, 128), /* struct prog_test_member __kptr_ref *ptr; */
688702
};
689703

690-
static int load_btf(void)
704+
static char bpf_vlog[UINT_MAX >> 8];
705+
706+
static int load_btf_spec(__u32 *types, int types_len,
707+
const char *strings, int strings_len)
691708
{
692709
struct btf_header hdr = {
693710
.magic = BTF_MAGIC,
694711
.version = BTF_VERSION,
695712
.hdr_len = sizeof(struct btf_header),
696-
.type_len = sizeof(btf_raw_types),
697-
.str_off = sizeof(btf_raw_types),
698-
.str_len = sizeof(btf_str_sec),
713+
.type_len = types_len,
714+
.str_off = types_len,
715+
.str_len = strings_len,
699716
};
700717
void *ptr, *raw_btf;
701718
int btf_fd;
719+
LIBBPF_OPTS(bpf_btf_load_opts, opts,
720+
.log_buf = bpf_vlog,
721+
.log_size = sizeof(bpf_vlog),
722+
.log_level = (verbose
723+
? VERBOSE_LIBBPF_LOG_LEVEL
724+
: DEFAULT_LIBBPF_LOG_LEVEL),
725+
);
702726

703-
ptr = raw_btf = malloc(sizeof(hdr) + sizeof(btf_raw_types) +
704-
sizeof(btf_str_sec));
727+
raw_btf = malloc(sizeof(hdr) + types_len + strings_len);
705728

729+
ptr = raw_btf;
706730
memcpy(ptr, &hdr, sizeof(hdr));
707731
ptr += sizeof(hdr);
708-
memcpy(ptr, btf_raw_types, hdr.type_len);
732+
memcpy(ptr, types, hdr.type_len);
709733
ptr += hdr.type_len;
710-
memcpy(ptr, btf_str_sec, hdr.str_len);
734+
memcpy(ptr, strings, hdr.str_len);
711735
ptr += hdr.str_len;
712736

713-
btf_fd = bpf_btf_load(raw_btf, ptr - raw_btf, NULL);
714-
free(raw_btf);
737+
btf_fd = bpf_btf_load(raw_btf, ptr - raw_btf, &opts);
715738
if (btf_fd < 0)
716-
return -1;
717-
return btf_fd;
739+
printf("Failed to load BTF spec: '%s'\n", strerror(errno));
740+
741+
free(raw_btf);
742+
743+
return btf_fd < 0 ? -1 : btf_fd;
744+
}
745+
746+
static int load_btf(void)
747+
{
748+
return load_btf_spec(btf_raw_types, sizeof(btf_raw_types),
749+
btf_str_sec, sizeof(btf_str_sec));
750+
}
751+
752+
static int load_btf_for_test(struct bpf_test *test)
753+
{
754+
int types_num = 0;
755+
756+
while (types_num < MAX_BTF_TYPES &&
757+
test->btf_types[types_num] != BTF_END_RAW)
758+
++types_num;
759+
760+
int types_len = types_num * sizeof(test->btf_types[0]);
761+
762+
return load_btf_spec(test->btf_types, types_len,
763+
test->btf_strings, sizeof(test->btf_strings));
718764
}
719765

720766
static int create_map_spin_lock(void)
@@ -793,8 +839,6 @@ static int create_map_kptr(void)
793839
return fd;
794840
}
795841

796-
static char bpf_vlog[UINT_MAX >> 8];
797-
798842
static void do_test_fixup(struct bpf_test *test, enum bpf_prog_type prog_type,
799843
struct bpf_insn *prog, int *map_fds)
800844
{
@@ -1360,7 +1404,7 @@ static bool check_xlated_program(struct bpf_test *test, int fd_prog)
13601404
static void do_test_single(struct bpf_test *test, bool unpriv,
13611405
int *passes, int *errors)
13621406
{
1363-
int fd_prog, expected_ret, alignment_prevented_execution;
1407+
int fd_prog, btf_fd, expected_ret, alignment_prevented_execution;
13641408
int prog_len, prog_type = test->prog_type;
13651409
struct bpf_insn *prog = test->insns;
13661410
LIBBPF_OPTS(bpf_prog_load_opts, opts);
@@ -1372,8 +1416,10 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
13721416
__u32 pflags;
13731417
int i, err;
13741418

1419+
fd_prog = -1;
13751420
for (i = 0; i < MAX_NR_MAPS; i++)
13761421
map_fds[i] = -1;
1422+
btf_fd = -1;
13771423

13781424
if (!prog_type)
13791425
prog_type = BPF_PROG_TYPE_SOCKET_FILTER;
@@ -1406,11 +1452,11 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
14061452

14071453
opts.expected_attach_type = test->expected_attach_type;
14081454
if (verbose)
1409-
opts.log_level = 1;
1455+
opts.log_level = VERBOSE_LIBBPF_LOG_LEVEL;
14101456
else if (expected_ret == VERBOSE_ACCEPT)
14111457
opts.log_level = 2;
14121458
else
1413-
opts.log_level = 4;
1459+
opts.log_level = DEFAULT_LIBBPF_LOG_LEVEL;
14141460
opts.prog_flags = pflags;
14151461

14161462
if (prog_type == BPF_PROG_TYPE_TRACING && test->kfunc) {
@@ -1428,6 +1474,19 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
14281474
opts.attach_btf_id = attach_btf_id;
14291475
}
14301476

1477+
if (test->btf_types[0] != 0) {
1478+
btf_fd = load_btf_for_test(test);
1479+
if (btf_fd < 0)
1480+
goto fail_log;
1481+
opts.prog_btf_fd = btf_fd;
1482+
}
1483+
1484+
if (test->func_info_cnt != 0) {
1485+
opts.func_info = test->func_info;
1486+
opts.func_info_cnt = test->func_info_cnt;
1487+
opts.func_info_rec_size = sizeof(test->func_info[0]);
1488+
}
1489+
14311490
opts.log_buf = bpf_vlog;
14321491
opts.log_size = sizeof(bpf_vlog);
14331492
fd_prog = bpf_prog_load(prog_type, NULL, "GPL", prog, prog_len, &opts);
@@ -1539,6 +1598,7 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
15391598
if (test->fill_insns)
15401599
free(test->fill_insns);
15411600
close(fd_prog);
1601+
close(btf_fd);
15421602
for (i = 0; i < MAX_NR_MAPS; i++)
15431603
close(map_fds[i]);
15441604
sched_yield();

0 commit comments

Comments
 (0)