Commit 9f4ab6ec authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 553bc087 bd570ff9
...@@ -169,7 +169,9 @@ u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5); ...@@ -169,7 +169,9 @@ u64 bpf_tail_call(u64 ctx, u64 r2, u64 index, u64 r4, u64 r5);
u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5); u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
void bpf_fd_array_map_clear(struct bpf_map *map); void bpf_fd_array_map_clear(struct bpf_map *map);
bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp); bool bpf_prog_array_compatible(struct bpf_array *array, const struct bpf_prog *fp);
const struct bpf_func_proto *bpf_get_trace_printk_proto(void); const struct bpf_func_proto *bpf_get_trace_printk_proto(void);
const struct bpf_func_proto *bpf_get_event_output_proto(void);
#ifdef CONFIG_BPF_SYSCALL #ifdef CONFIG_BPF_SYSCALL
DECLARE_PER_CPU(int, bpf_prog_active); DECLARE_PER_CPU(int, bpf_prog_active);
......
...@@ -347,6 +347,10 @@ enum bpf_func_id { ...@@ -347,6 +347,10 @@ enum bpf_func_id {
#define BPF_F_ZERO_CSUM_TX (1ULL << 1) #define BPF_F_ZERO_CSUM_TX (1ULL << 1)
#define BPF_F_DONT_FRAGMENT (1ULL << 2) #define BPF_F_DONT_FRAGMENT (1ULL << 2)
/* BPF_FUNC_perf_event_output flags. */
#define BPF_F_INDEX_MASK 0xffffffffULL
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
/* user accessible mirror of in-kernel sk_buff. /* user accessible mirror of in-kernel sk_buff.
* new fields can only be added to the end of this structure * new fields can only be added to the end of this structure
*/ */
......
...@@ -764,14 +764,21 @@ const struct bpf_func_proto bpf_map_delete_elem_proto __weak; ...@@ -764,14 +764,21 @@ const struct bpf_func_proto bpf_map_delete_elem_proto __weak;
const struct bpf_func_proto bpf_get_prandom_u32_proto __weak; const struct bpf_func_proto bpf_get_prandom_u32_proto __weak;
const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak; const struct bpf_func_proto bpf_get_smp_processor_id_proto __weak;
const struct bpf_func_proto bpf_ktime_get_ns_proto __weak; const struct bpf_func_proto bpf_ktime_get_ns_proto __weak;
const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak; const struct bpf_func_proto bpf_get_current_pid_tgid_proto __weak;
const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak; const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
const struct bpf_func_proto bpf_get_current_comm_proto __weak; const struct bpf_func_proto bpf_get_current_comm_proto __weak;
const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void) const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
{ {
return NULL; return NULL;
} }
const struct bpf_func_proto * __weak bpf_get_event_output_proto(void)
{
return NULL;
}
/* Always built-in helper functions. */ /* Always built-in helper functions. */
const struct bpf_func_proto bpf_tail_call_proto = { const struct bpf_func_proto bpf_tail_call_proto = {
.func = NULL, .func = NULL,
......
...@@ -225,11 +225,12 @@ static const struct bpf_func_proto bpf_perf_event_read_proto = { ...@@ -225,11 +225,12 @@ static const struct bpf_func_proto bpf_perf_event_read_proto = {
.arg2_type = ARG_ANYTHING, .arg2_type = ARG_ANYTHING,
}; };
static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size) static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 flags, u64 r4, u64 size)
{ {
struct pt_regs *regs = (struct pt_regs *) (long) r1; struct pt_regs *regs = (struct pt_regs *) (long) r1;
struct bpf_map *map = (struct bpf_map *) (long) r2; struct bpf_map *map = (struct bpf_map *) (long) r2;
struct bpf_array *array = container_of(map, struct bpf_array, map); struct bpf_array *array = container_of(map, struct bpf_array, map);
u64 index = flags & BPF_F_INDEX_MASK;
void *data = (void *) (long) r4; void *data = (void *) (long) r4;
struct perf_sample_data sample_data; struct perf_sample_data sample_data;
struct perf_event *event; struct perf_event *event;
...@@ -239,6 +240,10 @@ static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size) ...@@ -239,6 +240,10 @@ static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size)
.data = data, .data = data,
}; };
if (unlikely(flags & ~(BPF_F_INDEX_MASK)))
return -EINVAL;
if (index == BPF_F_CURRENT_CPU)
index = raw_smp_processor_id();
if (unlikely(index >= array->map.max_entries)) if (unlikely(index >= array->map.max_entries))
return -E2BIG; return -E2BIG;
...@@ -272,6 +277,33 @@ static const struct bpf_func_proto bpf_perf_event_output_proto = { ...@@ -272,6 +277,33 @@ static const struct bpf_func_proto bpf_perf_event_output_proto = {
.arg5_type = ARG_CONST_STACK_SIZE, .arg5_type = ARG_CONST_STACK_SIZE,
}; };
static DEFINE_PER_CPU(struct pt_regs, bpf_pt_regs);
static u64 bpf_event_output(u64 r1, u64 r2, u64 flags, u64 r4, u64 size)
{
struct pt_regs *regs = this_cpu_ptr(&bpf_pt_regs);
perf_fetch_caller_regs(regs);
return bpf_perf_event_output((long)regs, r2, flags, r4, size);
}
static const struct bpf_func_proto bpf_event_output_proto = {
.func = bpf_event_output,
.gpl_only = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_CONST_MAP_PTR,
.arg3_type = ARG_ANYTHING,
.arg4_type = ARG_PTR_TO_STACK,
.arg5_type = ARG_CONST_STACK_SIZE,
};
const struct bpf_func_proto *bpf_get_event_output_proto(void)
{
return &bpf_event_output_proto;
}
static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id) static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
{ {
switch (func_id) { switch (func_id) {
......
...@@ -2039,6 +2039,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id) ...@@ -2039,6 +2039,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
return &bpf_redirect_proto; return &bpf_redirect_proto;
case BPF_FUNC_get_route_realm: case BPF_FUNC_get_route_realm:
return &bpf_get_route_realm_proto; return &bpf_get_route_realm_proto;
case BPF_FUNC_perf_event_output:
return bpf_get_event_output_proto();
default: default:
return sk_filter_func_proto(func_id); return sk_filter_func_proto(func_id);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment