xref: /DragonOS/kernel/src/arch/x86_64/kvm/vmx/vmx_asm_wrapper.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
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