BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next 0/5] bpf: Unwinding via r3
@ 2026-10-18  1:02 Alexei Starovoitov
  2026-10-18  1:02 ` [PATCH bpf-next 1/5] bpf: Support unwinding " Alexei Starovoitov
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Alexei Starovoitov @ 2026-10-18  1:02 UTC (permalink / raw)
  To: bpf; +Cc: daniel, andrii, eddyz87, memxor

From: Alexei Starovoitov <ast@anthropic.com>

This is the r3 alternative from the discussion of v12 of Yonghong's series
[1] as patches, with x86-64 and arm64 JITs and selftests.

1. What is the problem?

A rust panic or a C++ exception has to run Drop impls or destructors of
every frame it passes through. bpf_throw() discards the frames, so the
verifier doesn't let a frame that owns a lock or a reference throw. In rust
every index and every unwrap() can panic.

2. Is it worth solving?

Without it rust-bpf [2] drops all landing pads and a panic is bpf_throw().
A prog that can panic with a guard held doesn't load.

3. Is there a simpler way?

[1] keeps the normal path free of unwind code. llvm emits a table, libbpf
passes it to the kernel, bpf_unwind() walks the stack and rewrites return
addresses, and the verifier models hidden edges from calls to pads. That's
1400 lines in the kernel, with new uapi and two kfuncs, and 440 lines in
libbpf.

Here llvm emits plain insns [3]:

  ret                            r3 = 0; exit
  invoke foo unwind pad          call foo; if r3 != 0 goto pad
  resume                         r0 = 0; r3 = 1; exit

Pads are ordinary code, so the verifier part is 96 lines in patch 1.
The price is a branch after a call that may unwind. Patches 2 and 3 take it
off the normal path in the JITs without telling the verifier. 360 lines
with them.

4. Will the api and the layers last?

No uapi, no kfuncs, no changes in libbpf and other loaders.
r3 and BTF decl_tag "unwind" become an ABI between llvm and the kernel.
The source level entry point is _Unwind_RaiseException() of the Itanium
ABI. It's what the runtimes of rust and C++ call on other architectures.

5. Is it good taste?

Every frame returns through its own epilogue. The only question is where it
returns to. That's one bit.

It's not specific to rust. A C++ prog with throw, catch and destructors
compiles, loads and runs. It's a selftest in patch 5.

Since the sketches in [1]:
- bpf_unwind() is gone. _Unwind_RaiseException() starts an unwind.
- llvm applies the convention to functions with uwtable only, so C progs
  are not affected.
- JITs opt in. A JIT that loses r3 would skip a pad.
- A subprog with the tag has to exit with a scalar in r3.
- A callback that doesn't set r3 was hitting verifier_bug().
- The extable lookup is search_bpf_extables().
- 'Functions end with exit' was not quite right. A function can still end
  with a call of a noreturn function that cannot unwind, like bpf_throw().
  rust-bpf adds 'exit' after it.

Tested in qemu only, x86-64 and arm64 with and without pointer
authentication: the selftests, C, C++ and rust progs built with [3],
with and without bpf_jit_harden=2. test_progs was run on x86-64. On arm64
the same objects were loaded and run by a small loader, and __jited
patterns were matched against the JIT output by a script.

[1] https://lore.kernel.org/bpf/20261017025129.1914859-1-yonghong.song@linux.dev/
[2] https://github.com/4ast/rust-bpf
[3] https://github.com/llvm/llvm-project/pull/233140

Alexei Starovoitov (5):
  bpf: Support unwinding via r3
  bpf, x86: Replace 'if r3 != 0 goto pad' after a call with an extable
    entry
  bpf, arm64: Support unwinding via r3
  selftests/bpf: Add tests for unwinding via r3
  selftests/bpf: Add a C++ prog with exceptions

 arch/arm64/net/bpf_jit.h                      |   2 +
 arch/arm64/net/bpf_jit_comp.c                 | 110 +++
 arch/x86/net/bpf_jit_comp.c                   | 107 ++-
 include/linux/bpf.h                           |   1 +
 include/linux/bpf_verifier.h                  |   5 +-
 include/linux/filter.h                        |  11 +
 kernel/bpf/backtrack.c                        |  10 +-
 kernel/bpf/core.c                             |  53 ++
 kernel/bpf/fixups.c                           |   1 +
 kernel/bpf/liveness.c                         |   7 +-
 kernel/bpf/verifier.c                         |  66 +-
 tools/testing/selftests/bpf/Makefile.skel     |  11 +
 .../selftests/bpf/prog_tests/unwind_attach.c  |  67 ++
 .../selftests/bpf/prog_tests/unwind_cxx.c     |  76 ++
 .../selftests/bpf/prog_tests/verifier.c       |   2 +
 .../selftests/bpf/progs/unwind_attach.c       |  32 +
 .../selftests/bpf/progs/unwind_cxx.cpp        | 117 +++
 .../selftests/bpf/progs/verifier_unwind.c     | 759 ++++++++++++++++++
 18 files changed, 1427 insertions(+), 10 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/prog_tests/unwind_attach.c
 create mode 100644 tools/testing/selftests/bpf/prog_tests/unwind_cxx.c
 create mode 100644 tools/testing/selftests/bpf/progs/unwind_attach.c
 create mode 100644 tools/testing/selftests/bpf/progs/unwind_cxx.cpp
 create mode 100644 tools/testing/selftests/bpf/progs/verifier_unwind.c


base-commit: c058636f788f8751e419b407206516280226e568
-- 
2.55.0


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2026-10-18  1:48 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-18  1:02 [PATCH bpf-next 0/5] bpf: Unwinding via r3 Alexei Starovoitov
2026-10-18  1:02 ` [PATCH bpf-next 1/5] bpf: Support unwinding " Alexei Starovoitov
2026-10-18  1:32   ` sashiko-bot
2026-10-18  1:48   ` bot+bpf-ci
2026-10-18  1:02 ` [PATCH bpf-next 2/5] bpf, x86: Replace 'if r3 != 0 goto pad' after a call with an extable entry Alexei Starovoitov
2026-10-18  1:28   ` sashiko-bot
2026-10-18  1:02 ` [PATCH bpf-next 3/5] bpf, arm64: Support unwinding via r3 Alexei Starovoitov
2026-10-18  1:34   ` sashiko-bot
2026-10-18  1:02 ` [PATCH bpf-next 4/5] selftests/bpf: Add tests for " Alexei Starovoitov
2026-10-18  1:38   ` bot+bpf-ci
2026-10-18  1:02 ` [PATCH bpf-next 5/5] selftests/bpf: Add a C++ prog with exceptions Alexei Starovoitov
2026-10-18  1:38   ` bot+bpf-ci
2026-10-18  1:31 ` [PATCH bpf-next 0/5] bpf: Unwinding via r3 Kumar Kartikeya Dwivedi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox