diff options
27 files changed, 3 insertions, 4381 deletions
diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 1478068ad5dd..0b4e79dbd3f6 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -125,9 +125,6 @@ Given a $HOME/.perfconfig like this: group = true skip-empty = true - [llvm] - dump-obj = true - clang-opt = -g You can hide source code of annotate feature setting the config to false with @@ -657,36 +654,6 @@ ftrace.*:: -F option is not specified. Possible values are 'function' and 'function_graph'. -llvm.*:: - llvm.clang-path:: - Path to clang. If omit, search it from $PATH. - - llvm.clang-bpf-cmd-template:: - Cmdline template. Below lines show its default value. Environment - variable is used to pass options. - "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ - "-DLINUX_VERSION_CODE=$LINUX_VERSION_CODE " \ - "$CLANG_OPTIONS $PERF_BPF_INC_OPTIONS $KERNEL_INC_OPTIONS " \ - "-Wno-unused-value -Wno-pointer-sign " \ - "-working-directory $WORKING_DIR " \ - "-c \"$CLANG_SOURCE\" --target=bpf $CLANG_EMIT_LLVM -O2 -o - $LLVM_OPTIONS_PIPE" - - llvm.clang-opt:: - Options passed to clang. - - llvm.kbuild-dir:: - kbuild directory. If not set, use /lib/modules/`uname -r`/build. - If set to "" deliberately, skip kernel header auto-detector. - - llvm.kbuild-opts:: - Options passed to 'make' when detecting kernel header options. - - llvm.dump-obj:: - Enable perf dump BPF object files compiled by LLVM. - - llvm.opts:: - Options passed to llc. - samples.*:: samples.context:: diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 680396c56bd1..7d362407fb39 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -99,20 +99,6 @@ OPTIONS If you want to profile write accesses in [0x1000~1008), just set 'mem:0x1000/8:w'. - - a BPF source file (ending in .c) or a precompiled object file (ending - in .o) selects one or more BPF events. - The BPF program can attach to various perf events based on the ELF section - names. - - When processing a '.c' file, perf searches an installed LLVM to compile it - into an object file first. Optional clang options can be passed via the - '--clang-opt' command line option, e.g.: - - perf record --clang-opt "-DLINUX_VERSION_CODE=0x50000" \ - -e tests/bpf-script-example.c - - Note: '--clang-opt' must be placed before '--event/-e'. - - a group of events surrounded by a pair of brace ("{event1,event2,...}"). Each event is separated by commas and the group should be quoted to prevent the shell interpretation. You also need to use --group on @@ -547,14 +533,6 @@ PERF_RECORD_SWITCH_CPU_WIDE. In some cases (e.g. Intel PT, CoreSight or Arm SPE) switch events will be enabled automatically, which can be suppressed by by the option --no-switch-events. ---clang-path=PATH:: -Path to clang binary to use for compiling BPF scriptlets. -(enabled when BPF support is on) - ---clang-opt=OPTIONS:: -Options passed to clang when compiling BPF scriptlets. -(enabled when BPF support is on) - --vmlinux=PATH:: Specify vmlinux path which has debuginfo. (enabled when BPF prologue is on) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index e0592ed4c10f..d66b52407e19 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -589,18 +589,6 @@ ifndef NO_LIBELF LIBBPF_STATIC := 1 endif endif - - ifndef NO_DWARF - ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET - CFLAGS += -DHAVE_BPF_PROLOGUE - $(call detected,CONFIG_BPF_PROLOGUE) - else - msg := $(warning BPF prologue is not supported by architecture $(SRCARCH), missing regs_query_register_offset()); - endif - else - msg := $(warning DWARF support is off, BPF prologue is disabled); - endif - endif # NO_LIBBPF endif # NO_LIBELF diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index aec18db7ff23..34bb31f08bb5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -37,8 +37,6 @@ #include "util/parse-branch-options.h" #include "util/parse-regs-options.h" #include "util/perf_api_probe.h" -#include "util/llvm-utils.h" -#include "util/bpf-loader.h" #include "util/trigger.h" #include "util/perf-hooks.h" #include "util/cpu-set-sched.h" @@ -2465,16 +2463,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } } - err = bpf__apply_obj_config(); - if (err) { - char errbuf[BUFSIZ]; - - bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); - pr_err("ERROR: Apply config to BPF failed: %s\n", - errbuf); - goto out_free_threads; - } - /* * Normally perf_session__new would do this, but it doesn't have the * evlist. @@ -3486,10 +3474,6 @@ static struct option __record_options[] = { "collect kernel callchains"), OPT_BOOLEAN(0, "user-callchains", &record.opts.user_callchains, "collect user callchains"), - OPT_STRING(0, "clang-path", &llvm_param.clang_path, "clang path", - "clang binary to use for compiling BPF scriptlets"), - OPT_STRING(0, "clang-opt", &llvm_param.clang_opt, "clang options", - "options passed to clang when compiling BPF scriptlets"), OPT_STRING(0, "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), OPT_BOOLEAN(0, "buildid-all", &record.buildid_all, @@ -3967,27 +3951,6 @@ int cmd_record(int argc, const char **argv) setlocale(LC_ALL, ""); -#ifndef HAVE_LIBBPF_SUPPORT -# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, "NO_LIBBPF=1", c) - set_nobuild('\0', "clang-path", true); - set_nobuild('\0', "clang-opt", true); -# undef set_nobuild -#endif - -#ifndef HAVE_BPF_PROLOGUE -# if !defined (HAVE_DWARF_SUPPORT) -# define REASON "NO_DWARF=1" -# elif !defined (HAVE_LIBBPF_SUPPORT) -# define REASON "NO_LIBBPF=1" -# else -# define REASON "this architecture doesn't support BPF prologue" -# endif -# define set_nobuild(s, l, c) set_option_nobuild(record_options, s, l, REASON, c) - set_nobuild('\0', "vmlinux", true); -# undef set_nobuild -# undef REASON -#endif - #ifndef HAVE_BPF_SKEL # define set_nobuild(s, l, m, c) set_option_nobuild(record_options, s, l, m, c) set_nobuild('\0', "off-cpu", "no BUILD_BPF_SKEL=1", true); @@ -4116,14 +4079,6 @@ int cmd_record(int argc, const char **argv) if (dry_run) goto out; - err = bpf__setup_stdout(rec->evlist); - if (err) { - bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf)); - pr_err("ERROR: Setup BPF stdout failed: %s\n", - errbuf); - goto out; - } - err = -ENOMEM; if (rec->no_buildid_cache || rec->no_buildid) { diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7ece2521efb6..59862467e781 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -18,6 +18,7 @@ #include <api/fs/tracing_path.h> #ifdef HAVE_LIBBPF_SUPPORT #include <bpf/bpf.h> +#include <bpf/libbpf.h> #endif #include "util/bpf_map.h" #include "util/rlimit.h" @@ -53,7 +54,6 @@ #include "trace/beauty/beauty.h" #include "trace-event.h" #include "util/parse-events.h" -#include "util/bpf-loader.h" #include "util/tracepoint.h" #include "callchain.h" #include "print_binary.h" @@ -3287,17 +3287,6 @@ static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace, const ch return bpf_object__find_map_by_name(trace->bpf_obj, name); } -static void trace__set_bpf_map_filtered_pids(struct trace *trace) -{ - trace->filter_pids.map = trace__find_bpf_map_by_name(trace, "pids_filtered"); -} - -static void trace__set_bpf_map_syscalls(struct trace *trace) -{ - trace->syscalls.prog_array.sys_enter = trace__find_bpf_map_by_name(trace, "syscalls_sys_enter"); - trace->syscalls.prog_array.sys_exit = trace__find_bpf_map_by_name(trace, "syscalls_sys_exit"); -} - static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, const char *name) { struct bpf_program *pos, *prog = NULL; @@ -3553,25 +3542,6 @@ static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace) return err; } -static void trace__delete_augmented_syscalls(struct trace *trace) -{ - struct evsel *evsel, *tmp; - - evlist__remove(trace->evlist, trace->syscalls.events.augmented); - evsel__delete(trace->syscalls.events.augmented); - trace->syscalls.events.augmented = NULL; - - evlist__for_each_entry_safe(trace->evlist, tmp, evsel) { - if (evsel->bpf_obj == trace->bpf_obj) { - evlist__remove(trace->evlist, evsel); - evsel__delete(evsel); - } - - } - - bpf_object__close(trace->bpf_obj); - trace->bpf_obj = NULL; -} #else // HAVE_LIBBPF_SUPPORT static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace __maybe_unused, const char *name __maybe_unused) @@ -3579,45 +3549,12 @@ static struct bpf_map *trace__find_bpf_map_by_name(struct trace *trace __maybe_u return NULL; } -static void trace__set_bpf_map_filtered_pids(struct trace *trace __maybe_unused) -{ -} - -static void trace__set_bpf_map_syscalls(struct trace *trace __maybe_unused) -{ -} - -static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace __maybe_unused, - const char *name __maybe_unused) -{ - return NULL; -} - static int trace__init_syscalls_bpf_prog_array_maps(struct trace *trace __maybe_unused) { return 0; } - -static void trace__delete_augmented_syscalls(struct trace *trace __maybe_unused) -{ -} #endif // HAVE_LIBBPF_SUPPORT -static bool trace__only_augmented_syscalls_evsels(struct trace *trace) -{ - struct evsel *evsel; - - evlist__for_each_entry(trace->evlist, evsel) { - if (evsel == trace->syscalls.events.augmented || - evsel->bpf_obj == trace->bpf_obj) - continue; - - return false; - } - - return true; -} - static int trace__set_ev_qualifier_filter(struct trace *trace) { if (trace->syscalls.events.sys_enter) @@ -3981,16 +3918,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv) if (err < 0) goto out_error_open; - err = bpf__apply_obj_config(); - if (err) { - char errbuf[BUFSIZ]; - - bpf__strerror_apply_obj_config(err, errbuf, sizeof(errbuf)); - pr_err("ERROR: Apply config to BPF failed: %s\n", - errbuf); - goto out_error_open; - } - err = trace__set_filter_pids(trace); if (err < 0) goto out_error_mem; @@ -4922,77 +4849,6 @@ int cmd_trace(int argc, const char **argv) "cgroup monitoring only available in system-wide mode"); } - evsel = bpf__setup_output_event(trace.evlist, "__augmented_syscalls__"); - if (IS_ERR(evsel)) { - bpf__strerror_setup_output_event(trace.evlist, PTR_ERR(evsel), bf, sizeof(bf)); - pr_err("ERROR: Setup trace syscalls enter failed: %s\n", bf); - goto out; - } - - if (evsel) { - trace.syscalls.events.augmented = evsel; - - evsel = evlist__find_tracepoint_by_name(trace.evlist, "raw_syscalls:sys_enter"); - if (evsel == NULL) { - pr_err("ERROR: raw_syscalls:sys_enter not found in the augmented BPF object\n"); - goto out; - } - - if (evsel->bpf_obj == NULL) { - pr_err("ERROR: raw_syscalls:sys_enter not associated to a BPF object\n"); - goto out; - } - - trace.bpf_obj = evsel->bpf_obj; - - /* - * If we have _just_ the augmenter event but don't have a - * explicit --syscalls, then assume we want all strace-like - * syscalls: - */ - if (!trace.trace_syscalls && trace__only_augmented_syscalls_evsels(&trace)) - trace.trace_syscalls = true; - /* - * So, if we have a syscall augmenter, but trace_syscalls, aka - * strace-like syscall tracing is not set, then we need to trow - * away the augmenter, i.e. all the events that were created - * from that BPF object file. - * - * This is more to fix the current .perfconfig trace.add_events - * style of setting up the strace-like eBPF based syscall point - * payload augmenter. - * - * All this complexity will be avoided by adding an alternative - * to trace.add_events in the form of - * trace.bpf_augmented_syscalls, that will be only parsed if we - * need it. - * - * .perfconfig trace.add_events is still useful if we want, for - * instance, have msr_write.msr in some .perfconfig profile based - * 'perf trace --config determinism.profile' mode, where for some - * particular goal/workload type we want a set of events and - * output mode (with timings, etc) instead of having to add - * all via the command line. - * - * Also --config to specify an alternate .perfconfig file needs - * to be implemented. - */ - if (!trace.trace_syscalls) { - trace__delete_augmented_syscalls(&trace); - } else { - trace__set_bpf_map_filtered_pids(&trace); - trace__set_bpf_map_syscalls(&trace); - trace.syscalls.unaugmented_prog = trace__find_bpf_program_by_title(&trace, "!raw_syscalls:unaugmented"); - } - } - - err = bpf__setup_stdout(trace.evlist); - if (err) { - bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf)); - pr_err("ERROR: Setup BPF stdout failed: %s\n", bf); - goto out; - } - err = -1; if (map_dump_str) { diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 38cae4721583..d3fc8090413c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -18,7 +18,6 @@ #include <subcmd/run-command.h> #include "util/parse-events.h" #include <subcmd/parse-options.h> -#include "util/bpf-loader.h" #include "util/debug.h" #include "util/event.h" #include "util/util.h" // usage() @@ -324,7 +323,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) perf_config__exit(); exit_browser(status); perf_env__exit(&perf_env); - bpf__clear(); if (status) return status & 0xff; diff --git a/tools/perf/tests/.gitignore b/tools/perf/tests/.gitignore deleted file mode 100644 index d053b325f728..000000000000 --- a/tools/perf/tests/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -llvm-src-base.c -llvm-src-kbuild.c -llvm-src-prologue.c -llvm-src-relocation.c diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 52df5923a8b9..63d5e6d5f165 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -37,8 +37,6 @@ perf-y += sample-parsing.o perf-y += parse-no-sample-id-all.o perf-y += kmod-path.o perf-y += thread-map.o -perf-y += llvm.o llvm-src-base.o llvm-src-kbuild.o llvm-src-prologue.o llvm-src-relocation.o -perf-y += bpf.o perf-y += topology.o perf-y += mem.o perf-y += cpumap.o @@ -69,34 +67,6 @@ perf-y += sigtrap.o perf-y += event_groups.o perf-y += symbols.o -$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build - $(call rule_mkdir) - $(Q)echo '#include <tests/llvm.h>' > $@ - $(Q)echo 'const char test_llvm__bpf_base_prog[] =' >> $@ - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ - $(Q)echo ';' >> $@ - -$(OUTPUT)tests/llvm-src-kbuild.c: tests/bpf-script-test-kbuild.c tests/Build - $(call rule_mkdir) - $(Q)echo '#include <tests/llvm.h>' > $@ - $(Q)echo 'const char test_llvm__bpf_test_kbuild_prog[] =' >> $@ - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ - $(Q)echo ';' >> $@ - -$(OUTPUT)tests/llvm-src-prologue.c: tests/bpf-script-test-prologue.c tests/Build - $(call rule_mkdir) - $(Q)echo '#include <tests/llvm.h>' > $@ - $(Q)echo 'const char test_llvm__bpf_test_prologue_prog[] =' >> $@ - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ - $(Q)echo ';' >> $@ - -$(OUTPUT)tests/llvm-src-relocation.c: tests/bpf-script-test-relocation.c tests/Build - $(call rule_mkdir) - $(Q)echo '#include <tests/llvm.h>' > $@ - $(Q)echo 'const char test_llvm__bpf_test_relocation[] =' >> $@ - $(Q)sed -e 's/"/\\"/g' -e 's/\(.*\)/"\1\\n"/g' $< >> $@ - $(Q)echo ';' >> $@ - ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc)) perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o endif diff --git a/tools/perf/tests/bpf-script-example.c b/tools/perf/tests/bpf-script-example.c deleted file mode 100644 index b638cc99d5ae..000000000000 --- a/tools/perf/tests/bpf-script-example.c +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * bpf-script-example.c - * Test basic LLVM building - */ -#ifndef LINUX_VERSION_CODE -# error Need LINUX_VERSION_CODE -# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' -#endif -#define BPF_ANY 0 -#define BPF_MAP_TYPE_ARRAY 2 -#define BPF_FUNC_map_lookup_elem 1 -#define BPF_FUNC_map_update_elem 2 - -static void *(*bpf_map_lookup_elem)(void *map, void *key) = - (void *) BPF_FUNC_map_lookup_elem; -static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = - (void *) BPF_FUNC_map_update_elem; - -/* - * Following macros are taken from tools/lib/bpf/bpf_helpers.h, - * and are used to create BTF defined maps. It is easier to take - * 2 simple macros, than being able to include above header in - * runtime. - * - * __uint - defines integer attribute of BTF map definition, - * Such attributes are represented using a pointer to an array, - * in which dimensionality of array encodes specified integer - * value. - * - * __type - defines pointer variable with typeof(val) type for - * attributes like key or value, which will be defined by the - * size of the type. - */ -#define __uint(name, val) int (*name)[val] -#define __type(name, val) typeof(val) *name - -#define SEC(NAME) __attribute__((section(NAME), used)) -struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __uint(max_entries, 1); - __type(key, int); - __type(value, int); -} flip_table SEC(".maps"); - -SEC("syscalls:sys_enter_epoll_pwait") -int bpf_func__SyS_epoll_pwait(void *ctx) -{ - int ind =0; - int *flag = bpf_map_lookup_elem(&flip_table, &ind); - int new_flag; - if (!flag) - return 0; - /* flip flag and store back */ - new_flag = !*flag; - bpf_map_update_elem(&flip_table, &ind, &new_flag, BPF_ANY); - return new_flag; -} -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = LINUX_VERSION_CODE; diff --git a/tools/perf/tests/bpf-script-test-kbuild.c b/tools/perf/tests/bpf-script-test-kbuild.c deleted file mode 100644 index 219673aa278f..000000000000 --- a/tools/perf/tests/bpf-script-test-kbuild.c +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * bpf-script-test-kbuild.c - * Test include from kernel header - */ -#ifndef LINUX_VERSION_CODE -# error Need LINUX_VERSION_CODE -# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' -#endif -#define SEC(NAME) __attribute__((section(NAME), used)) - -#include <uapi/linux/fs.h> - -SEC("func=vfs_llseek") -int bpf_func__vfs_llseek(void *ctx) -{ - return 0; -} - -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = LINUX_VERSION_CODE; diff --git a/tools/perf/tests/bpf-script-test-prologue.c b/tools/perf/tests/bpf-script-test-prologue.c deleted file mode 100644 index 91778b5c6125..000000000000 --- a/tools/perf/tests/bpf-script-test-prologue.c +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * bpf-script-test-prologue.c - * Test BPF prologue - */ -#ifndef LINUX_VERSION_CODE -# error Need LINUX_VERSION_CODE -# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' -#endif -#define SEC(NAME) __attribute__((section(NAME), used)) - -#include <uapi/linux/fs.h> - -/* - * If CONFIG_PROFILE_ALL_BRANCHES is selected, - * 'if' is redefined after include kernel header. - * Recover 'if' for BPF object code. - */ -#ifdef if -# undef if -#endif - -typedef unsigned int __bitwise fmode_t; - -#define FMODE_READ 0x1 -#define FMODE_WRITE 0x2 - -static void (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) = - (void *) 6; - -SEC("func=null_lseek file->f_mode offset orig") -int bpf_func__null_lseek(void *ctx, int err, unsigned long _f_mode, - unsigned long offset, unsigned long orig) -{ - fmode_t f_mode = (fmode_t)_f_mode; - - if (err) - return 0; - if (f_mode & FMODE_WRITE) - return 0; - if (offset & 1) - return 0; - if (orig == SEEK_CUR) - return 0; - return 1; -} - -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = LINUX_VERSION_CODE; diff --git a/tools/perf/tests/bpf-script-test-relocation.c b/tools/perf/tests/bpf-script-test-relocation.c deleted file mode 100644 index 74006e4b2d24..000000000000 --- a/tools/perf/tests/bpf-script-test-relocation.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * bpf-script-test-relocation.c - * Test BPF loader checking relocation - */ -#ifndef LINUX_VERSION_CODE -# error Need LINUX_VERSION_CODE -# error Example: for 4.2 kernel, put 'clang-opt="-DLINUX_VERSION_CODE=0x40200" into llvm section of ~/.perfconfig' -#endif -#define BPF_ANY 0 -#define BPF_MAP_TYPE_ARRAY 2 -#define BPF_FUNC_map_lookup_elem 1 -#define BPF_FUNC_map_update_elem 2 - -static void *(*bpf_map_lookup_elem)(void *map, void *key) = - (void *) BPF_FUNC_map_lookup_elem; -static void *(*bpf_map_update_elem)(void *map, void *key, void *value, int flags) = - (void *) BPF_FUNC_map_update_elem; - -struct bpf_map_def { - unsigned int type; - unsigned int key_size; - unsigned int value_size; - unsigned int max_entries; -}; - -#define SEC(NAME) __attribute__((section(NAME), used)) -struct bpf_map_def SEC("maps") my_table = { - .type = BPF_MAP_TYPE_ARRAY, - .key_size = sizeof(int), - .value_size = sizeof(int), - .max_entries = 1, -}; - -int this_is_a_global_val; - -SEC("func=sys_write") -int bpf_func__sys_write(void *ctx) -{ - int key = 0; - int value = 0; - - /* - * Incorrect relocation. Should not allow this program be - * loaded into kernel. - */ - bpf_map_update_elem(&this_is_a_global_val, &key, &value, 0); - return 0; -} -char _license[] SEC("license") = "GPL"; -int _version SEC("version") = LINUX_VERSION_CODE; diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c deleted file mode 100644 index 9ccecd873ecd..000000000000 --- a/tools/perf/tests/bpf.c +++ /dev/null @@ -1,390 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/epoll.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <util/record.h> -#include <util/util.h> -#include <util/bpf-loader.h> -#include <util/evlist.h> -#include <linux/filter.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <api/fs/fs.h> -#include <perf/mmap.h> -#include "tests.h" -#include "llvm.h" -#include "debug.h" -#include "parse-events.h" -#include "util/mmap.h" -#define NR_ITERS 111 -#define PERF_TEST_BPF_PATH "/sys/fs/bpf/perf_test" - -#if defined(HAVE_LIBBPF_SUPPORT) && defined(HAVE_LIBTRACEEVENT) -#include <linux/bpf.h> -#include <bpf/bpf.h> - -static int epoll_pwait_loop(void) -{ - struct epoll_event events; - int i; - - /* Should fail NR_ITERS times */ - for (i = 0; i < NR_ITERS; i++) - epoll_pwait(-(i + 1), &events, 0, 0, NULL); - return 0; -} - -#ifdef HAVE_BPF_PROLOGUE - -static int llseek_loop(void) -{ - int fds[2], i; - - fds[0] = open("/dev/null", O_RDONLY); - fds[1] = open("/dev/null", O_RDWR); - - if (fds[0] < 0 || fds[1] < 0) - return -1; - - for (i = 0; i < NR_ITERS; i++) { - lseek(fds[i % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET); - lseek(fds[(i + 1) % 2], i, (i / 2) % 2 ? SEEK_CUR : SEEK_SET); - } - close(fds[0]); - close(fds[1]); - return 0; -} - -#endif - -static struct { - enum test_llvm__testcase prog_id; - const char *name; - const char *msg_compile_fail; - const char *msg_load_fail; - int (*target_func)(void); - int expect_result; - bool pin; -} bpf_testcase_table[] = { - { - .prog_id = LLVM_TESTCASE_BASE, - .name = "[basic_bpf_test]", - .msg_compile_fail = "fix 'perf test LLVM' first", - .msg_load_fail = "load bpf object failed", - .target_func = &epoll_pwait_loop, - .expect_result = (NR_ITERS + 1) / 2, - }, - { - .prog_id = LLVM_TESTCASE_BASE, - .name = "[bpf_pinning]", - .msg_compile_fail = "fix kbuild first", - .msg_load_fail = "check your vmlinux setting?", - .target_func = &epoll_pwait_loop, - .expect_result = (NR_ITERS + 1) / 2, - .pin = true, - }, -#ifdef HAVE_BPF_PROLOGUE - { - .prog_id = LLVM_TESTCASE_BPF_PROLOGUE, - .name = "[bpf_prologue_test]", - .msg_compile_fail = "fix kbuild first", - .msg_load_fail = "check your vmlinux setting?", - .target_func = &llseek_loop, - .expect_result = (NR_ITERS + 1) / 4, - }, -#endif -}; - -static int do_test(struct bpf_object *obj, int (*func)(void), - int expect) -{ - struct record_opts opts = { - .target = { - .uid = UINT_MAX, - .uses_mmap = true, - }, - .freq = 0, - .mmap_pages = 256, - .default_interval = 1, - }; - - char pid[16]; - char sbuf[STRERR_BUFSIZE]; - struct evlist *evlist; - int i, ret = TEST_FAIL, err = 0, count = 0; - - struct parse_events_state parse_state; - struct parse_events_error parse_error; - - parse_events_error__init(&parse_error); - bzero(&parse_state, sizeof(parse_state)); - parse_state.error = &parse_error; - INIT_LIST_HEAD(&parse_state.list); - - err = parse_events_load_bpf_obj(&parse_state, &parse_state.list, obj, NULL, NULL); - parse_events_error__exit(&parse_error); - if (err == -ENODATA) { - pr_debug("Failed to add events selected by BPF, debuginfo package not installed\n"); - return TEST_SKIP; - } - if (err || list_empty(&parse_state.list)) { - pr_debug("Failed to add events selected by BPF\n"); - return TEST_FAIL; - } - - snprintf(pid, sizeof(pid), "%d", getpid()); - pid[sizeof(pid) - 1] = '\0'; - opts.target.tid = opts.target.pid = pid; - - /* Instead of evlist__new_default, don't add default events */ - evlist = evlist__new(); - if (!evlist) { - pr_debug("Not enough memory to create evlist\n"); - return TEST_FAIL; - } - - err = evlist__create_maps(evlist, &opts.target); - if (err < 0) { - pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_evlist; - } - - evlist__splice_list_tail(evlist, &parse_state.list); - - evlist__config(evlist, &opts, NULL); - - err = evlist__open(evlist); - if (err < 0) { - pr_debug("perf_evlist__open: %s\n", - str_error_r(errno, sbuf, sizeof(sbuf))); - goto out_delete_evlist; - } - - err = evlist__mmap(evlist, opts.mmap_pages); - if (err < 0) { - pr_debug("evlist__mmap: %s\n", - str_error_r |