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

selftests/bpf: validate generic bpf_object and subskel APIs work together

Add a new subtest validating that bpf_object loaded and initialized
through generic APIs is still interoperable with BPF subskeleton,
including initialization and reading of global variables.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/r/20241023043908.3834423-4-andrii@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrii Nakryiko and committed by
Alexei Starovoitov
80a54566 137978f4

+75 -1
+75 -1
tools/testing/selftests/bpf/prog_tests/subskeleton.c
··· 46 46 return result; 47 47 } 48 48 49 - void test_subskeleton(void) 49 + /* initialize and load through skeleton, then instantiate subskeleton out of it */ 50 + static void subtest_skel_subskeleton(void) 50 51 { 51 52 int err, result; 52 53 struct test_subskeleton *skel; ··· 76 75 77 76 cleanup: 78 77 test_subskeleton__destroy(skel); 78 + } 79 + 80 + /* initialize and load through generic bpf_object API, then instantiate subskeleton out of it */ 81 + static void subtest_obj_subskeleton(void) 82 + { 83 + int err, result; 84 + const void *elf_bytes; 85 + size_t elf_bytes_sz = 0, rodata_sz = 0, bss_sz = 0; 86 + struct bpf_object *obj; 87 + const struct bpf_map *map; 88 + const struct bpf_program *prog; 89 + struct bpf_link *link = NULL; 90 + struct test_subskeleton__rodata *rodata; 91 + struct test_subskeleton__bss *bss; 92 + 93 + elf_bytes = test_subskeleton__elf_bytes(&elf_bytes_sz); 94 + if (!ASSERT_OK_PTR(elf_bytes, "elf_bytes")) 95 + return; 96 + 97 + obj = bpf_object__open_mem(elf_bytes, elf_bytes_sz, NULL); 98 + if (!ASSERT_OK_PTR(obj, "obj_open_mem")) 99 + return; 100 + 101 + map = bpf_object__find_map_by_name(obj, ".rodata"); 102 + if (!ASSERT_OK_PTR(map, "rodata_map_by_name")) 103 + goto cleanup; 104 + 105 + rodata = bpf_map__initial_value(map, &rodata_sz); 106 + if (!ASSERT_OK_PTR(rodata, "rodata_get")) 107 + goto cleanup; 108 + 109 + rodata->rovar1 = 10; 110 + rodata->var1 = 1; 111 + subskeleton_lib_setup(obj); 112 + 113 + err = bpf_object__load(obj); 114 + if (!ASSERT_OK(err, "obj_load")) 115 + goto cleanup; 116 + 117 + prog = bpf_object__find_program_by_name(obj, "handler1"); 118 + if (!ASSERT_OK_PTR(prog, "prog_by_name")) 119 + goto cleanup; 120 + 121 + link = bpf_program__attach(prog); 122 + if (!ASSERT_OK_PTR(link, "prog_attach")) 123 + goto cleanup; 124 + 125 + /* trigger tracepoint */ 126 + usleep(1); 127 + 128 + map = bpf_object__find_map_by_name(obj, ".bss"); 129 + if (!ASSERT_OK_PTR(map, "bss_map_by_name")) 130 + goto cleanup; 131 + 132 + bss = bpf_map__initial_value(map, &bss_sz); 133 + if (!ASSERT_OK_PTR(rodata, "rodata_get")) 134 + goto cleanup; 135 + 136 + result = subskeleton_lib_subresult(obj) * 10; 137 + ASSERT_EQ(bss->out1, result, "out1"); 138 + 139 + cleanup: 140 + bpf_link__destroy(link); 141 + bpf_object__close(obj); 142 + } 143 + 144 + 145 + void test_subskeleton(void) 146 + { 147 + if (test__start_subtest("skel_subskel")) 148 + subtest_skel_subskeleton(); 149 + if (test__start_subtest("obj_subskel")) 150 + subtest_obj_subskeleton(); 79 151 }