140314b30SXiaoye Zheng use super::vmcs::VmcsFields; 2*2eab6dd7S曾俊 340314b30SXiaoye Zheng use core::arch::asm; 4*2eab6dd7S曾俊 use log::debug; 591e9d4abSLoGin use system_error::SystemError; 640314b30SXiaoye Zheng use x86; 740314b30SXiaoye Zheng /// Enable VMX operation. 840314b30SXiaoye Zheng pub fn vmxon(vmxon_pa: u64) -> Result<(), SystemError> { 940314b30SXiaoye Zheng match unsafe { x86::bits64::vmx::vmxon(vmxon_pa) } { 1040314b30SXiaoye Zheng Ok(_) => Ok(()), 1140314b30SXiaoye Zheng Err(e) => { 12*2eab6dd7S曾俊 debug!("vmxon fail: {:?}", e); 1340314b30SXiaoye Zheng Err(SystemError::EVMXONFailed) 1440314b30SXiaoye Zheng } 1540314b30SXiaoye Zheng } 1640314b30SXiaoye Zheng } 1740314b30SXiaoye Zheng 1840314b30SXiaoye Zheng /// Disable VMX operation. 1940314b30SXiaoye Zheng pub fn vmxoff() -> Result<(), SystemError> { 2040314b30SXiaoye Zheng match unsafe { x86::bits64::vmx::vmxoff() } { 2140314b30SXiaoye Zheng Ok(_) => Ok(()), 2240314b30SXiaoye Zheng Err(_) => Err(SystemError::EVMXOFFFailed), 2340314b30SXiaoye Zheng } 2440314b30SXiaoye Zheng } 2540314b30SXiaoye Zheng 2640314b30SXiaoye Zheng /// vmrite the current VMCS. 2740314b30SXiaoye Zheng pub fn vmx_vmwrite(vmcs_field: u32, value: u64) -> Result<(), SystemError> { 2840314b30SXiaoye Zheng match unsafe { x86::bits64::vmx::vmwrite(vmcs_field, value) } { 2940314b30SXiaoye Zheng Ok(_) => Ok(()), 3040314b30SXiaoye Zheng Err(e) => { 31*2eab6dd7S曾俊 debug!("vmx_write fail: {:?}", e); 32*2eab6dd7S曾俊 debug!("vmcs_field: {:x}", vmcs_field); 3340314b30SXiaoye Zheng Err(SystemError::EVMWRITEFailed) 3440314b30SXiaoye Zheng } 3540314b30SXiaoye Zheng } 3640314b30SXiaoye Zheng } 3740314b30SXiaoye Zheng 3840314b30SXiaoye Zheng /// vmread the current VMCS. 3940314b30SXiaoye Zheng pub fn vmx_vmread(vmcs_field: u32) -> Result<u64, SystemError> { 4040314b30SXiaoye Zheng match unsafe { x86::bits64::vmx::vmread(vmcs_field) } { 4140314b30SXiaoye Zheng Ok(value) => Ok(value), 4240314b30SXiaoye Zheng Err(e) => { 43*2eab6dd7S曾俊 debug!("vmx_read fail: {:?}", e); 4440314b30SXiaoye Zheng Err(SystemError::EVMREADFailed) 4540314b30SXiaoye Zheng } 4640314b30SXiaoye Zheng } 4740314b30SXiaoye Zheng } 4840314b30SXiaoye Zheng 4940314b30SXiaoye Zheng pub fn vmx_vmptrld(vmcs_pa: u64) -> Result<(), SystemError> { 5040314b30SXiaoye Zheng match unsafe { x86::bits64::vmx::vmptrld(vmcs_pa) } { 5140314b30SXiaoye Zheng Ok(_) => Ok(()), 5240314b30SXiaoye Zheng Err(_) => Err(SystemError::EVMPRTLDFailed), 5340314b30SXiaoye Zheng } 5440314b30SXiaoye Zheng } 5540314b30SXiaoye Zheng 5640314b30SXiaoye Zheng pub fn vmx_vmlaunch() -> Result<(), SystemError> { 5740314b30SXiaoye Zheng let host_rsp = VmcsFields::HOST_RSP as u32; 5840314b30SXiaoye Zheng let host_rip = VmcsFields::HOST_RIP as u32; 5940314b30SXiaoye Zheng unsafe { 6040314b30SXiaoye Zheng asm!( 6140314b30SXiaoye Zheng "push rbp", 6240314b30SXiaoye Zheng "push rcx", 6340314b30SXiaoye Zheng "push rdx", 6440314b30SXiaoye Zheng "push rsi", 6540314b30SXiaoye Zheng "push rdi", 6640314b30SXiaoye Zheng "vmwrite {0:r}, rsp", 6740314b30SXiaoye Zheng "lea rax, 1f[rip]", 6840314b30SXiaoye Zheng "vmwrite {1:r}, rax", 6940314b30SXiaoye Zheng "vmlaunch", 7040314b30SXiaoye Zheng "1:", 7140314b30SXiaoye Zheng "pop rdi", 7240314b30SXiaoye Zheng "pop rsi", 7340314b30SXiaoye Zheng "pop rdx", 7440314b30SXiaoye Zheng "pop rcx", 7540314b30SXiaoye Zheng "pop rbp", 7640314b30SXiaoye Zheng "call vmx_return", 7740314b30SXiaoye Zheng in(reg) host_rsp, 7840314b30SXiaoye Zheng in(reg) host_rip, 7940314b30SXiaoye Zheng clobber_abi("C"), 8040314b30SXiaoye Zheng ) 8140314b30SXiaoye Zheng } 8240314b30SXiaoye Zheng Ok(()) 8340314b30SXiaoye Zheng // match unsafe { x86::bits64::vmx::vmlaunch() } { 8440314b30SXiaoye Zheng // Ok(_) => Ok(()), 8540314b30SXiaoye Zheng // Err(e) => { 86*2eab6dd7S曾俊 // debug!("vmx_launch fail: {:?}", e); 8740314b30SXiaoye Zheng // Err(SystemError::EVMLAUNCHFailed) 8840314b30SXiaoye Zheng // }, 8940314b30SXiaoye Zheng // } 9040314b30SXiaoye Zheng } 9140314b30SXiaoye Zheng 9240314b30SXiaoye Zheng pub fn vmx_vmclear(vmcs_pa: u64) -> Result<(), SystemError> { 9340314b30SXiaoye Zheng match unsafe { x86::bits64::vmx::vmclear(vmcs_pa) } { 9440314b30SXiaoye Zheng Ok(_) => Ok(()), 9540314b30SXiaoye Zheng Err(_) => Err(SystemError::EVMPRTLDFailed), 9640314b30SXiaoye Zheng } 9740314b30SXiaoye Zheng } 98