mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 14:16:33 +00:00
feat(ebpf):[WIP] add eBPF support (#948)
* feat(kprobe): Add basic kprobe support for x86_64 * feat: add ebpf support (#912) - 实现bpf()一部分命令,包括几种基本map,相关的helper函数 - 实现部分perf相关的数据结构 - 暂时为文件实现简单mmap - 实现一个使用kprobe统计syscall 调用次数的ebpf程序 对eBPF支持程度(基本): - 简单的eBPF程序(没有指定特殊的Map) - 使用内核已经实现的Map的eBPF程序 - 可以和kprobe配合使用 - 内核Map相关的接口定义已经实现,添加新的Map较为简单 不支持的功能: - 区分不同的eBPF程序类型(Network/Cgroup)并限定可调用的helper函数集 - 与内核其它跟踪机制配合(tracepoint) - 其它helper和Map todo - [ ] 修改mmap,需要讨论,因为这个和块缓存层相关 - [x] 添加文档 - [x] 修复可能的错误 - [x] 增加rbpf版本信息 * feat: add /sys/devices/system/cpu/possible file * feat: add /sys/devices/system/cpu/online
This commit is contained in:
@ -0,0 +1,6 @@
|
||||
[build]
|
||||
target-dir = "../target"
|
||||
target = "bpfel-unknown-none"
|
||||
|
||||
[unstable]
|
||||
build-std = ["core"]
|
@ -0,0 +1,2 @@
|
||||
[editor]
|
||||
workspace-lsp-roots = []
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.cargo.target": "bpfel-unknown-none",
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
}
|
4
user/apps/test_ebpf/syscall_ebpf/syscall_ebpf-ebpf/.vscode/settings.json
vendored
Normal file
4
user/apps/test_ebpf/syscall_ebpf/syscall_ebpf-ebpf/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"rust-analyzer.cargo.target": "bpfel-unknown-none",
|
||||
"rust-analyzer.checkOnSave.allTargets": false
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
[package]
|
||||
name = "syscall_ebpf-ebpf"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
aya-ebpf = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/aya.git", rev = "3d57d35" }
|
||||
aya-log-ebpf = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/aya.git", rev = "3d57d35" }
|
||||
|
||||
syscall_ebpf-common = { path = "../syscall_ebpf-common" }
|
||||
|
||||
[[bin]]
|
||||
name = "syscall_ebpf"
|
||||
path = "src/main.rs"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 3
|
||||
debug = false
|
||||
debug-assertions = false
|
||||
overflow-checks = false
|
||||
lto = true
|
||||
panic = "abort"
|
||||
incremental = false
|
||||
codegen-units = 1
|
||||
rpath = false
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
panic = "abort"
|
||||
codegen-units = 1
|
||||
|
||||
[workspace]
|
||||
members = []
|
@ -0,0 +1,13 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2024-07-23"
|
||||
# The source code of rustc, provided by the rust-src component, is needed for
|
||||
# building eBPF programs.
|
||||
components = [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"rust-docs",
|
||||
"rust-src",
|
||||
"rust-std",
|
||||
"rustc",
|
||||
"rustfmt",
|
||||
]
|
@ -0,0 +1,44 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use aya_ebpf::{macros::kprobe, programs::ProbeContext};
|
||||
use aya_ebpf::macros::map;
|
||||
use aya_ebpf::maps::HashMap;
|
||||
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();
|
||||
}
|
||||
}
|
||||
info!(&ctx, "invoke syscall {}", syscall_num);
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
#[map] //
|
||||
static SYSCALL_LIST: HashMap<u32, u32> =
|
||||
HashMap::<u32, u32>::with_max_entries(1024, 0);
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
unsafe { core::hint::unreachable_unchecked() }
|
||||
}
|
Reference in New Issue
Block a user