-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4c98b9e
commit 53e9fa6
Showing
8 changed files
with
114 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,7 @@ members = [ | |
"fs", | ||
"ftp", | ||
"gmtx", | ||
"hv", | ||
"kernel", | ||
"llt", | ||
"macros", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "hv" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
thiserror = "1.0.57" | ||
|
||
[target.'cfg(unit)'.dependencies] | ||
libc = "0.2.153" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
fn main() { | ||
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); | ||
|
||
if os == "macos" { | ||
println!("cargo:rustc-link-lib=framework=Hypervisor"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#![allow(non_camel_case_types)] | ||
|
||
use std::ffi::c_int; | ||
|
||
#[repr(C)] | ||
pub struct hv_vm_config_t([u8; 0]); | ||
|
||
extern "C" { | ||
pub fn hv_vm_create(config: *mut hv_vm_config_t) -> c_int; | ||
pub fn hv_vm_destroy() -> c_int; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
use std::sync::atomic::{AtomicBool, Ordering}; | ||
use thiserror::Error; | ||
|
||
#[cfg(target_os = "macos")] | ||
mod darwin; | ||
|
||
/// Manage a virtual machine of the current process. | ||
/// | ||
/// Each process can have only one VM. The reason this type is not a global variable is because we | ||
/// want to be able to drop it. | ||
pub struct Hypervisor { | ||
#[allow(dead_code)] | ||
active: Active, // Drop as the last one. | ||
} | ||
|
||
impl Hypervisor { | ||
pub fn new() -> Result<Self, NewError> { | ||
let active = Active::new().ok_or(NewError::Active)?; | ||
|
||
#[cfg(target_os = "macos")] | ||
match unsafe { self::darwin::hv_vm_create(std::ptr::null_mut()) } { | ||
0 => {} | ||
v => return Err(NewError::HostFailed(v)), | ||
} | ||
|
||
Ok(Self { active }) | ||
} | ||
} | ||
|
||
impl Drop for Hypervisor { | ||
#[cfg(target_os = "linux")] | ||
fn drop(&mut self) {} | ||
|
||
#[cfg(target_os = "windows")] | ||
fn drop(&mut self) {} | ||
|
||
#[cfg(target_os = "macos")] | ||
fn drop(&mut self) { | ||
let status = unsafe { self::darwin::hv_vm_destroy() }; | ||
|
||
if status != 0 { | ||
panic!("hv_vm_destroy() was failed with {status:#x}"); | ||
} | ||
} | ||
} | ||
|
||
/// RAII object to set release ACTIVE. | ||
struct Active; | ||
|
||
impl Active { | ||
fn new() -> Option<Self> { | ||
ACTIVE | ||
.compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) | ||
.map(|_| Self) | ||
.ok() | ||
} | ||
} | ||
|
||
impl Drop for Active { | ||
fn drop(&mut self) { | ||
ACTIVE.store(false, Ordering::Release); | ||
} | ||
} | ||
|
||
/// Represents an error when [`Hypervisor::new()`] was failed. | ||
#[derive(Debug, Error)] | ||
pub enum NewError { | ||
#[error("there is an active hypervisor")] | ||
Active, | ||
|
||
#[cfg(target_os = "macos")] | ||
#[error("the host failed to create the hypervisor ({0:#x})")] | ||
HostFailed(std::ffi::c_int), | ||
} | ||
|
||
static ACTIVE: AtomicBool = AtomicBool::new(false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters