-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathlib.rs
More file actions
95 lines (82 loc) · 2.9 KB
/
lib.rs
File metadata and controls
95 lines (82 loc) · 2.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//! `hv` is a high level safe Rust crate to access Hypervisor Framework.
use std::error;
use std::fmt;
/// Low level access to generated bindings.
pub use hv_sys as sys;
pub use vcpu::Vcpu;
pub use vm::Vm;
mod vcpu;
pub mod vm;
#[cfg(target_arch = "aarch64")]
pub mod arm64;
#[cfg(target_arch = "x86_64")]
pub mod x86;
pub type Size = u64;
/// Type of a user virtual address.
pub type Addr = *const u8;
/// Type of a guest physical address.
pub type GPAddr = u64;
bitflags::bitflags! {
/// Guest physical memory region permissions.
pub struct Memory: u64 {
const READ = 1 << 0;
const WRITE = 1 << 1;
const EXEC = 1 << 2;
}
}
/// Helper macro to call unsafe Hypervisor functions and map returned error codes to [Error] type.
#[macro_export]
macro_rules! call {
($f:expr) => {{
#[allow(clippy::macro_metavars_in_unsafe)]
let code = unsafe { $f };
match code {
0 => Ok(()),
_ => Err(Error::from(code)),
}
}};
}
/// The return type of framework functions.
/// Wraps the underlying `hv_return_t` type.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Error {
Unsuccessful,
Busy,
BadArgument,
NoResources,
NoDevice,
Unsupported,
/// Not mapped error code.
Unknown(sys::hv_return_t),
}
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Unsuccessful => write!(f, "The operation was unsuccessful"),
Error::Busy => write!(f, "The operation was unsuccessful because the owning resource was busy"),
Error::BadArgument => write!(f, "The operation was unsuccessful because the function call had an invalid argument"),
Error::NoResources => write!(f, "The operation was unsuccessful because the host had no resources available to complete the request"),
Error::NoDevice => write!(f, "The operation was unsuccessful because no VM or vCPU was available"),
Error::Unsupported => write!(f, "The operation requested isn’t supported by the hypervisor"),
Error::Unknown(code) => write!(f, "Error code: {}", *code),
}
}
}
impl From<sys::hv_return_t> for Error {
fn from(value: sys::hv_return_t) -> Self {
// Looks like bindgen gets confused sometimes and produces different code for these
// constants (`sys::HV_ERROR` vs `hv_return_t_HV_ERROR`) on different machines making things
// to fail. It's probably easier to just hardcode them.
let v = value as i64;
match v {
0xfae94001 => Error::Unsuccessful,
0xfae94002 => Error::Busy,
0xfae94003 => Error::BadArgument,
0xfae94005 => Error::NoResources,
0xfae94006 => Error::NoDevice,
0xfae9400f => Error::Unsupported,
_ => Error::Unknown(value),
}
}
}