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