root/tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_stack_print_output
  2. test_get_stack_raw_tp

   1 // SPDX-License-Identifier: GPL-2.0
   2 #define _GNU_SOURCE
   3 #include <pthread.h>
   4 #include <sched.h>
   5 #include <sys/socket.h>
   6 #include <test_progs.h>
   7 
   8 #define MAX_CNT_RAWTP   10ull
   9 #define MAX_STACK_RAWTP 100
  10 
  11 static int duration = 0;
  12 
  13 struct get_stack_trace_t {
  14         int pid;
  15         int kern_stack_size;
  16         int user_stack_size;
  17         int user_stack_buildid_size;
  18         __u64 kern_stack[MAX_STACK_RAWTP];
  19         __u64 user_stack[MAX_STACK_RAWTP];
  20         struct bpf_stack_build_id user_stack_buildid[MAX_STACK_RAWTP];
  21 };
  22 
  23 static void get_stack_print_output(void *ctx, int cpu, void *data, __u32 size)
  24 {
  25         bool good_kern_stack = false, good_user_stack = false;
  26         const char *nonjit_func = "___bpf_prog_run";
  27         struct get_stack_trace_t *e = data;
  28         int i, num_stack;
  29         static __u64 cnt;
  30         struct ksym *ks;
  31 
  32         cnt++;
  33 
  34         if (size < sizeof(struct get_stack_trace_t)) {
  35                 __u64 *raw_data = data;
  36                 bool found = false;
  37 
  38                 num_stack = size / sizeof(__u64);
  39                 /* If jit is enabled, we do not have a good way to
  40                  * verify the sanity of the kernel stack. So we
  41                  * just assume it is good if the stack is not empty.
  42                  * This could be improved in the future.
  43                  */
  44                 if (env.jit_enabled) {
  45                         found = num_stack > 0;
  46                 } else {
  47                         for (i = 0; i < num_stack; i++) {
  48                                 ks = ksym_search(raw_data[i]);
  49                                 if (ks && (strcmp(ks->name, nonjit_func) == 0)) {
  50                                         found = true;
  51                                         break;
  52                                 }
  53                         }
  54                 }
  55                 if (found) {
  56                         good_kern_stack = true;
  57                         good_user_stack = true;
  58                 }
  59         } else {
  60                 num_stack = e->kern_stack_size / sizeof(__u64);
  61                 if (env.jit_enabled) {
  62                         good_kern_stack = num_stack > 0;
  63                 } else {
  64                         for (i = 0; i < num_stack; i++) {
  65                                 ks = ksym_search(e->kern_stack[i]);
  66                                 if (ks && (strcmp(ks->name, nonjit_func) == 0)) {
  67                                         good_kern_stack = true;
  68                                         break;
  69                                 }
  70                         }
  71                 }
  72                 if (e->user_stack_size > 0 && e->user_stack_buildid_size > 0)
  73                         good_user_stack = true;
  74         }
  75 
  76         if (!good_kern_stack)
  77             CHECK(!good_kern_stack, "kern_stack", "corrupted kernel stack\n");
  78         if (!good_user_stack)
  79             CHECK(!good_user_stack, "user_stack", "corrupted user stack\n");
  80 }
  81 
  82 void test_get_stack_raw_tp(void)
  83 {
  84         const char *file = "./test_get_stack_rawtp.o";
  85         const char *file_err = "./test_get_stack_rawtp_err.o";
  86         const char *prog_name = "raw_tracepoint/sys_enter";
  87         int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP;
  88         struct perf_buffer_opts pb_opts = {};
  89         struct perf_buffer *pb = NULL;
  90         struct bpf_link *link = NULL;
  91         struct timespec tv = {0, 10};
  92         struct bpf_program *prog;
  93         struct bpf_object *obj;
  94         struct bpf_map *map;
  95         cpu_set_t cpu_set;
  96 
  97         err = bpf_prog_load(file_err, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
  98         if (CHECK(err >= 0, "prog_load raw tp", "err %d errno %d\n", err, errno))
  99                 return;
 100 
 101         err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
 102         if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
 103                 return;
 104 
 105         prog = bpf_object__find_program_by_title(obj, prog_name);
 106         if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name))
 107                 goto close_prog;
 108 
 109         map = bpf_object__find_map_by_name(obj, "perfmap");
 110         if (CHECK(!map, "bpf_find_map", "not found\n"))
 111                 goto close_prog;
 112 
 113         err = load_kallsyms();
 114         if (CHECK(err < 0, "load_kallsyms", "err %d errno %d\n", err, errno))
 115                 goto close_prog;
 116 
 117         CPU_ZERO(&cpu_set);
 118         CPU_SET(0, &cpu_set);
 119         err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
 120         if (CHECK(err, "set_affinity", "err %d, errno %d\n", err, errno))
 121                 goto close_prog;
 122 
 123         link = bpf_program__attach_raw_tracepoint(prog, "sys_enter");
 124         if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n", PTR_ERR(link)))
 125                 goto close_prog;
 126 
 127         pb_opts.sample_cb = get_stack_print_output;
 128         pb = perf_buffer__new(bpf_map__fd(map), 8, &pb_opts);
 129         if (CHECK(IS_ERR(pb), "perf_buf__new", "err %ld\n", PTR_ERR(pb)))
 130                 goto close_prog;
 131 
 132         /* trigger some syscall action */
 133         for (i = 0; i < MAX_CNT_RAWTP; i++)
 134                 nanosleep(&tv, NULL);
 135 
 136         while (exp_cnt > 0) {
 137                 err = perf_buffer__poll(pb, 100);
 138                 if (err < 0 && CHECK(err < 0, "pb__poll", "err %d\n", err))
 139                         goto close_prog;
 140                 exp_cnt -= err;
 141         }
 142 
 143 close_prog:
 144         if (!IS_ERR_OR_NULL(link))
 145                 bpf_link__destroy(link);
 146         if (!IS_ERR_OR_NULL(pb))
 147                 perf_buffer__free(pb);
 148         bpf_object__close(obj);
 149 }

/* [<][>][^][v][top][bottom][index][help] */