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