hyperlight_host/sandbox/
mod.rs1pub mod config;
19mod host_funcs;
21pub(crate) mod hypervisor;
23pub mod initialized_multi_use;
26pub(crate) mod mem_access;
29pub(crate) mod mem_mgr;
32pub(crate) mod outb;
33pub mod uninitialized;
36pub(crate) mod uninitialized_evolve;
39
40mod callable;
42
43pub use callable::Callable;
45pub use config::SandboxConfiguration;
47pub use initialized_multi_use::MultiUseSandbox;
49use tracing::{Span, instrument};
50pub use uninitialized::GuestBinary;
52pub use uninitialized::UninitializedSandbox;
54
55use self::mem_mgr::MemMgrWrapper;
56#[cfg(target_os = "windows")]
57use crate::hypervisor::windows_hypervisor_platform;
58use crate::mem::shared_mem::HostSharedMemory;
59
60#[instrument(skip_all, parent = Span::current())]
69pub fn is_supported_platform() -> bool {
70 #[cfg(not(target_os = "linux"))]
71 #[cfg(not(target_os = "windows"))]
72 return false;
73
74 true
75}
76
77pub type ExtraAllowedSyscall = i64;
79
80#[instrument(skip_all, parent = Span::current())]
85pub fn is_hypervisor_present() -> bool {
86 hypervisor::get_available_hypervisor().is_some()
87}
88
89pub(crate) trait WrapperGetter {
90 #[allow(dead_code)]
91 fn get_mgr_wrapper(&self) -> &MemMgrWrapper<HostSharedMemory>;
92 fn get_mgr_wrapper_mut(&mut self) -> &mut MemMgrWrapper<HostSharedMemory>;
93}
94
95#[cfg(test)]
96mod tests {
97 use std::sync::Arc;
98 use std::thread;
99
100 use crossbeam_queue::ArrayQueue;
101 use hyperlight_testing::simple_guest_as_string;
102
103 use crate::sandbox::uninitialized::GuestBinary;
104 use crate::sandbox_state::sandbox::EvolvableSandbox;
105 use crate::sandbox_state::transition::Noop;
106 use crate::{MultiUseSandbox, UninitializedSandbox, new_error};
107
108 #[test]
109 #[cfg(target_os = "linux")]
111 fn is_hypervisor_present() {
112 use std::path::Path;
113
114 cfg_if::cfg_if! {
115 if #[cfg(all(kvm, mshv))] {
116 assert_eq!(Path::new("/dev/kvm").exists() || Path::new("/dev/mshv").exists(), super::is_hypervisor_present());
117 } else if #[cfg(kvm)] {
118 assert_eq!(Path::new("/dev/kvm").exists(), super::is_hypervisor_present());
119 } else if #[cfg(mshv)] {
120 assert_eq!(Path::new("/dev/mshv").exists(), super::is_hypervisor_present());
121 } else {
122 assert!(!super::is_hypervisor_present());
123 }
124 }
125 }
126
127 #[test]
128 fn check_create_and_use_sandbox_on_different_threads() {
129 let unintializedsandbox_queue = Arc::new(ArrayQueue::<UninitializedSandbox>::new(10));
130 let sandbox_queue = Arc::new(ArrayQueue::<MultiUseSandbox>::new(10));
131
132 for i in 0..10 {
133 let simple_guest_path = simple_guest_as_string().expect("Guest Binary Missing");
134 let unintializedsandbox =
135 UninitializedSandbox::new(GuestBinary::FilePath(simple_guest_path), None)
136 .unwrap_or_else(|_| panic!("Failed to create UninitializedSandbox {}", i));
137
138 unintializedsandbox_queue
139 .push(unintializedsandbox)
140 .unwrap_or_else(|_| panic!("Failed to push UninitializedSandbox {}", i));
141 }
142
143 let thread_handles = (0..10)
144 .map(|i| {
145 let uq = unintializedsandbox_queue.clone();
146 let sq = sandbox_queue.clone();
147 thread::spawn(move || {
148 let uninitialized_sandbox = uq.pop().unwrap_or_else(|| {
149 panic!("Failed to pop UninitializedSandbox thread {}", i)
150 });
151 let host_funcs = uninitialized_sandbox
152 .host_funcs
153 .try_lock()
154 .map_err(|_| new_error!("Error locking"));
155
156 assert!(host_funcs.is_ok());
157
158 host_funcs
159 .unwrap()
160 .host_print(format!(
161 "Printing from UninitializedSandbox on Thread {}\n",
162 i
163 ))
164 .unwrap();
165
166 let sandbox = uninitialized_sandbox
167 .evolve(Noop::default())
168 .unwrap_or_else(|_| {
169 panic!("Failed to initialize UninitializedSandbox thread {}", i)
170 });
171
172 sq.push(sandbox).unwrap_or_else(|_| {
173 panic!("Failed to push UninitializedSandbox thread {}", i)
174 })
175 })
176 })
177 .collect::<Vec<_>>();
178
179 for handle in thread_handles {
180 handle.join().unwrap();
181 }
182
183 let thread_handles = (0..10)
184 .map(|i| {
185 let sq = sandbox_queue.clone();
186 thread::spawn(move || {
187 let sandbox = sq
188 .pop()
189 .unwrap_or_else(|| panic!("Failed to pop Sandbox thread {}", i));
190 let host_funcs = sandbox
191 ._host_funcs
192 .try_lock()
193 .map_err(|_| new_error!("Error locking"));
194
195 assert!(host_funcs.is_ok());
196
197 host_funcs
198 .unwrap()
199 .host_print(format!("Print from Sandbox on Thread {}\n", i))
200 .unwrap();
201 })
202 })
203 .collect::<Vec<_>>();
204
205 for handle in thread_handles {
206 handle.join().unwrap();
207 }
208 }
209}