1use crate::bits64::rflags::{self, RFlags};
4use crate::vmx::{Result, VmFail};
5use core::arch::asm;
6
7#[inline(always)]
14fn vmx_capture_status() -> Result<()> {
15 let flags = rflags::read();
16
17 if flags.contains(RFlags::FLAGS_ZF) {
18 Err(VmFail::VmFailValid)
19 } else if flags.contains(RFlags::FLAGS_CF) {
20 Err(VmFail::VmFailInvalid)
21 } else {
22 Ok(())
23 }
24}
25
26pub unsafe fn vmxon(addr: u64) -> Result<()> {
34 asm!("vmxon ({0})", in(reg) &addr, options(att_syntax));
35 vmx_capture_status()
36}
37
38pub unsafe fn vmxoff() -> Result<()> {
43 asm!("vmxoff");
44 vmx_capture_status()
45}
46
47pub unsafe fn vmclear(addr: u64) -> Result<()> {
55 asm!("vmclear ({0})", in(reg) &addr, options(att_syntax));
56 vmx_capture_status()
57}
58
59pub unsafe fn vmptrld(addr: u64) -> Result<()> {
66 asm!("vmptrld ({0})", in(reg) &addr, options(att_syntax));
67 vmx_capture_status()
68}
69
70pub unsafe fn vmptrst() -> Result<u64> {
75 let value: u64 = 0;
76 asm!("vmptrst ({0})", in(reg) &value, options(att_syntax));
77 vmx_capture_status().and(Ok(value))
78}
79
80pub unsafe fn vmread(field: u32) -> Result<u64> {
85 let field: u64 = field.into();
86 let value: u64;
87 asm!("vmread {0}, {1}", in(reg) field, out(reg) value, options(att_syntax));
88 vmx_capture_status().and(Ok(value))
89}
90
91pub unsafe fn vmwrite(field: u32, value: u64) -> Result<()> {
96 let field: u64 = field.into();
97 asm!("vmwrite {1}, {0}", in(reg) field, in(reg) value, options(att_syntax));
98 vmx_capture_status()
99}
100
101#[inline(always)]
106pub unsafe fn vmlaunch() -> Result<()> {
107 asm!("vmlaunch");
108 vmx_capture_status()
109}
110
111#[inline(always)]
116pub unsafe fn vmresume() -> Result<()> {
117 asm!("vmresume");
118 vmx_capture_status()
119}