Skip to content

Commit 72423f9

Browse files
authored
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 <[email protected]>
1 parent c09af90 commit 72423f9

File tree

53 files changed

+849
-511
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+849
-511
lines changed

kernel/crates/rbpf/src/interpreter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,9 +660,9 @@ pub fn execute_program(
660660
// Save the callee saved registers
661661
pre_stack.save_registers(&reg[6..=9]);
662662
// Save the return address
663-
pre_stack.save_return_address(insn_ptr as u16);
663+
pre_stack.save_return_address(insn_ptr as u64);
664664
// save the stack pointer
665-
pre_stack.save_sp(reg[10] as u16);
665+
pre_stack.save_sp(reg[10]);
666666
let mut stack = StackFrame::new();
667667
log::trace!("BPF TO BPF CALL: new pc: {} + {} = {}",insn_ptr ,insn.imm,insn_ptr + insn.imm as usize);
668668
reg[10] = stack.as_ptr() as u64 + stack.len() as u64;
@@ -695,7 +695,7 @@ pub fn execute_program(
695695
// Restore the return address
696696
insn_ptr = stack.get_return_address() as usize;
697697
// Restore the stack pointer
698-
reg[10] = stack.get_sp() as u64;
698+
reg[10] = stack.get_sp();
699699
log::trace!("EXIT: new pc: {}", insn_ptr);
700700
}
701701
}

kernel/crates/rbpf/src/stack.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::{ebpf::STACK_SIZE, vec, Vec};
22

33
pub struct StackFrame {
4-
return_address: u16,
4+
return_address: u64,
55
saved_registers: [u64; 4],
6-
sp: u16,
6+
sp: u64,
77
frame: Vec<u8>,
88
}
99

@@ -54,22 +54,22 @@ impl StackFrame {
5454
}
5555

