18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <errno.h> 38c2ecf20Sopenharmony_ci#include <stdio.h> 48c2ecf20Sopenharmony_ci#include <stdlib.h> 58c2ecf20Sopenharmony_ci#include <sys/epoll.h> 68c2ecf20Sopenharmony_ci#include <sys/types.h> 78c2ecf20Sopenharmony_ci#include <sys/stat.h> 88c2ecf20Sopenharmony_ci#include <fcntl.h> 98c2ecf20Sopenharmony_ci#include <util/record.h> 108c2ecf20Sopenharmony_ci#include <util/util.h> 118c2ecf20Sopenharmony_ci#include <util/bpf-loader.h> 128c2ecf20Sopenharmony_ci#include <util/evlist.h> 138c2ecf20Sopenharmony_ci#include <linux/bpf.h> 148c2ecf20Sopenharmony_ci#include <linux/filter.h> 158c2ecf20Sopenharmony_ci#include <linux/kernel.h> 168c2ecf20Sopenharmony_ci#include <linux/string.h> 178c2ecf20Sopenharmony_ci#include <api/fs/fs.h> 188c2ecf20Sopenharmony_ci#include <bpf/bpf.h> 198c2ecf20Sopenharmony_ci#include <perf/mmap.h> 208c2ecf20Sopenharmony_ci#include "tests.h" 218c2ecf20Sopenharmony_ci#include "llvm.h" 228c2ecf20Sopenharmony_ci#include "debug.h" 238c2ecf20Sopenharmony_ci#include "parse-events.h" 248c2ecf20Sopenharmony_ci#include "util/mmap.h" 258c2ecf20Sopenharmony_ci#define NR_ITERS 111 268c2ecf20Sopenharmony_ci#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test" 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#ifdef HAVE_LIBBPF_SUPPORT 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic int epoll_pwait_loop(void) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci int i; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci /* Should fail NR_ITERS times */ 358c2ecf20Sopenharmony_ci for (i = 0; i < NR_ITERS; i++) 368c2ecf20Sopenharmony_ci epoll_pwait(-(i + 1), NULL, 0, 0, NULL); 378c2ecf20Sopenharmony_ci return 0; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#ifdef HAVE_BPF_PROLOGUE 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic int llseek_loop(void) 438c2ecf20Sopenharmony_ci{ 448c2ecf20Sopenharmony_ci int fds[2], i; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci fds[0] = open("/dev/null", O_RDONLY); 478c2ecf20Sopenharmony_ci fds[1] = open("/dev/null", O_RDWR); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (fds[0] < 0 || fds[1] < 0) 508c2ecf20Sopenharmony_ci return -1; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci for (i = 0; i < NR_ITERS; i++) { 538c2ecf20Sopenharmony_ci lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET); 548c2ecf20Sopenharmony_ci lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET); 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci close(fds[0]); 578c2ecf20Sopenharmony_ci close(fds[1]); 588c2ecf20Sopenharmony_ci return 0; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic struct { 648c2ecf20Sopenharmony_ci enum test_llvm__testcase prog_id; 658c2ecf20Sopenharmony_ci const char *desc; 668c2ecf20Sopenharmony_ci const char *name; 678c2ecf20Sopenharmony_ci const char *msg_compile_fail; 688c2ecf20Sopenharmony_ci const char *msg_load_fail; 698c2ecf20Sopenharmony_ci int (*target_func)(void); 708c2ecf20Sopenharmony_ci int expect_result; 718c2ecf20Sopenharmony_ci bool pin; 728c2ecf20Sopenharmony_ci} bpf_testcase_table[] = { 738c2ecf20Sopenharmony_ci { 748c2ecf20Sopenharmony_ci .prog_id = LLVM_TESTCASE_BASE, 758c2ecf20Sopenharmony_ci .desc = "Basic BPF filtering", 768c2ecf20Sopenharmony_ci .name = "[basic_bpf_test]", 778c2ecf20Sopenharmony_ci .msg_compile_fail = "fix 'perf test LLVM' first", 788c2ecf20Sopenharmony_ci .msg_load_fail = "load bpf object failed", 798c2ecf20Sopenharmony_ci .target_func = &epoll_pwait_loop, 808c2ecf20Sopenharmony_ci .expect_result = (NR_ITERS + 1) / 2, 818c2ecf20Sopenharmony_ci }, 828c2ecf20Sopenharmony_ci { 838c2ecf20Sopenharmony_ci .prog_id = LLVM_TESTCASE_BASE, 848c2ecf20Sopenharmony_ci .desc = "BPF pinning", 858c2ecf20Sopenharmony_ci .name = "[bpf_pinning]", 868c2ecf20Sopenharmony_ci .msg_compile_fail = "fix kbuild first", 878c2ecf20Sopenharmony_ci .msg_load_fail = "check your vmlinux setting?", 888c2ecf20Sopenharmony_ci .target_func = &epoll_pwait_loop, 898c2ecf20Sopenharmony_ci .expect_result = (NR_ITERS + 1) / 2, 908c2ecf20Sopenharmony_ci .pin = true, 918c2ecf20Sopenharmony_ci }, 928c2ecf20Sopenharmony_ci#ifdef HAVE_BPF_PROLOGUE 938c2ecf20Sopenharmony_ci { 948c2ecf20Sopenharmony_ci .prog_id = LLVM_TESTCASE_BPF_PROLOGUE, 958c2ecf20Sopenharmony_ci .desc = "BPF prologue generation", 968c2ecf20Sopenharmony_ci .name = "[bpf_prologue_test]", 978c2ecf20Sopenharmony_ci .msg_compile_fail = "fix kbuild first", 988c2ecf20Sopenharmony_ci .msg_load_fail = "check your vmlinux setting?", 998c2ecf20Sopenharmony_ci .target_func = &llseek_loop, 1008c2ecf20Sopenharmony_ci .expect_result = (NR_ITERS + 1) / 4, 1018c2ecf20Sopenharmony_ci }, 1028c2ecf20Sopenharmony_ci#endif 1038c2ecf20Sopenharmony_ci { 1048c2ecf20Sopenharmony_ci .prog_id = LLVM_TESTCASE_BPF_RELOCATION, 1058c2ecf20Sopenharmony_ci .desc = "BPF relocation checker", 1068c2ecf20Sopenharmony_ci .name = "[bpf_relocation_test]", 1078c2ecf20Sopenharmony_ci .msg_compile_fail = "fix 'perf test LLVM' first", 1088c2ecf20Sopenharmony_ci .msg_load_fail = "libbpf error when dealing with relocation", 1098c2ecf20Sopenharmony_ci }, 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_cistatic int do_test(struct bpf_object *obj, int (*func)(void), 1138c2ecf20Sopenharmony_ci int expect) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci struct record_opts opts = { 1168c2ecf20Sopenharmony_ci .target = { 1178c2ecf20Sopenharmony_ci .uid = UINT_MAX, 1188c2ecf20Sopenharmony_ci .uses_mmap = true, 1198c2ecf20Sopenharmony_ci }, 1208c2ecf20Sopenharmony_ci .freq = 0, 1218c2ecf20Sopenharmony_ci .mmap_pages = 256, 1228c2ecf20Sopenharmony_ci .default_interval = 1, 1238c2ecf20Sopenharmony_ci }; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci char pid[16]; 1268c2ecf20Sopenharmony_ci char sbuf[STRERR_BUFSIZE]; 1278c2ecf20Sopenharmony_ci struct evlist *evlist; 1288c2ecf20Sopenharmony_ci int i, ret = TEST_FAIL, err = 0, count = 0; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci struct parse_events_state parse_state; 1318c2ecf20Sopenharmony_ci struct parse_events_error parse_error; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci bzero(&parse_error, sizeof(parse_error)); 1348c2ecf20Sopenharmony_ci bzero(&parse_state, sizeof(parse_state)); 1358c2ecf20Sopenharmony_ci parse_state.error = &parse_error; 1368c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&parse_state.list); 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL); 1398c2ecf20Sopenharmony_ci if (err || list_empty(&parse_state.list)) { 1408c2ecf20Sopenharmony_ci pr_debug("Failed to add events selected by BPF\n"); 1418c2ecf20Sopenharmony_ci return TEST_FAIL; 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci snprintf(pid, sizeof(pid), "%d", getpid()); 1458c2ecf20Sopenharmony_ci pid[sizeof(pid) - 1] = '\0'; 1468c2ecf20Sopenharmony_ci opts.target.tid = opts.target.pid = pid; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci /* Instead of perf_evlist__new_default, don't add default events */ 1498c2ecf20Sopenharmony_ci evlist = evlist__new(); 1508c2ecf20Sopenharmony_ci if (!evlist) { 1518c2ecf20Sopenharmony_ci pr_debug("Not enough memory to create evlist\n"); 1528c2ecf20Sopenharmony_ci return TEST_FAIL; 1538c2ecf20Sopenharmony_ci } 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci err = perf_evlist__create_maps(evlist, &opts.target); 1568c2ecf20Sopenharmony_ci if (err < 0) { 1578c2ecf20Sopenharmony_ci pr_debug("Not enough memory to create thread/cpu maps\n"); 1588c2ecf20Sopenharmony_ci goto out_delete_evlist; 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci perf_evlist__splice_list_tail(evlist, &parse_state.list); 1628c2ecf20Sopenharmony_ci evlist->nr_groups = parse_state.nr_groups; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci perf_evlist__config(evlist, &opts, NULL); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci err = evlist__open(evlist); 1678c2ecf20Sopenharmony_ci if (err < 0) { 1688c2ecf20Sopenharmony_ci pr_debug("perf_evlist__open: %s\n", 1698c2ecf20Sopenharmony_ci str_error_r(errno, sbuf, sizeof(sbuf))); 1708c2ecf20Sopenharmony_ci goto out_delete_evlist; 1718c2ecf20Sopenharmony_ci } 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci err = evlist__mmap(evlist, opts.mmap_pages); 1748c2ecf20Sopenharmony_ci if (err < 0) { 1758c2ecf20Sopenharmony_ci pr_debug("evlist__mmap: %s\n", 1768c2ecf20Sopenharmony_ci str_error_r(errno, sbuf, sizeof(sbuf))); 1778c2ecf20Sopenharmony_ci goto out_delete_evlist; 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci evlist__enable(evlist); 1818c2ecf20Sopenharmony_ci (*func)(); 1828c2ecf20Sopenharmony_ci evlist__disable(evlist); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci for (i = 0; i < evlist->core.nr_mmaps; i++) { 1858c2ecf20Sopenharmony_ci union perf_event *event; 1868c2ecf20Sopenharmony_ci struct mmap *md; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci md = &evlist->mmap[i]; 1898c2ecf20Sopenharmony_ci if (perf_mmap__read_init(&md->core) < 0) 1908c2ecf20Sopenharmony_ci continue; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci while ((event = perf_mmap__read_event(&md->core)) != NULL) { 1938c2ecf20Sopenharmony_ci const u32 type = event->header.type; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci if (type == PERF_RECORD_SAMPLE) 1968c2ecf20Sopenharmony_ci count ++; 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci perf_mmap__read_done(&md->core); 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci if (count != expect * evlist->core.nr_entries) { 2028c2ecf20Sopenharmony_ci pr_debug("BPF filter result incorrect, expected %d, got %d samples\n", expect * evlist->core.nr_entries, count); 2038c2ecf20Sopenharmony_ci goto out_delete_evlist; 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci ret = TEST_OK; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ciout_delete_evlist: 2098c2ecf20Sopenharmony_ci evlist__delete(evlist); 2108c2ecf20Sopenharmony_ci return ret; 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic struct bpf_object * 2148c2ecf20Sopenharmony_ciprepare_bpf(void *obj_buf, size_t obj_buf_sz, const char *name) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci struct bpf_object *obj; 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci obj = bpf__prepare_load_buffer(obj_buf, obj_buf_sz, name); 2198c2ecf20Sopenharmony_ci if (IS_ERR(obj)) { 2208c2ecf20Sopenharmony_ci pr_debug("Compile BPF program failed.\n"); 2218c2ecf20Sopenharmony_ci return NULL; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci return obj; 2248c2ecf20Sopenharmony_ci} 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_cistatic int __test__bpf(int idx) 2278c2ecf20Sopenharmony_ci{ 2288c2ecf20Sopenharmony_ci int ret; 2298c2ecf20Sopenharmony_ci void *obj_buf; 2308c2ecf20Sopenharmony_ci size_t obj_buf_sz; 2318c2ecf20Sopenharmony_ci struct bpf_object *obj; 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz, 2348c2ecf20Sopenharmony_ci bpf_testcase_table[idx].prog_id, 2358c2ecf20Sopenharmony_ci true, NULL); 2368c2ecf20Sopenharmony_ci if (ret != TEST_OK || !obj_buf || !obj_buf_sz) { 2378c2ecf20Sopenharmony_ci pr_debug("Unable to get BPF object, %s\n", 2388c2ecf20Sopenharmony_ci bpf_testcase_table[idx].msg_compile_fail); 2398c2ecf20Sopenharmony_ci if (idx == 0) 2408c2ecf20Sopenharmony_ci return TEST_SKIP; 2418c2ecf20Sopenharmony_ci else 2428c2ecf20Sopenharmony_ci return TEST_FAIL; 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci obj = prepare_bpf(obj_buf, obj_buf_sz, 2468c2ecf20Sopenharmony_ci bpf_testcase_table[idx].name); 2478c2ecf20Sopenharmony_ci if ((!!bpf_testcase_table[idx].target_func) != (!!obj)) { 2488c2ecf20Sopenharmony_ci if (!obj) 2498c2ecf20Sopenharmony_ci pr_debug("Fail to load BPF object: %s\n", 2508c2ecf20Sopenharmony_ci bpf_testcase_table[idx].msg_load_fail); 2518c2ecf20Sopenharmony_ci else 2528c2ecf20Sopenharmony_ci pr_debug("Success unexpectedly: %s\n", 2538c2ecf20Sopenharmony_ci bpf_testcase_table[idx].msg_load_fail); 2548c2ecf20Sopenharmony_ci ret = TEST_FAIL; 2558c2ecf20Sopenharmony_ci goto out; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if (obj) { 2598c2ecf20Sopenharmony_ci ret = do_test(obj, 2608c2ecf20Sopenharmony_ci bpf_testcase_table[idx].target_func, 2618c2ecf20Sopenharmony_ci bpf_testcase_table[idx].expect_result); 2628c2ecf20Sopenharmony_ci if (ret != TEST_OK) 2638c2ecf20Sopenharmony_ci goto out; 2648c2ecf20Sopenharmony_ci if (bpf_testcase_table[idx].pin) { 2658c2ecf20Sopenharmony_ci int err; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci if (!bpf_fs__mount()) { 2688c2ecf20Sopenharmony_ci pr_debug("BPF filesystem not mounted\n"); 2698c2ecf20Sopenharmony_ci ret = TEST_FAIL; 2708c2ecf20Sopenharmony_ci goto out; 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci err = mkdir(PERF_TEST_BPF_PATH, 0777); 2738c2ecf20Sopenharmony_ci if (err && errno != EEXIST) { 2748c2ecf20Sopenharmony_ci pr_debug("Failed to make perf_test dir: %s\n", 2758c2ecf20Sopenharmony_ci strerror(errno)); 2768c2ecf20Sopenharmony_ci ret = TEST_FAIL; 2778c2ecf20Sopenharmony_ci goto out; 2788c2ecf20Sopenharmony_ci } 2798c2ecf20Sopenharmony_ci if (bpf_object__pin(obj, PERF_TEST_BPF_PATH)) 2808c2ecf20Sopenharmony_ci ret = TEST_FAIL; 2818c2ecf20Sopenharmony_ci if (rm_rf(PERF_TEST_BPF_PATH)) 2828c2ecf20Sopenharmony_ci ret = TEST_FAIL; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ciout: 2878c2ecf20Sopenharmony_ci free(obj_buf); 2888c2ecf20Sopenharmony_ci bpf__clear(); 2898c2ecf20Sopenharmony_ci return ret; 2908c2ecf20Sopenharmony_ci} 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ciint test__bpf_subtest_get_nr(void) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci return (int)ARRAY_SIZE(bpf_testcase_table); 2958c2ecf20Sopenharmony_ci} 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ciconst char *test__bpf_subtest_get_desc(int i) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table)) 3008c2ecf20Sopenharmony_ci return NULL; 3018c2ecf20Sopenharmony_ci return bpf_testcase_table[i].desc; 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic int check_env(void) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci int err; 3078c2ecf20Sopenharmony_ci unsigned int kver_int; 3088c2ecf20Sopenharmony_ci char license[] = "GPL"; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci struct bpf_insn insns[] = { 3118c2ecf20Sopenharmony_ci BPF_MOV64_IMM(BPF_REG_0, 1), 3128c2ecf20Sopenharmony_ci BPF_EXIT_INSN(), 3138c2ecf20Sopenharmony_ci }; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci err = fetch_kernel_version(&kver_int, NULL, 0); 3168c2ecf20Sopenharmony_ci if (err) { 3178c2ecf20Sopenharmony_ci pr_debug("Unable to get kernel version\n"); 3188c2ecf20Sopenharmony_ci return err; 3198c2ecf20Sopenharmony_ci } 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci err = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns, 3228c2ecf20Sopenharmony_ci sizeof(insns) / sizeof(insns[0]), 3238c2ecf20Sopenharmony_ci license, kver_int, NULL, 0); 3248c2ecf20Sopenharmony_ci if (err < 0) { 3258c2ecf20Sopenharmony_ci pr_err("Missing basic BPF support, skip this test: %s\n", 3268c2ecf20Sopenharmony_ci strerror(errno)); 3278c2ecf20Sopenharmony_ci return err; 3288c2ecf20Sopenharmony_ci } 3298c2ecf20Sopenharmony_ci close(err); 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci return 0; 3328c2ecf20Sopenharmony_ci} 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ciint test__bpf(struct test *test __maybe_unused, int i) 3358c2ecf20Sopenharmony_ci{ 3368c2ecf20Sopenharmony_ci int err; 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci if (i < 0 || i >= (int)ARRAY_SIZE(bpf_testcase_table)) 3398c2ecf20Sopenharmony_ci return TEST_FAIL; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci if (geteuid() != 0) { 3428c2ecf20Sopenharmony_ci pr_debug("Only root can run BPF test\n"); 3438c2ecf20Sopenharmony_ci return TEST_SKIP; 3448c2ecf20Sopenharmony_ci } 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci if (check_env()) 3478c2ecf20Sopenharmony_ci return TEST_SKIP; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci err = __test__bpf(i); 3508c2ecf20Sopenharmony_ci return err; 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci#else 3548c2ecf20Sopenharmony_ciint test__bpf_subtest_get_nr(void) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci return 0; 3578c2ecf20Sopenharmony_ci} 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_ciconst char *test__bpf_subtest_get_desc(int i __maybe_unused) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci return NULL; 3628c2ecf20Sopenharmony_ci} 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ciint test__bpf(struct test *test __maybe_unused, int i __maybe_unused) 3658c2ecf20Sopenharmony_ci{ 3668c2ecf20Sopenharmony_ci pr_debug("Skip BPF test because BPF support is not compiled\n"); 3678c2ecf20Sopenharmony_ci return TEST_SKIP; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci#endif 370