]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: validate generic bpf_object and subskel APIs work together
authorAndrii Nakryiko <andrii@kernel.org>
Wed, 23 Oct 2024 04:39:08 +0000 (21:39 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Thu, 24 Oct 2024 05:15:09 +0000 (22:15 -0700)
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>
tools/testing/selftests/bpf/prog_tests/subskeleton.c

index 9c31b7004f9cf570c8fc3d485f3499de27da2fea..fdf13ed0152a7ef33d081fcfbaa996895d28add3 100644 (file)
@@ -46,7 +46,8 @@ static int subskeleton_lib_subresult(struct bpf_object *obj)
        return result;
 }
 
-void test_subskeleton(void)
+/* initialize and load through skeleton, then instantiate subskeleton out of it */
+static void subtest_skel_subskeleton(void)
 {
        int err, result;
        struct test_subskeleton *skel;
@@ -76,3 +77,76 @@ void test_subskeleton(void)
 cleanup:
        test_subskeleton__destroy(skel);
 }
+
+/* initialize and load through generic bpf_object API, then instantiate subskeleton out of it */
+static void subtest_obj_subskeleton(void)
+{
+       int err, result;
+       const void *elf_bytes;
+       size_t elf_bytes_sz = 0, rodata_sz = 0, bss_sz = 0;
+       struct bpf_object *obj;
+       const struct bpf_map *map;
+       const struct bpf_program *prog;
+       struct bpf_link *link = NULL;
+       struct test_subskeleton__rodata *rodata;
+       struct test_subskeleton__bss *bss;
+
+       elf_bytes = test_subskeleton__elf_bytes(&elf_bytes_sz);
+       if (!ASSERT_OK_PTR(elf_bytes, "elf_bytes"))
+               return;
+
+       obj = bpf_object__open_mem(elf_bytes, elf_bytes_sz, NULL);
+       if (!ASSERT_OK_PTR(obj, "obj_open_mem"))
+               return;
+
+       map = bpf_object__find_map_by_name(obj, ".rodata");
+       if (!ASSERT_OK_PTR(map, "rodata_map_by_name"))
+               goto cleanup;
+
+       rodata = bpf_map__initial_value(map, &rodata_sz);
+       if (!ASSERT_OK_PTR(rodata, "rodata_get"))
+               goto cleanup;
+
+       rodata->rovar1 = 10;
+       rodata->var1 = 1;
+       subskeleton_lib_setup(obj);
+
+       err = bpf_object__load(obj);
+       if (!ASSERT_OK(err, "obj_load"))
+               goto cleanup;
+
+       prog = bpf_object__find_program_by_name(obj, "handler1");
+       if (!ASSERT_OK_PTR(prog, "prog_by_name"))
+               goto cleanup;
+
+       link = bpf_program__attach(prog);
+       if (!ASSERT_OK_PTR(link, "prog_attach"))
+               goto cleanup;
+
+       /* trigger tracepoint */
+       usleep(1);
+
+       map = bpf_object__find_map_by_name(obj, ".bss");
+       if (!ASSERT_OK_PTR(map, "bss_map_by_name"))
+               goto cleanup;
+
+       bss = bpf_map__initial_value(map, &bss_sz);
+       if (!ASSERT_OK_PTR(rodata, "rodata_get"))
+               goto cleanup;
+
+       result = subskeleton_lib_subresult(obj) * 10;
+       ASSERT_EQ(bss->out1, result, "out1");
+
+cleanup:
+       bpf_link__destroy(link);
+       bpf_object__close(obj);
+}
+
+
+void test_subskeleton(void)
+{
+       if (test__start_subtest("skel_subskel"))
+               subtest_skel_subskeleton();
+       if (test__start_subtest("obj_subskel"))
+               subtest_obj_subskeleton();
+}