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