eBPF runtime, symbol table, and probe framework for AxVisor Hypervisor.
axebpf provides tracing and dynamic probing infrastructure for AxVisor. It supports:
- Hypervisor-side probes (
hprobe/hretprobe) - Guest kernel probes (
guest-kprobe) - Static tracepoints (
tracepoint-support) - eBPF program loading/execution (
runtime)
All modules are #![no_std].
- Symbol lookup via
ksym(symbols) - Tracepoint manager with filter support (
tracepoint-support) - ELF loading and relocation via
aya-obj(runtime) - Event pipeline with RingBuf + fallback queue (
event) - Hprobe/Hretprobe coexistence on the same symbol (
hprobe) - Guest-kprobe in two modes:
Stage2Fault: mark guest code page non-executableBrkInject: patch guest instruction with BRK/INT3
- Stale BRK recovery after detach to reduce guest trap races
src/
lib.rs
platform.rs
symbols.rs
tracepoint.rs
tracepoints/
runtime.rs
maps.rs
map_ops.rs
event.rs
context.rs
attach.rs
helpers.rs
programs/
probe/
hprobe/
kprobe/
tests/
runtime_tests.rs
symbols_tests.rs
tracepoint_tests.rs
guest_addr_translate_tests.rs
guest_kprobe_manager_tests.rs
guest_kprobe_handler_tests.rs
hprobe_coexistence_tests.rs
hretprobe_event_tests.rs
Note: this is intentionally non-exhaustive. Use rg --files src tests for full file list.
| Feature | Description | Dependencies |
|---|---|---|
symbols |
Symbol table support | ksym |
tracepoint-support |
Tracepoint subsystem and static keys | symbols, tracepoint, tp-lexer, spin, static-keys |
runtime |
eBPF VM, ELF loader, maps, ringbuf pipeline | rbpf, kbpf-basic, aya-obj, hashbrown, spin, axalloc |
axhal |
Real kernel platform operations | axhal |
precompiled-ebpf |
Embed .o files from target/bpf |
none |
hprobe |
EL2 self-probing with breakpoints | tracepoint-support, kprobe |
guest-kprobe |
Guest kernel probing support | hprobe |
test-utils |
Extra test hooks/mocks | none |
Default features: symbols, tracepoint-support, runtime, axhal
[dependencies]
axebpf = { path = "modules/axebpf" }Current Cargo.toml inherits axalloc from workspace dependencies. If you copy this crate out of AxVisor without adapting dependency sources, cargo manifest resolution fails.
If you need standalone usage, either:
- Keep it in a workspace that provides
workspace.dependencies.axalloc, or - Replace inherited workspace dependency entries with explicit crate/git dependencies.
Call one of:
axebpf::init()for runtime/tracepoint setup without loading kallsymsaxebpf::init_with_symbols(kallsyms_blob, stext, etext)when kprobe symbol lookup is required
init_with_symbols loads symbol table first, then initializes tracepoint/runtime modules.
Guest-kprobe depends on VM integration hooks. Before attach, register hooks from your VMM side.
probe::kprobe::addr_translate::register_vm_ttbr1_hookprobe::kprobe::addr_translate::register_guest_pt_read_hook- One of:
probe::kprobe::addr_translate::register_gpa_to_hpa_hook(for translation chain), orprobe::kprobe::addr_translate::register_gva_to_hva_hook(direct translation shortcut)
probe::kprobe::manager::register_stage2_exec_hook(required forStage2Faultmode)
use axebpf::probe::kprobe::{
addr_translate,
manager::{self, KprobeMode},
handler,
};
// 1) Initialize subsystem once
manager::init();
// 2) Register integration hooks from VMM
addr_translate::register_vm_ttbr1_hook(vm_ttbr1_hook);
addr_translate::register_guest_pt_read_hook(guest_pt_read_hook);
addr_translate::register_gpa_to_hpa_hook(gpa_to_hpa_hook);
addr_translate::register_gva_to_hva_hook(gva_to_hva_hook); // optional if direct path is preferred
manager::register_stage2_exec_hook(stage2_exec_hook);
// 3) Attach probe
manager::attach(vm_id, gva, prog_id, false, KprobeMode::BrkInject)?;
// 4) In trap/exit path, dispatch events to handler
let guest_regs = [0u64; 8];
let _ = handler::handle_guest_brk(vm_id, pc, iss, &guest_regs);
let _ = handler::handle_stage2_exec_fault(vm_id, gpa, gva, true, &guest_regs);
// 5) Detach when finished
manager::detach(vm_id, gva)?;
# Ok::<(), &'static str>(())| Probe | Target | Mechanism | Feature |
|---|---|---|---|
| Hprobe | VMM function entry (EL2) | Breakpoint patching + single-step | hprobe |
| Hretprobe | VMM function return (EL2) | Return probe bookkeeping + breakpoint | hprobe |
| Guest Kprobe | Guest kernel (EL1) | Stage-2 fault or BRK injection | guest-kprobe |
| Tracepoint | VMM static points | Compile-time instrumentation | tracepoint-support |
event module provides a unified TraceEvent record (64 bytes):
- Producers: tracepoint / hprobe / guest-kprobe handlers
- Sink 1: RingBuf map (best effort)
- Sink 2: fallback queue (always keeps recent events for shell-side consumption)
Probe tags include:
tracepointhprobehretprobekprobekretprobe
Standard helper IDs include:
bpf_map_lookup_elembpf_map_update_elembpf_map_delete_elembpf_probe_readbpf_ktime_get_nsbpf_trace_printkbpf_get_smp_processor_id
Hypervisor-specific helper IDs include:
bpf_get_current_vm_idbpf_get_current_vcpu_idbpf_get_exit_reason
Commands below were checked in this repository state.
# Minimal practical set for runtime development
cargo check --no-default-features --features "symbols,tracepoint-support,runtime"
# Full default feature check
cargo check# guest-kprobe handler path
cargo test --no-default-features \
--features "symbols,tracepoint-support,runtime,hprobe,guest-kprobe,test-utils" \
--test guest_kprobe_handler_tests --no-run
# hprobe entry/ret coexistence
cargo test --no-default-features \
--features "symbols,tracepoint-support,runtime,hprobe,test-utils" \
--test hprobe_coexistence_tests --no-runtests/runtime_tests.rs loads object files from target/bpf/*.o via include_bytes!. Make sure these files exist before building that test target.
The precompiled-ebpf feature in src/programs/bytecode.rs also expects prebuilt objects under target/bpf.
GPL-3.0-or-later OR Apache-2.0