Skip to content

Commit 9f4ab6e

Browse files
committed
Merge branch 'bpf_event_output'
Daniel Borkmann says: ==================== BPF updates This minor set adds a new helper bpf_event_output() for eBPF cls/act program types which allows to pass events to user space applications. For details, please see individual patches. v1 -> v2: - Address kbuild bot found compile issue in patch 2 - Rest as is ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 553bc08 + bd570ff commit 9f4ab6e

File tree

5 files changed

+48
-1
lines changed

5 files changed

+48
-1
lines changed

include/linux/bpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
169169
u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
170170
void bpf_fd_array_map_clear(struct bpf_map *map);
171171
bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp);
172+
172173
const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
174+
const struct bpf_func_proto *bpf_get_event_output_proto(void);
173175

174176
#ifdef CONFIG_BPF_SYSCALL
175177
DECLARE_PER_CPU(int, bpf_prog_active);

include/uapi/linux/bpf.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ enum bpf_func_id {
347347
#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
348348
#define BPF_F_DONT_FRAGMENT (1ULL << 2)
349349

350+
/* BPF_FUNC_perf_event_output flags. */
351+
#define BPF_F_INDEX_MASK 0xffffffffULL
352+
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
353+
350354
/* user accessible mirror of in-kernel sk_buff.
351355
* new fields can only be added to the end of this structure
352356
*/

kernel/bpf/core.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,14 +764,21 @@ const struct bpf_func_proto bpf_map_delete_elem_proto __weak;
764764
const struct bpf_func_proto bpf_get_prandom_u32_proto __weak;
765765
const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak;
766766
const struct bpf_func_proto bpf_ktime_get_ns_proto __weak;
767+
767768
const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
768769
const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
769770
const struct bpf_func_proto bpf_get_current_comm_proto __weak;
771+
770772
const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
771773
{
772774
return NULL;
773775
}
774776

777+
const struct bpf_func_proto * __weak bpf_get_event_output_proto(void)
778+
{
779+
return NULL;
780+
}
781+
775782
/* Always built-in helper functions. */
776783
const struct bpf_func_proto bpf_tail_call_proto = {
777784
.func = NULL,

kernel/trace/bpf_trace.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,12 @@ static const struct bpf_func_proto bpf_perf_event_read_proto = {
225225
.arg2_type = ARG_ANYTHING,
226226
};
227227

228-
static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size)
228+
static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 flags, u64 r4, u64 size)
229229
{
230230
struct pt_regs *regs = (struct pt_regs *) (long) r1;
231231
struct bpf_map *map = (struct bpf_map *) (long) r2;
232232
struct bpf_array *array = container_of(map, struct bpf_array, map);
233+
u64 index = flags & BPF_F_INDEX_MASK;
233234
void *data = (void *) (long) r4;
234235
struct perf_sample_data sample_data;
235236
struct perf_event *event;
@@ -239,6 +240,10 @@ static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size)
239240
.data = data,
240241
};
241242

243+
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
244+
return -EINVAL;
245+
if (index == BPF_F_CURRENT_CPU)
246+
index = raw_smp_processor_id();
242247
if (unlikely(index >= array->map.max_entries))
243248
return -E2BIG;
244249

@@ -272,6 +277,33 @@ static const struct bpf_func_proto bpf_perf_event_output_proto = {
272277
.arg5_type = ARG_CONST_STACK_SIZE,
273278
};
274279

280+
static DEFINE_PER_CPU(struct pt_regs, bpf_pt_regs);
281+
282+
static u64 bpf_event_output(u64 r1, u64 r2, u64 flags, u64 r4, u64 size)
283+
{
284+
struct pt_regs *regs = this_cpu_ptr(&bpf_pt_regs);
285+
286+
perf_fetch_caller_regs(regs);
287+
288+
return bpf_perf_event_output((long)regs, r2, flags, r4, size);
289+
}
290+
291+
static const struct bpf_func_proto bpf_event_output_proto = {
292+
.func = bpf_event_output,
293+
.gpl_only = true,
294+
.ret_type = RET_INTEGER,
295+
.arg1_type = ARG_PTR_TO_CTX,
296+
.arg2_type = ARG_CONST_MAP_PTR,
297+
.arg3_type = ARG_ANYTHING,
298+
.arg4_type = ARG_PTR_TO_STACK,
299+
.arg5_type = ARG_CONST_STACK_SIZE,
300+
};
301+
302+
const struct bpf_func_proto *bpf_get_event_output_proto(void)
303+
{
304+
return &bpf_event_output_proto;
305+
}
306+
275307
static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
276308
{
277309
switch (func_id) {

net/core/filter.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
20392039
return &bpf_redirect_proto;
20402040
case BPF_FUNC_get_route_realm:
20412041
return &bpf_get_route_realm_proto;
2042+
case BPF_FUNC_perf_event_output:
2043+
return bpf_get_event_output_proto();
20422044
default:
20432045
return sk_filter_func_proto(func_id);
20442046
}

0 commit comments

Comments
 (0)