5656
/// Save the return address
57-
pub fn save_return_address(&mut self, address: u16) {
57+
pub fn save_return_address(&mut self, address: u64) {
5858
self.return_address = address;
5959
}
6060

6161
/// Get the return address
62-
pub fn get_return_address(&self) -> u16 {
62+
pub fn get_return_address(&self) -> u64 {
6363
self.return_address
6464
}
6565

6666
/// Save the stack pointer
67-
pub fn save_sp(&mut self, sp: u16) {
67+
pub fn save_sp(&mut self, sp: u64) {
6868
self.sp = sp;
6969
}
7070

7171
/// Get the stack pointer
72-
pub fn get_sp(&self) -> u16 {
72+
pub fn get_sp(&self) -> u64 {
7373
self.sp
7474
}
7575
}

kernel/src/arch/x86_64/mm/fault.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,10 @@ impl X86_64MMArch {
267267
});
268268
} else {
269269
log::error!(
270-
"No mapped vma, error_code: {:#b}, address: {:#x}",
270+
"No mapped vma, error_code: {:#b}, address: {:#x}, flags: {:?}",
271271
error_code,
272272
address.data(),
273+
flags
273274
);
274275
let pid = ProcessManager::current_pid();
275276
let mut info =

kernel/src/bpf/helper/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pub const HELPER_MAP_LOOKUP_ELEM: u32 = 1;
22
pub const HELPER_MAP_UPDATE_ELEM: u32 = 2;
33
pub const HELPER_MAP_DELETE_ELEM: u32 = 3;
4+
pub const HELPER_KTIME_GET_NS: u32 = 5;
45
pub const HELPER_MAP_FOR_EACH_ELEM: u32 = 164;
56
pub const HELPER_MAP_LOOKUP_PERCPU_ELEM: u32 = 195;
67
pub const HELPER_PERF_EVENT_OUTPUT: u32 = 25;

kernel/src/bpf/helper/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::bpf::map::{BpfCallBackFn, BpfMap};
66
use crate::include::bindings::linux_bpf::BPF_F_CURRENT_CPU;
77
use crate::libs::lazy_init::Lazy;
88
use crate::smp::core::smp_get_processor_id;
9+
use crate::time::Instant;
910
use alloc::{collections::BTreeMap, sync::Arc};
1011
use core::ffi::c_void;
1112
use system_error::SystemError;
@@ -300,6 +301,10 @@ pub fn map_peek_elem(map: &Arc<BpfMap>, value: &mut [u8]) -> Result<()> {
300301
value
301302
}
302303

304+
pub fn bpf_ktime_get_ns() -> u64 {
305+
(Instant::now().total_micros() * 1000) as u64
306+
}
307+
303308
pub static BPF_HELPER_FUN_SET: Lazy<BTreeMap<u32, RawBPFHelperFn>> = Lazy::new();
304309

305310
/// Initialize the helper functions.
@@ -311,6 +316,7 @@ pub fn init_helper_functions() {
311316
map.insert(HELPER_MAP_LOOKUP_ELEM, define_func!(raw_map_lookup_elem));
312317
map.insert(HELPER_MAP_UPDATE_ELEM, define_func!(raw_map_update_elem));
313318
map.insert(HELPER_MAP_DELETE_ELEM, define_func!(raw_map_delete_elem));
319+
map.insert(HELPER_KTIME_GET_NS, define_func!(bpf_ktime_get_ns));
314320
map.insert(
315321
HELPER_MAP_FOR_EACH_ELEM,
316322
define_func!(raw_map_for_each_elem),

kernel/src/bpf/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub fn bpf(cmd: bpf_cmd, attr: &bpf_attr) -> Result<usize> {
3333
// Program related commands
3434
bpf_cmd::BPF_PROG_LOAD => prog::bpf_prog_load(attr),
3535
// Object creation commands
36-
bpf_cmd::BPF_BTF_LOAD => {
36+
bpf_cmd::BPF_BTF_LOAD | bpf_cmd::BPF_LINK_CREATE | bpf_cmd::BPF_OBJ_GET_INFO_BY_FD => {
3737
error!("bpf cmd {:?} not implemented", cmd);
3838
return Err(SystemError::ENOSYS);
3939
}

kernel/src/driver/base/device/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ pub enum DeviceType {
310310
PlatformDev,
311311
Char,
312312
Pci,
313+
Other,
313314
}
314315

315316
/// @brief: 设备标识符类型

kernel/src/driver/base/init.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub fn driver_init() -> Result<(), SystemError> {
2121
platform_bus_init()?;
2222
serio_bus_init()?;
2323
CpuDeviceManager::init()?;
24-
2524
// 至此,已完成设备驱动模型的初始化
2625
return Ok(());
2726
}

kernel/src/filesystem/procfs/mod.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,31 @@ impl ProcFS {
394394
} else {
395395
panic!("create ksmg error");
396396
}
397-
397+
// 这个文件是用来欺骗Aya框架识别内核版本
398+
/* On Ubuntu LINUX_VERSION_CODE doesn't correspond to info.release,
399+
* but Ubuntu provides /proc/version_signature file, as described at
400+
* https://ubuntu.com/kernel, with an example contents below, which we
401+
* can use to get a proper LINUX_VERSION_CODE.
402+
*
403+
* Ubuntu 5.4.0-12.15-generic 5.4.8
404+
*
405+
* In the above, 5.4.8 is what kernel is actually expecting, while
406+
* uname() call will return 5.4.0 in info.release.
407+
*/
408+
let binding = inode.create("version_signature", FileType::File, ModeType::S_IRUGO);
409+
if let Ok(version_signature) = binding {
410+
let version_signature = version_signature
411+
.as_any_ref()
412+
.downcast_ref::<LockedProcFSInode>()
413+
.unwrap();
414+
version_signature.0.lock().fdata.ftype = ProcFileType::Default;
415+
version_signature.0.lock().data = "DragonOS 6.0.0-generic 6.0.0\n"
416+
.to_string()
417+
.as_bytes()
418+
.to_vec();
419+
} else {
420+
panic!("create version_signature error");
421+
}
398422
return result;
399423
}
400424

@@ -466,6 +490,7 @@ impl IndexNode for LockedProcFSInode {
466490
let file_size = match inode.fdata.ftype {
467491
ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
468492
ProcFileType::ProcMeminfo => inode.open_meminfo(&mut private_data)?,
493+
ProcFileType::Default => inode.data.len() as i64,
469494
_ => {
470495
todo!()
471496
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
use crate::driver::base::class::Class;
2+
use crate::driver::base::device::bus::Bus;
3+
use crate::driver::base::device::driver::Driver;
4+
use crate::driver::base::device::{Device, DeviceCommonData, DeviceType, IdTable};
5+
use crate::driver::base::kobject::{
6+
KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState,
7+
};
8+
use crate::driver::base::kset::KSet;
9+
use crate::filesystem::kernfs::KernFSInode;
10+
use crate::filesystem::sysfs::{Attribute, SysFSOpsSupport};
11+
use crate::filesystem::vfs::syscall::ModeType;
12+
use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard};
13+
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
14+
use alloc::string::{String, ToString};
15+
use alloc::sync::{Arc, Weak};
16+
use core::fmt::Debug;
17+
use system_error::SystemError;
18+
19+
#[derive(Debug)]
20+
#[cast_to([sync] Device)]
21+
pub struct KprobeDevice {
22+
inner: SpinLock<InnerKprobeDevice>,
23+
kobj_state: LockedKObjectState,
24+
name: String,
25+
}
26+
27+
#[derive(Debug)]
28+
struct InnerKprobeDevice {
29+
kobject_common: KObjectCommonData,
30+
device_common: DeviceCommonData,
31+
}
32+
33+
impl KprobeDevice {
34+
pub fn new(parent: Option<Weak<dyn KObject>>) -> Arc<Self> {
35+
let bus_device = Self {
36+
inner: SpinLock::new(InnerKprobeDevice {
37+
kobject_common: KObjectCommonData::default(),
38+
device_common: DeviceCommonData::default(),
39+
}),
40+
kobj_state: LockedKObjectState::new(None),
41+
name: "kprobe".to_string(),
42+
};
43+
bus_device.set_parent(parent);
44+
return Arc::new(bus_device);
45+
}
46+
47+
fn inner(&self) -> SpinLockGuard<InnerKprobeDevice> {
48+
self.inner.lock()
49+
}
50+
}
51+
52+
impl KObject for KprobeDevice {
53+
fn as_any_ref(&self) -> &dyn core::any::Any {
54+
self
55+
}
56+
57+
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
58+
self.inner().kobject_common.kern_inode = inode;
59+
}
60+
61+
fn inode(&self) -> Option<Arc<KernFSInode>> {
62+
self.inner().kobject_common.kern_inode.clone()
63+
}
64+
65+
fn parent(&self) -> Option<Weak<dyn KObject>> {
66+
self.inner().kobject_common.parent.clone()
67+
}
68+
69+
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
70+
self.inner().kobject_common.parent = parent;
71+
}
72+
73+
fn kset(&self) -> Option<Arc<KSet>> {
74+
self.inner().kobject_common.kset.clone()
75+
}
76+
77+
fn set_kset(&self, kset: Option<Arc<KSet>>) {
78+
self.inner().kobject_common.kset = kset;
79+
}
80+
81+
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
82+
self.inner().kobject_common.kobj_type
83+
}
84+
85+
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
86+
self.inner().kobject_common.kobj_type = ktype;
87+
}
88+
89+
fn name(&self) -> String {
90+
self.name.clone()
91+
}
92+
93+
fn set_name(&self, _name: String) {}
94+
95+
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
96+
self.kobj_state.read()
97+
}
98+
99+
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
100+
self.kobj_state.write()
101+
}
102+
103+
fn set_kobj_state(&self, state: KObjectState) {
104+
*self.kobj_state.write() = state;
105+
}
106+
}
107+
108+
impl Device for KprobeDevice {
109+
#[inline]
110+
#[allow(dead_code)]
111+
fn dev_type(&self) -> DeviceType {
112+
return DeviceType::Other;
113+
}
114+
115+
#[inline]
116+
fn id_table(&self) -> IdTable {
117+
IdTable::new("kprobe".to_string(), None)
118+
}
119+
120+
fn bus(&self) -> Option<Weak<dyn Bus>> {
121+
self.inner().device_common.bus.clone()
122+
}
123+
124+
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
125+
self.inner().device_common.bus = bus;
126+
}
127+
128+
fn set_class(&self, class: Option<Weak<dyn Class>>) {
129+
self.inner().device_common.class = class;
130+
}
131+
132+
fn driver(&self) -> Option<Arc<dyn Driver>> {
133+
self.inner().device_common.driver.clone()?.upgrade()
134+
}
135+
136+
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
137+
self.inner().device_common.driver = driver;
138+
}
139+
140+
#[inline]
141+
fn is_dead(&self) -> bool {
142+
false
143+
}
144+
145+
fn can_match(&self) -> bool {
146+
todo!()
147+
}
148+
149+
fn set_can_match(&self, _can_match: bool) {
150+
todo!()
151+
}
152+
153+
fn state_synced(&self) -> bool {
154+
todo!()
155+
}
156+
157+
fn dev_parent(&self) -> Option<Weak<dyn Device>> {
158+
self.inner().device_common.get_parent_weak_or_clear()
159+
}
160+
161+
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
162+
self.inner().device_common.parent = dev_parent;
163+
}
164+
}
165+
166+
#[derive(Debug)]
167+
pub struct KprobeAttr;
168+
169+
impl Attribute for KprobeAttr {
170+
fn name(&self) -> &str {
171+
"type"
172+
}
173+
174+
fn mode(&self) -> ModeType {
175+
ModeType::S_IRUGO
176+
}
177+
178+
fn support(&self) -> SysFSOpsSupport {
179+
SysFSOpsSupport::ATTR_SHOW
180+
}
181+
fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
182+
if buf.is_empty() {
183+
return Err(SystemError::EINVAL);
184+
}
185+
// perf_type_id::PERF_TYPE_MAX
186+
buf[0] = b'6';
187+
Ok(1)
188+
}
189+
}

0 commit comments

Comments
 (0)