|
| 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