1 use super::vmcs::VmcsFields; 2 3 use core::arch::asm; 4 use log::debug; 5 use system_error::SystemError; 6 use x86; 7 /// Enable VMX operation. 8 pub fn vmxon(vmxon_pa: u64) -> Result<(), SystemError> { 9 match unsafe { x86::bits64::vmx::vmxon(vmxon_pa) } { 10 Ok(_) => Ok(()), 11 Err(e) => { 12 debug!("vmxon fail: {:?}", e); 13 Err(SystemError::EVMXONFailed) 14 } 15 } 16 } 17 18 /// Disable VMX operation. 19 pub fn vmxoff() -> Result<(), SystemError> { 20 match unsafe { x86::bits64::vmx::vmxoff() } { 21 Ok(_) => Ok(()), 22 Err(_) => Err(SystemError::EVMXOFFFailed), 23 } 24 } 25 26 /// vmrite the current VMCS. 27 pub fn vmx_vmwrite(vmcs_field: u32, value: u64) -> Result<(), SystemError> { 28 match unsafe { x86::bits64::vmx::vmwrite(vmcs_field, value) } { 29 Ok(_) => Ok(()), 30 Err(e) => { 31 debug!("vmx_write fail: {:?}", e); 32 debug!("vmcs_field: {:x}", vmcs_field); 33 Err(SystemError::EVMWRITEFailed) 34 } 35 } 36 } 37 38 /// vmread the current VMCS. 39 pub fn vmx_vmread(vmcs_field: u32) -> Result<u64, SystemError> { 40 match unsafe { x86::bits64::vmx::vmread(vmcs_field) } { 41 Ok(value) => Ok(value), 42 Err(e) => { 43 debug!("vmx_read fail: {:?}", e); 44 Err(SystemError::EVMREADFailed) 45 } 46 } 47 } 48 49 pub fn vmx_vmptrld(vmcs_pa: u64) -> Result<(), SystemError> { 50 match unsafe { x86::bits64::vmx::vmptrld(vmcs_pa) } { 51 Ok(_) => Ok(()), 52 Err(_) => Err(SystemError::EVMPRTLDFailed), 53 } 54 } 55 56 pub fn vmx_vmlaunch() -> Result<(), SystemError> { 57 let host_rsp = VmcsFields::HOST_RSP as u32; 58 let host_rip = VmcsFields::HOST_RIP as u32; 59 unsafe { 60 asm!( 61 "push rbp", 62 "push rcx", 63 "push rdx", 64 "push rsi", 65 "push rdi", 66 "vmwrite {0:r}, rsp", 67 "lea rax, 1f[rip]", 68 "vmwrite {1:r}, rax", 69 "vmlaunch", 70 "1:", 71 "pop rdi", 72 "pop rsi", 73 "pop rdx", 74 "pop rcx", 75 "pop rbp", 76 "call vmx_return", 77 in(reg) host_rsp, 78 in(reg) host_rip, 79 clobber_abi("C"), 80 ) 81 } 82 Ok(()) 83 // match unsafe { x86::bits64::vmx::vmlaunch() } { 84 // Ok(_) => Ok(()), 85 // Err(e) => { 86 // debug!("vmx_launch fail: {:?}", e); 87 // Err(SystemError::EVMLAUNCHFailed) 88 // }, 89 // } 90 } 91 92 pub fn vmx_vmclear(vmcs_pa: u64) -> Result<(), SystemError> { 93 match unsafe { x86::bits64::vmx::vmclear(vmcs_pa) } { 94 Ok(_) => Ok(()), 95 Err(_) => Err(SystemError::EVMPRTLDFailed), 96 } 97 } 98