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