aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-03-08 02:22:34 +0100
committerDaniel Borkmann <daniel@iogearbox.net>2018-03-08 02:22:35 +0100
commit12ef9bda06a5536fc377bab636074848799d7749 (patch)
tree822b9bb7680c97b84f98f8d471b297637048d473 /kernel
parentip6mr: remove synchronize_rcu() in favor of SOCK_RCU_FREE (diff)
parentsamples/bpf: add example to test reading address (diff)
downloadlinux-dev-12ef9bda06a5536fc377bab636074848799d7749.tar.xz
linux-dev-12ef9bda06a5536fc377bab636074848799d7749.zip
Merge branch 'bpf-perf-sample-addr'
Teng Qin says: ==================== These patches add support that allows bpf programs attached to perf events to read the address values recorded with the perf events. These values are requested by specifying sample_type with PERF_SAMPLE_ADDR when calling perf_event_open(). The main motivation for these changes is to support building memory or lock access profiling and tracing tools. For example on Intel CPUs, the recorded address values for supported memory or lock access perf events would be the access or lock target addresses from PEBS buffer. Such information would be very valuable for building tools that help understand memory access or lock acquire pattern. ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/bpf_trace.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index c0a9e310d715..c634e093951f 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -726,8 +726,7 @@ const struct bpf_prog_ops tracepoint_prog_ops = {
static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type,
struct bpf_insn_access_aux *info)
{
- const int size_sp = FIELD_SIZEOF(struct bpf_perf_event_data,
- sample_period);
+ const int size_u64 = sizeof(u64);
if (off < 0 || off >= sizeof(struct bpf_perf_event_data))
return false;
@@ -738,8 +737,13 @@ static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type
switch (off) {
case bpf_ctx_range(struct bpf_perf_event_data, sample_period):
- bpf_ctx_record_field_size(info, size_sp);
- if (!bpf_ctx_narrow_access_ok(off, size, size_sp))
+ bpf_ctx_record_field_size(info, size_u64);
+ if (!bpf_ctx_narrow_access_ok(off, size, size_u64))
+ return false;
+ break;
+ case bpf_ctx_range(struct bpf_perf_event_data, addr):
+ bpf_ctx_record_field_size(info, size_u64);
+ if (!bpf_ctx_narrow_access_ok(off, size, size_u64))
return false;
break;
default:
@@ -766,6 +770,14 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type,
bpf_target_off(struct perf_sample_data, period, 8,
target_size));
break;
+ case offsetof(struct bpf_perf_event_data, addr):
+ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
+ data), si->dst_reg, si->src_reg,
+ offsetof(struct bpf_perf_event_data_kern, data));
+ *insn++ = BPF_LDX_MEM(BPF_DW, si->dst_reg, si->dst_reg,
+ bpf_target_off(struct perf_sample_data, addr, 8,
+ target_size));
+ break;
default:
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern,
regs), si->dst_reg, si->src_reg,