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.
vmxon(vmxon_pa: u64) -> Result<(), SystemError>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.
vmxoff() -> Result<(), SystemError>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.
vmx_vmwrite(vmcs_field: u32, value: u64) -> Result<(), SystemError>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.
vmx_vmread(vmcs_field: u32) -> Result<u64, SystemError>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
vmx_vmptrld(vmcs_pa: u64) -> Result<(), SystemError>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
vmx_vmlaunch() -> Result<(), SystemError>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, 2f[rip]",
68 "vmwrite {1:r}, rax",
69 "vmlaunch",
70 "2:",
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
vmx_vmclear(vmcs_pa: u64) -> Result<(), SystemError>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