140314b30SXiaoye Zheng use super::vmcs::VmcsFields;
22eab6dd7S曾俊
340314b30SXiaoye Zheng use core::arch::asm;
42eab6dd7S曾俊 use log::debug;
591e9d4abSLoGin use system_error::SystemError;
640314b30SXiaoye Zheng use x86;
740314b30SXiaoye Zheng /// Enable VMX operation.
vmxon(vmxon_pa: u64) -> Result<(), SystemError>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) => {
122eab6dd7S曾俊 debug!("vmxon fail: {:?}", e);
1340314b30SXiaoye Zheng Err(SystemError::EVMXONFailed)
1440314b30SXiaoye Zheng }
1540314b30SXiaoye Zheng }
1640314b30SXiaoye Zheng }
1740314b30SXiaoye Zheng
1840314b30SXiaoye Zheng /// Disable VMX operation.
vmxoff() -> Result<(), SystemError>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.
vmx_vmwrite(vmcs_field: u32, value: u64) -> Result<(), SystemError>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) => {
312eab6dd7S曾俊 debug!("vmx_write fail: {:?}", e);
322eab6dd7S曾俊 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.
vmx_vmread(vmcs_field: u32) -> Result<u64, SystemError>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) => {
432eab6dd7S曾俊 debug!("vmx_read fail: {:?}", e);
4440314b30SXiaoye Zheng Err(SystemError::EVMREADFailed)
4540314b30SXiaoye Zheng }
4640314b30SXiaoye Zheng }
4740314b30SXiaoye Zheng }
4840314b30SXiaoye Zheng
vmx_vmptrld(vmcs_pa: u64) -> Result<(), SystemError>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
vmx_vmlaunch() -> Result<(), SystemError>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",
67*bd70d2d1SLoGin "lea rax, 2f[rip]",
6840314b30SXiaoye Zheng "vmwrite {1:r}, rax",
6940314b30SXiaoye Zheng "vmlaunch",
70*bd70d2d1SLoGin "2:",
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) => {
862eab6dd7S曾俊 // debug!("vmx_launch fail: {:?}", e);
8740314b30SXiaoye Zheng // Err(SystemError::EVMLAUNCHFailed)
8840314b30SXiaoye Zheng // },
8940314b30SXiaoye Zheng // }
9040314b30SXiaoye Zheng }
9140314b30SXiaoye Zheng
vmx_vmclear(vmcs_pa: u64) -> Result<(), SystemError>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