mbox series

[v5,bpf-next,0/9] bpf: Add gen_epilogue to bpf_verifier_ops

Message ID 20240829210833.388152-1-martin.lau@linux.dev (mailing list archive)
Headers show
Series bpf: Add gen_epilogue to bpf_verifier_ops | expand

Message

Martin KaFai Lau Aug. 29, 2024, 9:08 p.m. UTC
From: Martin KaFai Lau <martin.lau@kernel.org>

This set allows the subsystem to patch codes before BPF_EXIT.
The verifier ops, .gen_epilogue, is added for this purpose.
One of the use case will be in the bpf qdisc, the bpf qdisc
subsystem can ensure the skb->dev is in the correct value.
The bpf qdisc subsystem can either inline fixing it in the
epilogue or call another kernel function to handle it (e.g. drop)
in the epilogue. Another use case could be in bpf_tcp_ca.c to
enforce snd_cwnd has valid value (e.g. positive value).

v5:
 * Removed the skip_cnt argument from adjust_jmp_off() in patch 2.
   Instead, reuse the delta argument and skip
   the [tgt_idx, tgt_idx + delta) instructions.
 * Added a BPF_JMP32_A macro in patch 3.
 * Removed pro_epilogue_subprog.c in patch 6.
   The pro_epilogue_kfunc.c has covered the subprog case.
   Renamed the file pro_epilogue_kfunc.c to pro_epilogue.c.
   Some of the SEC names and function names are changed
   accordingly (mainly shorten them by removing the _kfunc suffix).
 * Added comments to explain the tail_call result in patch 7.
 * Fixed the following bpf CI breakages. I ran it in CI
   manually to confirm:
   https://github.com/kernel-patches/bpf/actions/runs/10590714532
 * s390 zext added "w3 = w3". Adjusted the test to
   use all ALU64 and BPF_DW to avoid zext.
   Also changed the "int a" in the "struct st_ops_args" to "u64 a".
 * llvm17 does not take:
       *(u64 *)(r1 +0) = 0;
   so it is changed to:
       r3 = 0;
       *(u64 *)(r1 +0) = r3;

v4:
 * Fixed a bug in the memcpy in patch 3
   The size in the memcpy should be
   epilogue_cnt * sizeof(*epilogue_buf)

v3:
 * Moved epilogue_buf[16] to env.
   Patch 1 is added to move the existing insn_buf[16] to env.
 * Fixed a case that the bpf prog has a BPF_JMP that goes back
   to the first instruction of the main prog.
   The jump back to 1st insn case also applies to the prologue.
   Patch 2 is added to handle it.
 * If the bpf main prog has multiple BPF_EXIT, use a BPF_JA
   to goto the earlier patched epilogue.
   Note that there are (BPF_JMP32 | BPF_JA) vs (BPF_JMP | BPF_JA)
   details in the patch 3 commit message.
 * There are subtle changes in patch 3, so I reset the Reviewed-by.
 * Added patch 8 and patch 9 to cover the changes in patch 2 and patch 3.
 * Dropped the kfunc call from pro/epilogue and its selftests.

v2:
 * Remove the RFC tag. Keep the ordering at where .gen_epilogue is
   called in the verifier relative to the check_max_stack_depth().
   This will be consistent with the other extra stack_depth
   usage like optimize_bpf_loop().
 * Use __xlated check provided by the test_loader to
   check the patched instructions after gen_pro/epilogue (Eduard).
 * Added Patch 3 by Eduard (Thanks!).

Eduard Zingerman (1):
  selftests/bpf: attach struct_ops maps before test prog runs

