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 { 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 { 81 fn set_fs(&self, fs: Weak<DevFS>) { 82 self.0.lock().fs = fs; 83 } 84 } 85 86 impl IndexNode for LockedKvmInode { 87 fn as_any_ref(&self) -> &dyn core::any::Any { 88 self 89 } 90 91 fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> { 92 kdebug!("file private data:{:?}", _data); 93 return Ok(()); 94 } 95 96 fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> { 97 return Ok(()); 98 } 99 100 fn metadata(&self) -> Result<Metadata, SystemError> { 101 return Ok(self.0.lock().metadata.clone()); 102 } 103 104 fn fs(&self) -> Arc<dyn FileSystem> { 105 return self.0.lock().fs.upgrade().unwrap(); 106 } 107 108 fn list(&self) -> Result<Vec<String>, SystemError> { 109 Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) 110 } 111 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(错误码) 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 /// 读设备 - 应该调用设备的函数读写,而不是通过文件系统读写 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 /// 写设备 - 应该调用设备的函数读写,而不是通过文件系统读写 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] 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