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