1 use crate::driver::base::device::device_number::DeviceNumber;
2 use crate::filesystem::devfs::DevFS;
3 use crate::filesystem::vfs::{
4 core::generate_inode_id,
5 file::{File, FileMode},
6 FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
7 };
8 use crate::mm::VirtAddr;
9 use crate::process::ProcessManager;
10 use crate::syscall::user_access::copy_from_user;
11 use crate::virt::kvm::host_mem::KvmUserspaceMemoryRegion;
12 use crate::virt::kvm::update_vm;
13 use crate::virt::kvm::vcpu_dev::LockedVcpuInode;
14 use crate::virt::kvm::vm;
15 use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::TimeSpec};
16 use crate::{filesystem, kdebug};
17 use alloc::{
18 string::String,
19 sync::{Arc, Weak},
20 vec::Vec,
21 };
22 use system_error::SystemError;
23
24 // pub const KVM_API_VERSION:u32 = 12;
25 // pub const GUEST_STACK_SIZE:usize = 1024;
26 // pub const HOST_STACK_SIZE:usize = 0x1000 * 6;
27
28 /*
29 * ioctls for /dev/vm fds:
30 */
31 pub const KVM_CREATE_VCPU: u32 = 0x00;
32 pub const KVM_SET_USER_MEMORY_REGION: u32 = 0x01;
33 pub const KVM_GET_DIRTY_LOG: u32 = 0x02;
34 pub const KVM_IRQFD: u32 = 0x03;
35 pub const KVM_IOEVENTFD: u32 = 0x04;
36 pub const KVM_IRQ_LINE_STATUS: u32 = 0x05;
37
38 // #[derive(Debug)]
39 // pub struct InodeInfo {
40 // kvm: Arc<Hypervisor>,
41 // }
42
43 #[derive(Debug)]
44 pub struct VmInode {
45 /// uuid 暂时不知道有什么用(x
46 // uuid: Uuid,
47 /// 指向自身的弱引用
48 self_ref: Weak<LockedVmInode>,
49 /// 指向inode所在的文件系统对象的指针
50 fs: Weak<DevFS>,
51 /// INode 元数据
52 metadata: Metadata,
53 // fdata: InodeInfo,
54 }
55
56 #[derive(Debug)]
57 pub struct LockedVmInode(SpinLock<VmInode>);
58
59 impl LockedVmInode {
new() -> Arc<Self>60 pub fn new() -> Arc<Self> {
61 let inode = VmInode {
62 self_ref: Weak::default(),
63 fs: Weak::default(),
64 metadata: Metadata {
65 dev_id: 1,
66 inode_id: generate_inode_id(),
67 size: 0,
68 blk_size: 0,
69 blocks: 0,
70 atime: TimeSpec::default(),
71 mtime: TimeSpec::default(),
72 ctime: TimeSpec::default(),
73 file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
74 mode: filesystem::vfs::syscall::ModeType::S_IALLUGO,
75 nlinks: 1,
76 uid: 0,
77 gid: 0,
78 raw_dev: DeviceNumber::default(), // 这里用来作为device number
79 },
80 // fdata: InodeInfo {
81 // kvm: kvm,
82 // },
83 };
84
85 let result = Arc::new(LockedVmInode(SpinLock::new(inode)));
86 result.0.lock().self_ref = Arc::downgrade(&result);
87
88 return result;
89 }
90 }
91
92 impl IndexNode for LockedVmInode {
as_any_ref(&self) -> &dyn core::any::Any93 fn as_any_ref(&self) -> &dyn core::any::Any {
94 self
95 }
96
open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError>97 fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
98 kdebug!("file private data:{:?}", _data);
99 return Ok(());
100 }
101
close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError>102 fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
103 return Ok(());
104 }
105
metadata(&self) -> Result<Metadata, SystemError>106 fn metadata(&self) -> Result<Metadata, SystemError> {
107 return Ok(self.0.lock().metadata.clone());
108 }
109
fs(&self) -> Arc<dyn FileSystem>110 fn fs(&self) -> Arc<dyn FileSystem> {
111 return self.0.lock().fs.upgrade().unwrap();
112 }
113
list(&self) -> Result<Vec<String>, SystemError>114 fn list(&self) -> Result<Vec<String>, SystemError> {
115 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
116 }
117
set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError>118 fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
119 let mut inode = self.0.lock();
120 inode.metadata.atime = metadata.atime;
121 inode.metadata.mtime = metadata.mtime;
122 inode.metadata.ctime = metadata.ctime;
123 inode.metadata.mode = metadata.mode;
124 inode.metadata.uid = metadata.uid;
125 inode.metadata.gid = metadata.gid;
126
127 return Ok(());
128 }
129
130 /// @brief io control接口
131 ///
132 /// @param cmd 命令
133 /// @param data 数据
134 ///
135 /// @return 成功:Ok()
136 /// 失败:Err(错误码)
ioctl( &self, cmd: u32, data: usize, _private_data: &FilePrivateData, ) -> Result<usize, SystemError>137 fn ioctl(
138 &self,
139 cmd: u32,
140 data: usize,
141 _private_data: &FilePrivateData,
142 ) -> Result<usize, SystemError> {
143 match cmd {
144 0xdeadbeef => {
145 kdebug!("kvm_vm ioctl");
146 Ok(0)
147 }
148 KVM_CREATE_VCPU => {
149 kdebug!("kvm_vcpu ioctl KVM_CREATE_VCPU");
150 kvm_vm_ioctl_create_vcpu(data as u32)
151 }
152 KVM_SET_USER_MEMORY_REGION => {
153 kdebug!("kvm_vcpu ioctl KVM_SET_USER_MEMORY_REGION data={:x}", data);
154 let mut kvm_userspace_mem = KvmUserspaceMemoryRegion::default(); // = unsafe { (data as *const KvmUserspaceMemoryRegion).as_ref().unwrap() };
155 unsafe {
156 copy_from_user(
157 core::slice::from_raw_parts_mut(
158 (&mut kvm_userspace_mem as *mut _) as *mut u8,
159 core::mem::size_of::<KvmUserspaceMemoryRegion>(),
160 ),
161 VirtAddr::new(data),
162 )?;
163 }
164 kdebug!(
165 "slot={}, flag={}, memory_size={:x}, guest_phys_addr={}, userspace_addr={}",
166 kvm_userspace_mem.slot,
167 kvm_userspace_mem.flags,
168 kvm_userspace_mem.memory_size,
169 kvm_userspace_mem.guest_phys_addr, // starting at physical address guest_phys_addr (from the guest’s perspective)
170 kvm_userspace_mem.userspace_addr // using memory at linear address userspace_addr (from the host’s perspective)
171 );
172
173 let mut current_vm = vm(0).unwrap();
174 current_vm.set_user_memory_region(&kvm_userspace_mem)?;
175 update_vm(0, current_vm);
176 Ok(0)
177 }
178 KVM_GET_DIRTY_LOG | KVM_IRQFD | KVM_IOEVENTFD | KVM_IRQ_LINE_STATUS => {
179 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
180 }
181 _ => {
182 kdebug!("kvm_vm ioctl");
183 Ok(usize::MAX)
184 }
185 }
186 }
187 /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
read_at( &self, _offset: usize, _len: usize, _buf: &mut [u8], _data: &mut FilePrivateData, ) -> Result<usize, SystemError>188 fn read_at(
189 &self,
190 _offset: usize,
191 _len: usize,
192 _buf: &mut [u8],
193 _data: &mut FilePrivateData,
194 ) -> Result<usize, SystemError> {
195 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
196 }
197
198 /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写
write_at( &self, _offset: usize, _len: usize, _buf: &[u8], _data: &mut FilePrivateData, ) -> Result<usize, SystemError>199 fn write_at(
200 &self,
201 _offset: usize,
202 _len: usize,
203 _buf: &[u8],
204 _data: &mut FilePrivateData,
205 ) -> Result<usize, SystemError> {
206 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
207 }
208 }
209
kvm_vm_ioctl_create_vcpu(id: u32) -> Result<usize, SystemError>210 fn kvm_vm_ioctl_create_vcpu(id: u32) -> Result<usize, SystemError> {
211 let vcpu = KVMArch::kvm_arch_vcpu_create(id).unwrap();
212 KVMArch::kvm_arch_vcpu_setup(vcpu.as_ref())?;
213
214 let mut current_vm = vm(0).unwrap();
215 current_vm.vcpu.push(vcpu);
216 current_vm.nr_vcpus += 1;
217 update_vm(0, current_vm);
218
219 let vcpu_inode = LockedVcpuInode::new();
220 let file: File = File::new(vcpu_inode, FileMode::O_RDWR)?;
221 let r = ProcessManager::current_pcb()
222 .fd_table()
223 .write()
224 .alloc_fd(file, None)
225 .map(|fd| fd as usize);
226 return r;
227 }
228