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