1 use crate::driver::base::device::device_number::DeviceNumber;
2 use crate::filesystem;
3 use crate::filesystem::devfs::{DevFS, DeviceINode};
4 use crate::filesystem::vfs::{
5 core::generate_inode_id,
6 file::{File, FileMode},
7 FilePrivateData, FileSystem, FileType, IndexNode, Metadata,
8 };
9 use crate::libs::spinlock::SpinLockGuard;
10 use crate::process::ProcessManager;
11 use crate::{arch::KVMArch, libs::spinlock::SpinLock, time::PosixTimeSpec};
12 // use crate::virt::kvm::{host_stack};
13 use super::push_vm;
14 use crate::virt::kvm::vm_dev::LockedVmInode;
15 use alloc::{
16 string::String,
17 sync::{Arc, Weak},
18 vec::Vec,
19 };
20 use log::debug;
21 use system_error::SystemError;
22
23 pub const KVM_API_VERSION: u32 = 12;
24
25 // use crate::virt::kvm::kvm_dev_ioctl_create_vm;
26 /*
27 * ioctls for /dev/kvm fds:
28 */
29 pub const KVM_GET_API_VERSION: u32 = 0x00;
30 pub const KVM_CREATE_VM: u32 = 0x01;
31 pub const KVM_CHECK_EXTENSION: u32 = 0x03;
32 pub const KVM_GET_VCPU_MMAP_SIZE: u32 = 0x04; // Get size for mmap(vcpu_fd) in bytes
33 pub const KVM_TRACE_ENABLE: u32 = 0x05;
34 pub const KVM_TRACE_PAUSE: u32 = 0x06;
35 pub const KVM_TRACE_DISABLE: u32 = 0x07;
36
37 #[derive(Debug)]
38 pub struct KvmInode {
39 /// uuid 暂时不知道有什么用(x
40 // uuid: Uuid,
41 /// 指向自身的弱引用
42 self_ref: Weak<LockedKvmInode>,
43 /// 指向inode所在的文件系统对象的指针
44 fs: Weak<DevFS>,
45 /// INode 元数据
46 metadata: Metadata,
47 }
48
49 #[derive(Debug)]
50 pub struct LockedKvmInode(SpinLock<KvmInode>);
51
52 impl LockedKvmInode {
new() -> Arc<Self>53 pub fn new() -> Arc<Self> {
54 let inode = KvmInode {
55 self_ref: Weak::default(),
56 fs: Weak::default(),
57 metadata: Metadata {
58 dev_id: 1,
59 inode_id: generate_inode_id(),
60 size: 0,
61 blk_size: 0,
62 blocks: 0,
63 atime: PosixTimeSpec::default(),
64 mtime: PosixTimeSpec::default(),
65 ctime: PosixTimeSpec::default(),
66 file_type: FileType::KvmDevice, // 文件夹,block设备,char设备
67 mode: filesystem::vfs::syscall::ModeType::S_IALLUGO,
68 nlinks: 1,
69 uid: 0,
70 gid: 0,
71 raw_dev: DeviceNumber::default(), // 这里用来作为device number
72 },
73 };
74
75 let result = Arc::new(LockedKvmInode(SpinLock::new(inode)));
76 result.0.lock().self_ref = Arc::downgrade(&result);
77
78 return result;
79 }
80 }
81
82 impl DeviceINode for LockedKvmInode {
set_fs(&self, fs: Weak<DevFS>)83 fn set_fs(&self, fs: Weak<DevFS>) {
84 self.0.lock().fs = fs;
85 }
86 }
87
88 impl IndexNode for LockedKvmInode {
as_any_ref(&self) -> &dyn core::any::Any89 fn as_any_ref(&self) -> &dyn core::any::Any {
90 self
91 }
92
open( &self, _data: SpinLockGuard<FilePrivateData>, _mode: &FileMode, ) -> Result<(), SystemError>93 fn open(
94 &self,
95 _data: SpinLockGuard<FilePrivateData>,
96 _mode: &FileMode,
97 ) -> Result<(), SystemError> {
98 debug!("file private data:{:?}", _data);
99 return Ok(());
100 }
101
close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError>102 fn close(&self, _data: SpinLockGuard<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::ENOSYS)
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 debug!("kvm ioctl");
146 Ok(0)
147 }
148 KVM_GET_API_VERSION => Ok(KVM_API_VERSION as usize),
149 KVM_CREATE_VM => {
150 debug!("kvm KVM_CREATE_VM");
151 kvm_dev_ioctl_create_vm(data)
152 }
153 KVM_CHECK_EXTENSION
154 | KVM_GET_VCPU_MMAP_SIZE
155 | KVM_TRACE_ENABLE
156 | KVM_TRACE_PAUSE
157 | KVM_TRACE_DISABLE => Err(SystemError::ENOSYS),
158 _ => KVMArch::kvm_arch_dev_ioctl(cmd, data),
159 }
160 }
161 /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写
read_at( &self, _offset: usize, _len: usize, _buf: &mut [u8], _data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>162 fn read_at(
163 &self,
164 _offset: usize,
165 _len: usize,
166 _buf: &mut [u8],
167 _data: SpinLockGuard<FilePrivateData>,
168 ) -> Result<usize, SystemError> {
169 Err(SystemError::ENOSYS)
170 }
171
172 /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写
write_at( &self, _offset: usize, _len: usize, _buf: &[u8], _data: SpinLockGuard<FilePrivateData>, ) -> Result<usize, SystemError>173 fn write_at(
174 &self,
175 _offset: usize,
176 _len: usize,
177 _buf: &[u8],
178 _data: SpinLockGuard<FilePrivateData>,
179 ) -> Result<usize, SystemError> {
180 Err(SystemError::ENOSYS)
181 }
182 }
183
184 #[no_mangle]
kvm_dev_ioctl_create_vm(_vmtype: usize) -> Result<usize, SystemError>185 pub fn kvm_dev_ioctl_create_vm(_vmtype: usize) -> Result<usize, SystemError> {
186 push_vm(0).expect("need a valid vm!");
187
188 // 创建vm文件,返回文件描述符
189 let vm_inode = LockedVmInode::new();
190 let file: File = File::new(vm_inode, FileMode::O_RDWR)?;
191 let r = ProcessManager::current_pcb()
192 .fd_table()
193 .write()
194 .alloc_fd(file, None)
195 .map(|fd| fd as usize);
196 return r;
197 }
198