[PATCH bpf-next 4/4] selftests/bpf: Test static data relocation
From: Joe Stringer <hidden>
Date: 2019-02-12 00:47:48
Subsystem:
bpf [general] (safe dynamic programs and tools), bpf [selftests] (test runners & infrastructure), kernel selftest framework, the rest · Maintainers:
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Shuah Khan, Linus Torvalds
Add tests for libbpf relocation of static variable references into the .data and .bss sections of the ELF. Signed-off-by: Joe Stringer <redacted> --- tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/test_progs.c | 44 +++++++++++++++++ .../selftests/bpf/test_static_data_kern.c | 47 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/test_static_data_kern.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index c7e1e3255448..ef52a58e2368 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile@@ -36,7 +36,7 @@ BPF_OBJ_FILES = \ get_cgroup_id_kern.o socket_cookie_prog.o test_select_reuseport_kern.o \ test_skb_cgroup_id_kern.o bpf_flow.o netcnt_prog.o test_xdp_vlan.o \ xdp_dummy.o test_map_in_map.o test_spin_lock.o test_map_lock.o \ - test_sock_fields_kern.o + test_sock_fields_kern.o test_static_data_kern.o # Objects are built with default compilation flags and with sub-register # code-gen enabled.
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c
index c52bd90fbb34..72899d58a77c 100644
--- a/tools/testing/selftests/bpf/test_progs.c
+++ b/tools/testing/selftests/bpf/test_progs.c@@ -736,6 +736,49 @@ static void test_pkt_md_access(void) bpf_object__close(obj); } +static void test_static_data_access(void) +{ + const char *file = "./test_static_data_kern.o"; + struct bpf_object *obj; + __u32 duration = 0, retval; + int i, err, prog_fd, map_fd; + uint32_t value; + + err = bpf_prog_load(file, BPF_PROG_TYPE_SCHED_CLS, &obj, &prog_fd); + if (CHECK(err, "load program", "error %d loading %s\n", err, file)) + return; + + map_fd = bpf_find_map(__func__, obj, "result"); + if (map_fd < 0) { + error_cnt++; + goto close_prog; + } + + err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), + NULL, NULL, &retval, &duration); + CHECK(err || retval, "pass packet", + "err %d errno %d retval %d duration %d\n", + err, errno, retval, duration); + + struct { + char *name; + uint32_t key; + uint32_t value; + } tests[] = { + { "relocate .bss reference", 0, 0 }, + { "relocate .data reference", 1, 42 }, + }; + for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { + err = bpf_map_lookup_elem(map_fd, &tests[i].key, &value); + CHECK (err || value != tests[i].value, tests[i].name, + "err %d result %d expected %d\n", + err, value, tests[i].value); + } + +close_prog: + bpf_object__close(obj); +} + static void test_obj_name(void) { struct {
@@ -2138,6 +2181,7 @@ int main(void) test_flow_dissector(); test_spinlock(); test_map_lock(); + test_static_data_access(); printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); return error_cnt ? EXIT_FAILURE : EXIT_SUCCESS;
diff --git a/tools/testing/selftests/bpf/test_static_data_kern.c b/tools/testing/selftests/bpf/test_static_data_kern.c
new file mode 100644
index 000000000000..f2485af6bd0b
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_static_data_kern.c@@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2019 Isovalent, Inc. + +#include <linux/bpf.h> +#include <linux/pkt_cls.h> + +#include <string.h> + +#include "bpf_helpers.h" + +#define NUM_CGROUP_LEVELS 4 + +struct bpf_map_def SEC("maps") result = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(__u32), + .value_size = sizeof(__u32), + .max_entries = 2, +}; + +#define __fetch(x) (__u32)(&(x)) + +static __u32 static_bss = 0; /* Reloc reference to .bss section */ +static __u32 static_data = 42; /* Reloc reference to .data section */ + +/** + * Load a u32 value from a static variable into a map, for the userland test + * program to validate. + */ +SEC("static_data_load") +int load_static_data(struct __sk_buff *skb) +{ + __u32 key, value; + + key = 0; + value = __fetch(static_bss); + bpf_map_update_elem(&result, &key, &value, 0); + + key = 1; + value = __fetch(static_data); + bpf_map_update_elem(&result, &key, &value, 0); + + return TC_ACT_OK; +} + +int _version SEC("version") = 1; + +char _license[] SEC("license") = "GPL";
--
2.19.1