Re: [PATCH v2 bpf-next 5/8] bpf: introduce BPF_RAW_TRACEPOINT
From: Daniel Borkmann <daniel@iogearbox.net>
Date: 2018-03-22 09:44:02
On 03/21/2018 07:54 PM, Alexei Starovoitov wrote: [...]
quoted hunk ↗ jump to hunk
@@ -546,6 +556,53 @@ extern void ftrace_profile_free_filter(struct perf_event *event); void perf_trace_buf_update(void *record, u16 type); void *perf_trace_buf_alloc(int size, struct pt_regs **regs, int *rctxp); +void bpf_trace_run1(struct bpf_prog *prog, u64 arg1); +void bpf_trace_run2(struct bpf_prog *prog, u64 arg1, u64 arg2); +void bpf_trace_run3(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3); +void bpf_trace_run4(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4); +void bpf_trace_run5(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5); +void bpf_trace_run6(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6); +void bpf_trace_run7(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7); +void bpf_trace_run8(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8); +void bpf_trace_run9(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9); +void bpf_trace_run10(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10); +void bpf_trace_run11(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11); +void bpf_trace_run12(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12); +void bpf_trace_run13(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, + u64 arg13); +void bpf_trace_run14(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, + u64 arg13, u64 arg14); +void bpf_trace_run15(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, + u64 arg13, u64 arg14, u64 arg15); +void bpf_trace_run16(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, + u64 arg13, u64 arg14, u64 arg15, u64 arg16); +void bpf_trace_run17(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, + u64 arg13, u64 arg14, u64 arg15, u64 arg16, u64 arg17); void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx, struct trace_event_call *call, u64 count, struct pt_regs *regs, struct hlist_head *head,
[...]
quoted hunk ↗ jump to hunk
@@ -896,3 +976,206 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info) return ret; } + +static __always_inline +void __bpf_trace_run(struct bpf_prog *prog, u64 *args) +{ + rcu_read_lock(); + preempt_disable(); + (void) BPF_PROG_RUN(prog, args); + preempt_enable(); + rcu_read_unlock(); +} + +#define EVAL1(FN, X) FN(X) +#define EVAL2(FN, X, Y...) FN(X) EVAL1(FN, Y) +#define EVAL3(FN, X, Y...) FN(X) EVAL2(FN, Y) +#define EVAL4(FN, X, Y...) FN(X) EVAL3(FN, Y) +#define EVAL5(FN, X, Y...) FN(X) EVAL4(FN, Y) +#define EVAL6(FN, X, Y...) FN(X) EVAL5(FN, Y) + +#define COPY(X) args[X - 1] = arg##X; + +void bpf_trace_run1(struct bpf_prog *prog, u64 arg1) +{ + u64 args[1]; + + EVAL1(COPY, 1); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run1); +void bpf_trace_run2(struct bpf_prog *prog, u64 arg1, u64 arg2) +{ + u64 args[2]; + + EVAL2(COPY, 1, 2); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run2); +void bpf_trace_run3(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3) +{ + u64 args[3]; + + EVAL3(COPY, 1, 2, 3); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run3); +void bpf_trace_run4(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4) +{ + u64 args[4]; + + EVAL4(COPY, 1, 2, 3, 4); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run4); +void bpf_trace_run5(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5) +{ + u64 args[5]; + + EVAL5(COPY, 1, 2, 3, 4, 5); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run5); +void bpf_trace_run6(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6) +{ + u64 args[6]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run6); +void bpf_trace_run7(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7) +{ + u64 args[7]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL1(COPY, 7); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run7); +void bpf_trace_run8(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8) +{ + u64 args[8]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL2(COPY, 7, 8); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run8); +void bpf_trace_run9(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9) +{ + u64 args[9]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL3(COPY, 7, 8, 9); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run9); +void bpf_trace_run10(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10) +{ + u64 args[10]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL4(COPY, 7, 8, 9, 10); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run10); +void bpf_trace_run11(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11) +{ + u64 args[11]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL5(COPY, 7, 8, 9, 10, 11); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run11); +void bpf_trace_run12(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12) +{ + u64 args[12]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL6(COPY, 7, 8, 9, 10, 11, 12); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run12); +void bpf_trace_run17(struct bpf_prog *prog, u64 arg1, u64 arg2, + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, + u64 arg13, u64 arg14, u64 arg15, u64 arg16, u64 arg17) +{ + u64 args[17]; + + EVAL6(COPY, 1, 2, 3, 4, 5, 6); + EVAL6(COPY, 7, 8, 9, 10, 11, 12); + EVAL5(COPY, 13, 14, 15, 16, 17); + __bpf_trace_run(prog, args); +} +EXPORT_SYMBOL_GPL(bpf_trace_run17);
Would be nice if we could generate all these above via macro, e.g. when we define a hard upper limit for max number of tracepoint args anyway, so this gets automatically adjusted as well. Maybe some of the logic from BPF_CALL_*() macros could be borrowed for this purpose. Thanks, Daniel