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:
linfeng
2024-10-25 15:59:57 +08:00
committed by GitHub
parent 80c9e8f8f0
commit fae6e9ade4
126 changed files with 29529 additions and 62 deletions

View File

@ -0,0 +1,6 @@
[build]
target-dir = "../target"
target = "bpfel-unknown-none"
[unstable]
build-std = ["core"]

View File

@ -0,0 +1,2 @@
[editor]
workspace-lsp-roots = []

View File

@ -0,0 +1,4 @@
{
"rust-analyzer.cargo.target": "bpfel-unknown-none",
"rust-analyzer.checkOnSave.allTargets": false
}

View File

@ -0,0 +1,4 @@
{
"rust-analyzer.cargo.target": "bpfel-unknown-none",
"rust-analyzer.checkOnSave.allTargets": false
}

View File

@ -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 = []

View File

@ -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",
]

View File

@ -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() }
}