Skip to content

Commit 9940d67

Browse files
4astdavem330
authored andcommitted
bpf: support bpf_get_stackid() and bpf_perf_event_output() in tracepoint programs
needs two wrapper functions to fetch 'struct pt_regs *' to convert tracepoint bpf context into kprobe bpf context to reuse existing helper functions Signed-off-by: Alexei Starovoitov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9fd82b6 commit 9940d67

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ struct bpf_array {
160160
#define MAX_TAIL_CALL_CNT 32
161161

162162
u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
163+
u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
163164
void bpf_fd_array_map_clear(struct bpf_map *map);
164165
bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp);
165166
const struct bpf_func_proto *bpf_get_trace_printk_proto(void);

kernel/bpf/stackmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr)
116116
return ERR_PTR(err);
117117
}
118118

119-
static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
119+
u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5)
120120
{
121121
struct pt_regs *regs = (struct pt_regs *) (long) r1;
122122
struct bpf_map *map = (struct bpf_map *) (long) r2;

kernel/trace/bpf_trace.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,52 @@ static struct bpf_prog_type_list kprobe_tl = {
340340
.type = BPF_PROG_TYPE_KPROBE,
341341
};
342342

343+
static u64 bpf_perf_event_output_tp(u64 r1, u64 r2, u64 index, u64 r4, u64 size)
344+
{
345+
/*
346+
* r1 points to perf tracepoint buffer where first 8 bytes are hidden
347+
* from bpf program and contain a pointer to 'struct pt_regs'. Fetch it
348+
* from there and call the same bpf_perf_event_output() helper
349+
*/
350+
u64 ctx = *(long *)r1;
351+
352+
return bpf_perf_event_output(ctx, r2, index, r4, size);
353+
}
354+
355+
static const struct bpf_func_proto bpf_perf_event_output_proto_tp = {
356+
.func = bpf_perf_event_output_tp,
357+
.gpl_only = true,
358+
.ret_type = RET_INTEGER,
359+
.arg1_type = ARG_PTR_TO_CTX,
360+
.arg2_type = ARG_CONST_MAP_PTR,
361+
.arg3_type = ARG_ANYTHING,
362+
.arg4_type = ARG_PTR_TO_STACK,
363+
.arg5_type = ARG_CONST_STACK_SIZE,
364+
};
365+
366+
static u64 bpf_get_stackid_tp(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
367+
{
368+
u64 ctx = *(long *)r1;
369+
370+
return bpf_get_stackid(ctx, r2, r3, r4, r5);
371+
}
372+
373+
static const struct bpf_func_proto bpf_get_stackid_proto_tp = {
374+
.func = bpf_get_stackid_tp,
375+
.gpl_only = true,
376+
.ret_type = RET_INTEGER,
377+
.arg1_type = ARG_PTR_TO_CTX,
378+
.arg2_type = ARG_CONST_MAP_PTR,
379+
.arg3_type = ARG_ANYTHING,
380+
};
381+
343382
static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id)
344383
{
345384
switch (func_id) {
346385
case BPF_FUNC_perf_event_output:
386+
return &bpf_perf_event_output_proto_tp;
347387
case BPF_FUNC_get_stackid:
348-
return NULL;
388+
return &bpf_get_stackid_proto_tp;
349389
default:
350390
return tracing_func_proto(func_id);
351391
}

0 commit comments

Comments
 (0)