use std::ffi::c_void;
use std::sync::Arc;
use crate::{call, sys, Addr, Error, GPAddr, Memory, Size, Vcpu};
#[cfg(target_arch = "x86_64")]
pub type Options = crate::x86::VmOptions;
#[cfg(target_arch = "aarch64")]
pub type Options = sys::hv_vm_config_t;
#[derive(Debug)]
pub struct Vm;
impl Drop for Vm {
fn drop(&mut self) {
call!(sys::hv_vm_destroy()).unwrap()
}
}
unsafe impl Send for Vm {}
impl Vm {
pub fn new(options: Options) -> Result<Vm, Error> {
#[cfg(target_arch = "x86_64")]
let options = options.bits();
call!(sys::hv_vm_create(options))?;
Ok(Vm)
}
pub fn create_cpu(self: Arc<Self>) -> Result<Vcpu, Error> {
Vcpu::new(Arc::clone(&self))
}
pub fn map(&self, uva: Addr, gpa: GPAddr, size: Size, flags: Memory) -> Result<(), Error> {
call!(sys::hv_vm_map(
uva as *mut c_void,
gpa,
size,
flags.bits() as _
))
}
pub fn unmap(&self, gpa: GPAddr, size: Size) -> Result<(), Error> {
call!(sys::hv_vm_unmap(gpa, size))
}
pub fn protect(&self, gpa: GPAddr, size: Size, flags: Memory) -> Result<(), Error> {
call!(sys::hv_vm_protect(gpa, size, flags.bits() as _))
}
}