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