Skip to content

Commit

Permalink
[performance] Move set_up_hypervisor_partition to inside the hv handl…
Browse files Browse the repository at this point in the history
…er thread

As per KVM docs, vCPU ioctls should be issued from the same thread that was used to create the vCPU.
In accordance to that, this PR moves set_up_hypervisor_partition to inside the hv handler thread,
which manages vCPU interactions like init and dispatching guest funciton calls.

Signed-off-by: danbugs <danilochiarlone@gmail.com>
  • Loading branch information
danbugs committed Nov 26, 2024
1 parent 6d4c3a8 commit 4a56fcf
Showing 1 changed file with 31 additions and 19 deletions.
50 changes: 31 additions & 19 deletions src/hyperlight_host/src/hypervisor/hypervisor_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ limitations under the License.

#[cfg(target_os = "windows")]
use core::ffi::c_void;
use std::ops::DerefMut;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::thread;
Expand Down Expand Up @@ -125,7 +126,7 @@ impl HvHandlerExecVars {
.thread_id
.try_lock()
.map_err(|_| new_error!("Failed to get_thread_id"))?)
.ok_or_else(|| new_error!("thread_id not set"))
.ok_or_else(|| new_error!("thread_id not set"))
}

#[cfg(target_os = "windows")]
Expand Down Expand Up @@ -228,15 +229,11 @@ impl HypervisorHandler {
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
pub(crate) fn start_hypervisor_handler(
&mut self,
mut sandbox_memory_manager: SandboxMemoryManager<GuestSharedMemory>,
sandbox_memory_manager: SandboxMemoryManager<GuestSharedMemory>,
) -> Result<()> {
let configuration = self.configuration.clone();
let mut hv = set_up_hypervisor_partition(
&mut sandbox_memory_manager,
configuration.outb_handler.clone(),
)?;
#[cfg(target_os = "windows")]
let in_process = sandbox_memory_manager.is_in_process();
let in_process = sandbox_memory_manager.is_in_process();

*self.execution_variables.shm.try_lock().unwrap() = Some(sandbox_memory_manager);

Expand Down Expand Up @@ -267,18 +264,8 @@ impl HypervisorHandler {
#[cfg(target_os = "linux")]
self.execution_variables.run_cancelled.store(false);

#[cfg(target_os = "windows")]
if !in_process {
self.execution_variables
.set_partition_handle(hv.get_partition_handle())?;
}

let to_handler_rx = self.communication_channels.to_handler_rx.clone();
#[cfg(target_os = "windows")]
let execution_variables = self.execution_variables.clone();
#[cfg(target_os = "linux")]
let mut execution_variables = self.execution_variables.clone();
// ^^^ this needs to be mut on linux to set_thread_id
let from_handler_tx = self.communication_channels.from_handler_tx.clone();
let hv_handler_clone = self.clone();

Expand All @@ -295,9 +282,24 @@ impl HypervisorHandler {
thread::Builder::new()
.name("Hypervisor Handler".to_string())
.spawn(move || -> Result<()> {
let mut hv: Option<Box<dyn Hypervisor>> = None;
for action in to_handler_rx {
match action {
HypervisorHandlerAction::Initialise => {
{
hv = Some(set_up_hypervisor_partition(
execution_variables.shm.try_lock().unwrap().deref_mut().as_mut().unwrap(),
configuration.outb_handler.clone(),
)?);
}
let hv = hv.as_mut().unwrap();

#[cfg(target_os = "windows")]
if !in_process {
execution_variables
.set_partition_handle(hv.get_partition_handle())?;
}

#[cfg(target_os = "linux")]
{
// We cannot use the Killable trait, so we get the `pthread_t` via a libc
Expand Down Expand Up @@ -328,6 +330,7 @@ impl HypervisorHandler {
.shared_mem
.lock
.try_read();

let res = hv.initialise(
configuration.peb_addr.clone(),
configuration.seed,
Expand Down Expand Up @@ -362,6 +365,8 @@ impl HypervisorHandler {
}
}
HypervisorHandlerAction::DispatchCallFromHost(function_name) => {
let hv = hv.as_mut().unwrap();

// Lock to indicate an action is being performed in the hypervisor
execution_variables.running.store(true, Ordering::SeqCst);

Expand Down Expand Up @@ -735,7 +740,7 @@ impl HypervisorHandler {
0,
0,
)
.map_err(|e| new_error!("Failed to cancel guest execution {:?}", e))?;
.map_err(|e| new_error!("Failed to cancel guest execution {:?}", e))?;
}
}
// if running in-process on windows, we currently have no way of cancelling the execution
Expand Down Expand Up @@ -911,7 +916,7 @@ mod tests {
None,
None,
)
.unwrap();
.unwrap();

usbox.evolve(Noop::default()).unwrap()
}
Expand Down Expand Up @@ -944,6 +949,13 @@ mod tests {
}
}

#[test]
fn create_10_sandboxes() {
for _ in 0..10 {
create_multi_use_sandbox();
}
}

#[test]
fn hello_world() -> Result<()> {
let mut sandbox = create_multi_use_sandbox();
Expand Down

0 comments on commit 4a56fcf

Please sign in to comment.