]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/trace/bpf_trace.c
Merge tag 'armsoc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux.git] / kernel / trace / bpf_trace.c
index 492a8bfaae98c584bdf94c3d53b656e889f02099..44bd08f2443b3bec8928ab5c9f9080af1c8a4c02 100644 (file)
@@ -505,14 +505,17 @@ static const struct bpf_func_proto bpf_perf_event_output_proto = {
        .arg5_type      = ARG_CONST_SIZE_OR_ZERO,
 };
 
-static DEFINE_PER_CPU(struct pt_regs, bpf_pt_regs);
-static DEFINE_PER_CPU(struct perf_sample_data, bpf_misc_sd);
+static DEFINE_PER_CPU(int, bpf_event_output_nest_level);
+struct bpf_nested_pt_regs {
+       struct pt_regs regs[3];
+};
+static DEFINE_PER_CPU(struct bpf_nested_pt_regs, bpf_pt_regs);
+static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_misc_sds);
 
 u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
                     void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy)
 {
-       struct perf_sample_data *sd = this_cpu_ptr(&bpf_misc_sd);
-       struct pt_regs *regs = this_cpu_ptr(&bpf_pt_regs);
+       int nest_level = this_cpu_inc_return(bpf_event_output_nest_level);
        struct perf_raw_frag frag = {
                .copy           = ctx_copy,
                .size           = ctx_size,
@@ -527,12 +530,25 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size,
                        .data   = meta,
                },
        };
+       struct perf_sample_data *sd;
+       struct pt_regs *regs;
+       u64 ret;
+
+       if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) {
+               ret = -EBUSY;
+               goto out;
+       }
+       sd = this_cpu_ptr(&bpf_misc_sds.sds[nest_level - 1]);
+       regs = this_cpu_ptr(&bpf_pt_regs.regs[nest_level - 1]);
 
        perf_fetch_caller_regs(regs);
        perf_sample_data_init(sd, 0, 0);
        sd->raw = &raw;
 
-       return __bpf_perf_event_output(regs, map, flags, sd);
+       ret = __bpf_perf_event_output(regs, map, flags, sd);
+out:
+       this_cpu_dec(bpf_event_output_nest_level);
+       return ret;
 }
 
 BPF_CALL_0(bpf_get_current_task)