^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <sys/epoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <util/record.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <util/util.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <util/bpf-loader.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <util/evlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/filter.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <api/fs/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <bpf/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <perf/mmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "tests.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "llvm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "util/mmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define NR_ITERS 111
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #ifdef HAVE_LIBBPF_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static int epoll_pwait_loop(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Should fail NR_ITERS times */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) for (i = 0; i < NR_ITERS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) epoll_pwait(-(i + 1), NULL, 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #ifdef HAVE_BPF_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int llseek_loop(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int fds[2], i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) fds[0] = open("/dev/null", O_RDONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) fds[1] = open("/dev/null", O_RDWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (fds[0] < 0 || fds[1] < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) for (i = 0; i < NR_ITERS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) close(fds[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) close(fds[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) enum test_llvm__testcase prog_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) const char *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const char *msg_compile_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const char *msg_load_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int (*target_func)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int expect_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) bool pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) } bpf_testcase_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .prog_id = LLVM_TESTCASE_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .desc = "Basic BPF filtering",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .name = "[basic_bpf_test]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .msg_compile_fail = "fix 'perf test LLVM' first",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .msg_load_fail = "load bpf object failed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .target_func = &epoll_pwait_loop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) .expect_result = (NR_ITERS + 1) / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .prog_id = LLVM_TESTCASE_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .desc = "BPF pinning",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .name = "[bpf_pinning]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .msg_compile_fail = "fix kbuild first",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .msg_load_fail = "check your vmlinux setting?",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .target_func = &epoll_pwait_loop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .expect_result = (NR_ITERS + 1) / 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .pin = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #ifdef HAVE_BPF_PROLOGUE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .prog_id = LLVM_TESTCASE_BPF_PROLOGUE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .desc = "BPF prologue generation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .name = "[bpf_prologue_test]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .msg_compile_fail = "fix kbuild first",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .msg_load_fail = "check your vmlinux setting?",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .target_func = &llseek_loop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .expect_result = (NR_ITERS + 1) / 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .prog_id = LLVM_TESTCASE_BPF_RELOCATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .desc = "BPF relocation checker",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .name = "[bpf_relocation_test]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) .msg_compile_fail = "fix 'perf test LLVM' first",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) .msg_load_fail = "libbpf error when dealing with relocation",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int do_test(struct bpf_object *obj, int (*func)(void),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int expect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct record_opts opts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) .target = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) .uid = UINT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .uses_mmap = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .freq = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .mmap_pages = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .default_interval = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) char pid[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) char sbuf[STRERR_BUFSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct evlist *evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int i, ret = TEST_FAIL, err = 0, count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct parse_events_state parse_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct parse_events_error parse_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bzero(&parse_error, sizeof(parse_error));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bzero(&parse_state, sizeof(parse_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) parse_state.error = &parse_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) INIT_LIST_HEAD(&parse_state.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (err || list_empty(&parse_state.list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) pr_debug("Failed to add events selected by BPF\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) snprintf(pid, sizeof(pid), "%d", getpid());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) pid[sizeof(pid) - 1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) opts.target.tid = opts.target.pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* Instead of perf_evlist__new_default, don't add default events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) evlist = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (!evlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) pr_debug("Not enough memory to create evlist\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) err = perf_evlist__create_maps(evlist, &opts.target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) pr_debug("Not enough memory to create thread/cpu maps\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) goto out_delete_evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) perf_evlist__splice_list_tail(evlist, &parse_state.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) evlist->nr_groups = parse_state.nr_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) perf_evlist__config(evlist, &opts, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) err = evlist__open(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pr_debug("perf_evlist__open: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) goto out_delete_evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) err = evlist__mmap(evlist, opts.mmap_pages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) pr_debug("evlist__mmap: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) str_error_r(errno, sbuf, sizeof(sbuf)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) goto out_delete_evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) evlist__enable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) (*func)();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) evlist__disable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) for (i = 0; i < evlist->core.nr_mmaps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) union perf_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct mmap *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) md = &evlist->mmap[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (perf_mmap__read_init(&md->core) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) while ((event = perf_mmap__read_event(&md->core)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) const u32 type = event->header.type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (type == PERF_RECORD_SAMPLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) count ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) perf_mmap__read_done(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (count != expect * evlist->core.nr_entries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) pr_debug("BPF filter result incorrect, expected %d, got %d samples\n", expect * evlist->core.nr_entries, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) goto out_delete_evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = TEST_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) out_delete_evlist:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static struct bpf_object *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) prepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct bpf_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (IS_ERR(obj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pr_debug("Compile BPF program failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int __test__bpf(int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) void *obj_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) size_t obj_buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct bpf_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) bpf_testcase_table[idx].prog_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) true, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pr_debug("Unable to get BPF object, %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bpf_testcase_table[idx].msg_compile_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (idx == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return TEST_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) obj = prepare_bpf(obj_buf, obj_buf_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) bpf_testcase_table[idx].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if ((!!bpf_testcase_table[idx].target_func) != (!!obj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pr_debug("Fail to load BPF object: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) bpf_testcase_table[idx].msg_load_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pr_debug("Success unexpectedly: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) bpf_testcase_table[idx].msg_load_fail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = do_test(obj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) bpf_testcase_table[idx].target_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) bpf_testcase_table[idx].expect_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (ret != TEST_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (bpf_testcase_table[idx].pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!bpf_fs__mount()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) pr_debug("BPF filesystem not mounted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) err = mkdir(PERF_TEST_BPF_PATH, 0777);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (err && errno != EEXIST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pr_debug("Failed to make perf_test dir: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ret = TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (bpf_object__pin(obj, PERF_TEST_BPF_PATH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (rm_rf(PERF_TEST_BPF_PATH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ret = TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) free(obj_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) bpf__clear();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) int test__bpf_subtest_get_nr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return (int)ARRAY_SIZE(bpf_testcase_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const char *test__bpf_subtest_get_desc(int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return bpf_testcase_table[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static int check_env(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) unsigned int kver_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) char license[] = "GPL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct bpf_insn insns[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) BPF_MOV64_IMM(BPF_REG_0, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) BPF_EXIT_INSN(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) err = fetch_kernel_version(&kver_int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pr_debug("Unable to get kernel version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) err = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) sizeof(insns) / sizeof(insns[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) license, kver_int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pr_err("Missing basic BPF support, skip this test: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) strerror(errno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) close(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int test__bpf(struct test *test __maybe_unused, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return TEST_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (geteuid() != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) pr_debug("Only root can run BPF test\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return TEST_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (check_env())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return TEST_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) err = __test__bpf(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int test__bpf_subtest_get_nr(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) const char *test__bpf_subtest_get_desc(int i __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int test__bpf(struct test *test __maybe_unused, int i __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) pr_debug("Skip BPF test because BPF support is not compiled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return TEST_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) #endif