Add tests for libbpf relocation of static variable references into the .data and .bss sections of the ELF.
Signed-off-by: Joe Stringer <j...@wand.net.nz> --- 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