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