[bpf-next,0/2] bpf: Allow access to perf sample data (v2)

Message ID 20221220220144.4016213-1-namhyung@kernel.org
Headers
Series bpf: Allow access to perf sample data (v2) |

Message

Namhyung Kim Dec. 20, 2022, 10:01 p.m. UTC
  Hello,

I'm working on perf event sample filtering using BPF.  To do that BPF needs
to access perf sample data and return 0 or 1 to drop or keep the samples.

Changes in v2)
 - reuse perf_prepare_sample() instead of adding new bpf_prepare_sample()
 - drop bpf_perf_event_read_helper() and access ctx->data directly using
   bpf_cast_to_kern_ctx().

v1) https://lore.kernel.org/r/20221101052340.1210239-1-namhyung@kernel.org

Thanks to bpf_cast_to_kern_ctx() kfunc, it can easily access the sample data
now.  But the problem is that perf didn't populate the sample data at the time
it calls bpf_prog_run().  I changed the code to simply call perf_prepare_sample
function before calling the BPF program.

But it also checks if the BPF calls bpf_cast_to_kern_ctx() since calling
perf_prepare_sample() is unnecessary if the BPF doesn't access to the sample.
The perf_prepare_sample() was only called right before putting it to the perf
ring buffer.  I think I can add a little optimization not to fill already set
fields as it can be called twice now.  It can be a separate patch for perf.

Another issue is that perf sample data only has selected fields according to
the sample_type flags in the perf_event_attr.  Accessing other fields can
result in uninitialized read.  I'm not sure how much it's gonna be a problem
but it seems there's no way to prevent it completely.  So properly written
programs should check the sample_type flags first when reading the sample data.

The code is available at 'bpf/perf-sample-v2' branch in

  git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git

Thanks,
Namhyung


Namhyung Kim (2):
  bpf/perf: Call perf_prepare_sample() before bpf_prog_run()
  selftests/bpf: Add perf_event_read_sample test cases

 include/linux/bpf.h                           |   1 +
 kernel/bpf/verifier.c                         |   1 +
 kernel/events/core.c                          |   3 +
 .../selftests/bpf/prog_tests/perf_sample.c    | 167 ++++++++++++++++++
 .../selftests/bpf/progs/test_perf_sample.c    |  33 ++++
 5 files changed, 205 insertions(+)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/perf_sample.c
 create mode 100644 tools/testing/selftests/bpf/progs/test_perf_sample.c