mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-19 09:06:32 +00:00
feat(ebpf): support Aya framework. (#1070)
* feat(ebpf): support Aya framework. 1. fix the rbpf bug 2. use new Aya template 3. add kprobe related device files and attributes to sysfs --- Signed-off-by: chenlinfeng <chenlinfeng25@outlook.com>
This commit is contained in:
12
user/apps/syscall_ebpf/syscall_ebpf-ebpf/.cargo/config.toml
Normal file
12
user/apps/syscall_ebpf/syscall_ebpf-ebpf/.cargo/config.toml
Normal file
@ -0,0 +1,12 @@
|
||||
# We have this so that one doesn't need to manually pass
|
||||
# --target=bpfel-unknown-none -Z build-std=core when running cargo
|
||||
# check/build/doc etc.
|
||||
#
|
||||
# NB: this file gets loaded only if you run cargo from this directory, it's
|
||||
# ignored if you run from the workspace root. See
|
||||
# https://doc.rust-lang.org/cargo/reference/config.html#hierarchical-structure
|
||||
[build]
|
||||
target = ["bpfeb-unknown-none", "bpfel-unknown-none"]
|
||||
|
||||
[unstable]
|
||||
build-std = ["core"]
|
17
user/apps/syscall_ebpf/syscall_ebpf-ebpf/Cargo.toml
Normal file
17
user/apps/syscall_ebpf/syscall_ebpf-ebpf/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "syscall_ebpf-ebpf"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
syscall_ebpf-common = { path = "../syscall_ebpf-common" }
|
||||
|
||||
aya-ebpf = { workspace = true }
|
||||
aya-log-ebpf = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
which = { workspace = true }
|
||||
|
||||
[[bin]]
|
||||
name = "syscall_ebpf"
|
||||
path = "src/main.rs"
|
17
user/apps/syscall_ebpf/syscall_ebpf-ebpf/build.rs
Normal file
17
user/apps/syscall_ebpf/syscall_ebpf-ebpf/build.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use which::which;
|
||||
|
||||
/// Building this crate has an undeclared dependency on the `bpf-linker` binary. This would be
|
||||
/// better expressed by [artifact-dependencies][bindeps] but issues such as
|
||||
/// https://github.com/rust-lang/cargo/issues/12385 make their use impractical for the time being.
|
||||
///
|
||||
/// This file implements an imperfect solution: it causes cargo to rebuild the crate whenever the
|
||||
/// mtime of `which bpf-linker` changes. Note that possibility that a new bpf-linker is added to
|
||||
/// $PATH ahead of the one used as the cache key still exists. Solving this in the general case
|
||||
/// would require rebuild-if-changed-env=PATH *and* rebuild-if-changed={every-directory-in-PATH}
|
||||
/// which would likely mean far too much cache invalidation.
|
||||
///
|
||||
/// [bindeps]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html?highlight=feature#artifact-dependencies
|
||||
fn main() {
|
||||
let bpf_linker = which("bpf-linker").unwrap();
|
||||
println!("cargo:rerun-if-changed={}", bpf_linker.to_str().unwrap());
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "nightly"
|
||||
components = ["rust-src"]
|
3
user/apps/syscall_ebpf/syscall_ebpf-ebpf/src/lib.rs
Normal file
3
user/apps/syscall_ebpf/syscall_ebpf-ebpf/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
||||
#![no_std]
|
||||
|
||||
// This file exists to enable the library target.
|
50
user/apps/syscall_ebpf/syscall_ebpf-ebpf/src/main.rs
Normal file
50
user/apps/syscall_ebpf/syscall_ebpf-ebpf/src/main.rs
Normal file
@ -0,0 +1,50 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use aya_ebpf::{
|
||||
helpers::bpf_ktime_get_ns,
|
||||
macros::{kprobe, map},
|
||||
maps::HashMap,
|
||||
programs::ProbeContext,
|
||||
};
|
||||
use aya_log_ebpf::info;
|
||||
|
||||
#[kprobe]
|
||||
pub fn syscall_ebpf(ctx: ProbeContext) -> u32 {
|
||||
try_syscall_ebpf(ctx).unwrap_or_else(|ret| ret)
|
||||
}
|
||||
|
||||
fn try_syscall_ebpf(ctx: ProbeContext) -> Result<u32, u32> {
|
||||
let pt_regs = unsafe { &*ctx.regs };
|
||||
// first arg -> rdi
|
||||
// second arg -> rsi
|
||||
// third arg -> rdx
|
||||
// four arg -> rcx
|
||||
let syscall_num = pt_regs.rsi as usize;
|
||||
if syscall_num != 1 {
|
||||
unsafe {
|
||||
if let Some(v) = SYSCALL_LIST.get(&(syscall_num as u32)) {
|
||||
let new_v = *v + 1;
|
||||
SYSCALL_LIST
|
||||
.insert(&(syscall_num as u32), &new_v, 0)
|
||||
.unwrap();
|
||||
} else {
|
||||
SYSCALL_LIST.insert(&(syscall_num as u32), &1, 0).unwrap();
|
||||
}
|
||||
}
|
||||
let time = unsafe { bpf_ktime_get_ns() };
|
||||
info!(&ctx, "[{}] invoke syscall {}", time, syscall_num);
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[map]
|
||||
static SYSCALL_LIST: HashMap<u32, u32> = HashMap::<u32, u32>::with_max_entries(1024, 0);
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
// we need use this because the verifier will forbid loop
|
||||
unsafe { core::hint::unreachable_unchecked() }
|
||||
// loop{}
|
||||
}
|
Reference in New Issue
Block a user