Martin KaFai Lau (8):
  bpf: Move insn_buf[16] to bpf_verifier_env
  bpf: Adjust BPF_JMP that jumps to the 1st insn of the prologue
  bpf: Add gen_epilogue to bpf_verifier_ops
  bpf: Export bpf_base_func_proto
  selftests/bpf: Test gen_prologue and gen_epilogue
  selftests/bpf: Add tailcall epilogue test
  selftests/bpf: A pro/epilogue test when the main prog jumps back to
    the 1st insn
  selftests/bpf: Test epilogue patching when the main prog has multiple
    BPF_EXIT

 include/linux/bpf.h                           |   2 +
 include/linux/bpf_verifier.h                  |   4 +
 include/linux/filter.h                        |  10 +
 kernel/bpf/helpers.c                          |   1 +
 kernel/bpf/verifier.c                         |  67 +++++-
 .../selftests/bpf/bpf_testmod/bpf_testmod.c   | 190 ++++++++++++++++++
 .../selftests/bpf/bpf_testmod/bpf_testmod.h   |  11 +
 .../bpf/bpf_testmod/bpf_testmod_kfunc.h       |   6 +
 .../selftests/bpf/prog_tests/pro_epilogue.c   |  60 ++++++
 .../selftests/bpf/progs/epilogue_exit.c       |  82 ++++++++
 .../selftests/bpf/progs/epilogue_tailcall.c   |  58 ++++++
 .../selftests/bpf/progs/pro_epilogue.c        | 154 ++++++++++++++
 .../bpf/progs/pro_epilogue_goto_start.c       | 149 ++++++++++++++
 tools/testing/selftests/bpf/test_loader.c     |  27 +++
 14 files changed, 813 insertions(+), 8 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
 create mode 100644 tools/testing/selftests/bpf/progs/epilogue_exit.c
 create mode 100644 tools/testing/selftests/bpf/progs/epilogue_tailcall.c
 create mode 100644 tools/testing/selftests/bpf/progs/pro_epilogue.c
 create mode 100644 tools/testing/selftests/bpf/progs/pro_epilogue_goto_start.c

Comments

patchwork-bot+netdevbpf@kernel.org Aug. 30, 2024, 1:30 a.m. UTC | #1
Hello:

This series was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Thu, 29 Aug 2024 14:08:22 -0700 you wrote:
> From: Martin KaFai Lau <martin.lau@kernel.org>
> 
> This set allows the subsystem to patch codes before BPF_EXIT.
> The verifier ops, .gen_epilogue, is added for this purpose.
> One of the use case will be in the bpf qdisc, the bpf qdisc
> subsystem can ensure the skb->dev is in the correct value.
> The bpf qdisc subsystem can either inline fixing it in the
> epilogue or call another kernel function to handle it (e.g. drop)
> in the epilogue. Another use case could be in bpf_tcp_ca.c to
> enforce snd_cwnd has valid value (e.g. positive value).
> 
> [...]

Here is the summary with links:
  - [v5,bpf-next,1/9] bpf: Move insn_buf[16] to bpf_verifier_env
    https://git.kernel.org/bpf/bpf-next/c/6f606ffd6dd7
  - [v5,bpf-next,2/9] bpf: Adjust BPF_JMP that jumps to the 1st insn of the prologue
    https://git.kernel.org/bpf/bpf-next/c/d5c47719f244
  - [v5,bpf-next,3/9] bpf: Add gen_epilogue to bpf_verifier_ops
    https://git.kernel.org/bpf/bpf-next/c/169c31761c8d
  - [v5,bpf-next,4/9] bpf: Export bpf_base_func_proto
    https://git.kernel.org/bpf/bpf-next/c/866d571e6201
  - [v5,bpf-next,5/9] selftests/bpf: attach struct_ops maps before test prog runs
    https://git.kernel.org/bpf/bpf-next/c/a0dbf6d0b21e
  - [v5,bpf-next,6/9] selftests/bpf: Test gen_prologue and gen_epilogue
    https://git.kernel.org/bpf/bpf-next/c/47e69431b57a
  - [v5,bpf-next,7/9] selftests/bpf: Add tailcall epilogue test
    https://git.kernel.org/bpf/bpf-next/c/b191b0fd7400
  - [v5,bpf-next,8/9] selftests/bpf: A pro/epilogue test when the main prog jumps back to the 1st insn
    https://git.kernel.org/bpf/bpf-next/c/42fdbbde6cf4
  - [v5,bpf-next,9/9] selftests/bpf: Test epilogue patching when the main prog has multiple BPF_EXIT
    https://git.kernel.org/bpf/bpf-next/c/cada0bdcc471

You are awesome, thank you!