extern crate core;
extern crate libc;
extern crate thiserror;
#[cfg(target_arch = "aarch64")]
#[allow(non_camel_case_types)]
pub mod aarch64;
#[cfg(target_arch = "x86_64")]
#[allow(non_camel_case_types)]
pub mod x86_64;
use thiserror::Error;
#[cfg(target_arch = "x86_64")]
use self::x86_64::ffi::*;
#[cfg(target_arch = "aarch64")]
use aarch64::ffi::*;
#[cfg(target_arch = "aarch64")]
pub use aarch64::*;
#[cfg(target_arch = "x86_64")]
pub use x86_64::*;
#[derive(Error, Debug)]
pub enum Error {
#[error("success")]
Success,
#[error("error")]
Error,
#[error("busy")]
Busy,
#[error("bad argument")]
BadArg,
#[error("no resource")]
NoRes,
#[error("no device")]
NoDev,
#[error("unsupported")]
Unsupp,
}
fn match_error_code(code: hv_return_t) -> Result<(), Error> {
match code {
HV_SUCCESS => Ok(()),
HV_BUSY => Err(Error::Busy),
HV_BAD_ARGUMENT => Err(Error::BadArg),
HV_NO_RESOURCES => Err(Error::NoRes),
HV_NO_DEVICE => Err(Error::NoDev),
HV_UNSUPPORTED => Err(Error::Unsupp),
_ => Err(Error::Error),
}
}
pub fn destroy_vm() -> Result<(), Error> {
match_error_code(unsafe { hv_vm_destroy() })
}
#[derive(Debug)]
pub enum MemPerm {
None,
Read,
Write,
ReadWrite,
Exec,
ExecWrite,
ExecRead,
ExecReadWrite,
}
#[allow(non_snake_case)]
#[inline(always)]
fn match_MemPerm(mem_perm: MemPerm) -> u64 {
match mem_perm {
MemPerm::None => 0,
MemPerm::Read => HV_MEMORY_READ,
MemPerm::Write => HV_MEMORY_WRITE,
MemPerm::ReadWrite => HV_MEMORY_WRITE | HV_MEMORY_READ,
MemPerm::Exec => HV_MEMORY_EXEC,
MemPerm::ExecWrite => HV_MEMORY_EXEC | HV_MEMORY_WRITE,
MemPerm::ExecRead => HV_MEMORY_EXEC | HV_MEMORY_READ,
MemPerm::ExecReadWrite => HV_MEMORY_EXEC | HV_MEMORY_READ | HV_MEMORY_WRITE,
}
}
impl VirtualCpu {
pub fn destroy(&self) -> Result<(), Error> {
match_error_code(unsafe { hv_vcpu_destroy(self.get_handle()) })
}
pub fn run(&self) -> Result<(), Error> {
match_error_code(unsafe { hv_vcpu_run(self.get_handle()) })
}
}