From d9c2455db6a94392c4bf05b6c8bcbedcc443e2d8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 May 2025 08:20:19 +0000 Subject: [PATCH 1/5] Initial plan for issue From 132d0f45f61181afc9ce81d19173cf38df2c7c5d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 21 May 2025 15:05:13 +0000 Subject: [PATCH 2/5] Remove OutBHandlerWrapper type Co-authored-by: simongdavies <1397489+simongdavies@users.noreply.github.com> --- src/hyperlight_host/src/hypervisor/handlers.rs | 8 -------- .../src/hypervisor/hyperv_linux.rs | 9 +++++---- .../src/hypervisor/hyperv_windows.rs | 9 +++++---- .../src/hypervisor/hypervisor_handler.rs | 4 ++-- src/hyperlight_host/src/hypervisor/kvm.rs | 9 ++++----- src/hyperlight_host/src/hypervisor/mod.rs | 16 +++++++--------- src/hyperlight_host/src/sandbox/outb.rs | 6 +++--- 7 files changed, 26 insertions(+), 35 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/handlers.rs b/src/hyperlight_host/src/hypervisor/handlers.rs index 9dbb948af..ac8106869 100644 --- a/src/hyperlight_host/src/hypervisor/handlers.rs +++ b/src/hyperlight_host/src/hypervisor/handlers.rs @@ -28,14 +28,6 @@ pub trait OutBHandlerCaller: Sync + Send { fn call(&mut self, port: u16, payload: u32) -> Result<()>; } -/// A convenient type representing a common way `OutBHandler` implementations -/// are passed as parameters to functions -/// -/// Note: This needs to be wrapped in a Mutex to be able to grab a mutable -/// reference to the underlying data (i.e., handle_outb in `Sandbox` takes -/// a &mut self). -pub type OutBHandlerWrapper = Arc>; - pub(crate) type OutBHandlerFunction = Box Result<()> + Send>; /// A `OutBHandler` implementation using a `OutBHandlerFunction` diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index 85dc514b5..506753f49 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -25,6 +25,7 @@ extern crate mshv_bindings3 as mshv_bindings; extern crate mshv_ioctls3 as mshv_ioctls; use std::fmt::{Debug, Formatter}; +use std::sync::{Arc, Mutex}; use log::{error, LevelFilter}; #[cfg(mshv2)] @@ -54,7 +55,7 @@ use super::fpu::{FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT}; use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, MshvDebug}; #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; -use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; +use super::handlers::{MemAccessHandlerWrapper, OutBHandler, OutBHandlerCaller}; use super::{ Hypervisor, VirtualCPU, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, @@ -459,7 +460,7 @@ impl Hypervisor for HypervLinuxDriver { peb_addr: RawPtr, seed: u64, page_size: u32, - outb_hdl: OutBHandlerWrapper, + outb_hdl: Arc>, mem_access_hdl: MemAccessHandlerWrapper, hv_handler: Option, max_guest_log_level: Option, @@ -501,7 +502,7 @@ impl Hypervisor for HypervLinuxDriver { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, mem_access_fn: MemAccessHandlerWrapper, hv_handler: Option, #[cfg(gdb)] dbg_mem_access_fn: DbgMemAccessHandlerWrapper, @@ -544,7 +545,7 @@ impl Hypervisor for HypervLinuxDriver { data: Vec, rip: u64, instruction_length: u64, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, ) -> Result<()> { let mut padded = [0u8; 4]; let copy_len = data.len().min(4); diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index abc2b77cf..799ef115c 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -18,6 +18,7 @@ use core::ffi::c_void; use std::fmt; use std::fmt::{Debug, Formatter}; use std::string::String; +use std::sync::{Arc, Mutex}; use hyperlight_common::mem::PAGE_SIZE_USIZE; use log::LevelFilter; @@ -31,7 +32,7 @@ use windows::Win32::System::Hypervisor::{ use super::fpu::{FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT}; #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; -use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; +use super::handlers::{MemAccessHandlerWrapper, OutBHandler, OutBHandlerCaller}; use super::surrogate_process::SurrogateProcess; use super::surrogate_process_manager::*; use super::windows_hypervisor_platform::{VMPartition, VMProcessor}; @@ -305,7 +306,7 @@ impl Hypervisor for HypervWindowsDriver { peb_address: RawPtr, seed: u64, page_size: u32, - outb_hdl: OutBHandlerWrapper, + outb_hdl: Arc>, mem_access_hdl: MemAccessHandlerWrapper, hv_handler: Option, max_guest_log_level: Option, @@ -347,7 +348,7 @@ impl Hypervisor for HypervWindowsDriver { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, - outb_hdl: OutBHandlerWrapper, + outb_hdl: Arc>, mem_access_hdl: MemAccessHandlerWrapper, hv_handler: Option, #[cfg(gdb)] dbg_mem_access_hdl: DbgMemAccessHandlerWrapper, @@ -388,7 +389,7 @@ impl Hypervisor for HypervWindowsDriver { data: Vec, rip: u64, instruction_length: u64, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, ) -> Result<()> { let mut padded = [0u8; 4]; let copy_len = data.len().min(4); diff --git a/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs b/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs index 8e351708c..7f318e46d 100644 --- a/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs +++ b/src/hyperlight_host/src/hypervisor/hypervisor_handler.rs @@ -39,7 +39,7 @@ use windows::Win32::System::Hypervisor::{WHvCancelRunVirtualProcessor, WHV_PARTI use super::gdb::create_gdb_thread; #[cfg(gdb)] use crate::hypervisor::handlers::DbgMemAccessHandlerWrapper; -use crate::hypervisor::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; +use crate::hypervisor::handlers::{MemAccessHandlerWrapper, OutBHandler}; #[cfg(target_os = "windows")] use crate::hypervisor::wrappers::HandleWrapper; use crate::hypervisor::Hypervisor; @@ -184,7 +184,7 @@ pub(crate) struct HvHandlerConfig { pub(crate) dispatch_function_addr: Arc>>, pub(crate) max_init_time: Duration, pub(crate) max_exec_time: Duration, - pub(crate) outb_handler: OutBHandlerWrapper, + pub(crate) outb_handler: Arc>, pub(crate) mem_access_handler: MemAccessHandlerWrapper, pub(crate) max_wait_for_cancellation: Duration, pub(crate) max_guest_log_level: Option, diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index 3dd1cb1fc..469de6177 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -16,7 +16,6 @@ limitations under the License. use std::convert::TryFrom; use std::fmt::Debug; -#[cfg(gdb)] use std::sync::{Arc, Mutex}; use kvm_bindings::{kvm_fpu, kvm_regs, kvm_userspace_memory_region, KVM_MEM_READONLY}; @@ -30,7 +29,7 @@ use super::fpu::{FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT}; use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, KvmDebug, VcpuStopReason}; #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; -use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; +use super::handlers::{MemAccessHandlerWrapper, OutBHandler, OutBHandlerCaller}; use super::{ HyperlightExit, Hypervisor, VirtualCPU, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, @@ -404,7 +403,7 @@ impl Hypervisor for KVMDriver { peb_addr: RawPtr, seed: u64, page_size: u32, - outb_hdl: OutBHandlerWrapper, + outb_hdl: Arc>, mem_access_hdl: MemAccessHandlerWrapper, hv_handler: Option, max_guest_log_level: Option, @@ -445,7 +444,7 @@ impl Hypervisor for KVMDriver { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, mem_access_fn: MemAccessHandlerWrapper, hv_handler: Option, #[cfg(gdb)] dbg_mem_access_fn: DbgMemAccessHandlerWrapper, @@ -487,7 +486,7 @@ impl Hypervisor for KVMDriver { data: Vec, _rip: u64, _instruction_length: u64, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, ) -> Result<()> { // KVM does not need RIP or instruction length, as it automatically sets the RIP diff --git a/src/hyperlight_host/src/hypervisor/mod.rs b/src/hyperlight_host/src/hypervisor/mod.rs index 62cebe829..e37969ef9 100644 --- a/src/hyperlight_host/src/hypervisor/mod.rs +++ b/src/hyperlight_host/src/hypervisor/mod.rs @@ -67,9 +67,7 @@ use gdb::VcpuStopReason; #[cfg(gdb)] use self::handlers::{DbgMemAccessHandlerCaller, DbgMemAccessHandlerWrapper}; -use self::handlers::{ - MemAccessHandlerCaller, MemAccessHandlerWrapper, OutBHandlerCaller, OutBHandlerWrapper, -}; +use self::handlers::{MemAccessHandlerCaller, MemAccessHandlerWrapper, OutBHandler}; use crate::hypervisor::hypervisor_handler::HypervisorHandler; use crate::mem::ptr::RawPtr; @@ -124,7 +122,7 @@ pub(crate) trait Hypervisor: Debug + Sync + Send { peb_addr: RawPtr, seed: u64, page_size: u32, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, mem_access_fn: MemAccessHandlerWrapper, hv_handler: Option, guest_max_log_level: Option, @@ -141,7 +139,7 @@ pub(crate) trait Hypervisor: Debug + Sync + Send { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, mem_access_fn: MemAccessHandlerWrapper, hv_handler: Option, #[cfg(gdb)] dbg_mem_access_fn: DbgMemAccessHandlerWrapper, @@ -154,7 +152,7 @@ pub(crate) trait Hypervisor: Debug + Sync + Send { data: Vec, rip: u64, instruction_length: u64, - outb_handle_fn: OutBHandlerWrapper, + outb_handle_fn: Arc>, ) -> Result<()>; /// Run the vCPU @@ -254,7 +252,7 @@ impl VirtualCPU { pub fn run( hv: &mut dyn Hypervisor, hv_handler: Option, - outb_handle_fn: Arc>, + outb_handle_fn: Arc>, mem_access_fn: Arc>, #[cfg(gdb)] dbg_mem_access_fn: Arc>, ) -> Result<()> { @@ -341,7 +339,7 @@ pub(crate) mod tests { #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; - use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper}; + use super::handlers::{MemAccessHandlerWrapper, OutBHandler}; use crate::hypervisor::hypervisor_handler::{ HvHandlerConfig, HypervisorHandler, HypervisorHandlerAction, }; @@ -351,7 +349,7 @@ pub(crate) mod tests { use crate::{new_error, Result}; pub(crate) fn test_initialise( - outb_hdl: OutBHandlerWrapper, + outb_hdl: Arc>, mem_access_hdl: MemAccessHandlerWrapper, #[cfg(gdb)] dbg_mem_access_fn: DbgMemAccessHandlerWrapper, ) -> Result<()> { diff --git a/src/hyperlight_host/src/sandbox/outb.rs b/src/hyperlight_host/src/sandbox/outb.rs index 4dc91207f..6f04a75e5 100644 --- a/src/hyperlight_host/src/sandbox/outb.rs +++ b/src/hyperlight_host/src/sandbox/outb.rs @@ -26,7 +26,7 @@ use tracing_log::format_trace; use super::host_funcs::FunctionRegistry; use super::mem_mgr::MemMgrWrapper; -use crate::hypervisor::handlers::{OutBHandler, OutBHandlerFunction, OutBHandlerWrapper}; +use crate::hypervisor::handlers::{OutBHandler, OutBHandlerFunction}; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::shared_mem::HostSharedMemory; use crate::{new_error, HyperlightError, Result}; @@ -184,14 +184,14 @@ fn handle_outb_impl( } /// Given a `MemMgrWrapper` and ` HostFuncsWrapper` -- both passed by _value_ -/// -- return an `OutBHandlerWrapper` wrapping the core OUTB handler logic. +/// -- return an `Arc>` wrapping the core OUTB handler logic. /// /// TODO: pass at least the `host_funcs_wrapper` param by reference. #[instrument(skip_all, parent = Span::current(), level= "Trace")] pub(crate) fn outb_handler_wrapper( mut mem_mgr_wrapper: MemMgrWrapper, host_funcs_wrapper: Arc>, -) -> OutBHandlerWrapper { +) -> Arc> { let outb_func: OutBHandlerFunction = Box::new(move |port, payload| { handle_outb_impl( &mut mem_mgr_wrapper, From 4c61fc467c7f4f6e6b540d422df709a8a6f7f153 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Jun 2025 18:30:05 +0000 Subject: [PATCH 3/5] Remove dyn OutBHandlerCaller trait entirely Co-authored-by: simongdavies <1397489+simongdavies@users.noreply.github.com> --- src/hyperlight_host/src/hypervisor/handlers.rs | 13 +++---------- src/hyperlight_host/src/hypervisor/hyperv_linux.rs | 2 +- .../src/hypervisor/hyperv_windows.rs | 2 +- src/hyperlight_host/src/hypervisor/kvm.rs | 2 +- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/handlers.rs b/src/hyperlight_host/src/hypervisor/handlers.rs index ac8106869..58872139f 100644 --- a/src/hyperlight_host/src/hypervisor/handlers.rs +++ b/src/hyperlight_host/src/hypervisor/handlers.rs @@ -20,14 +20,6 @@ use tracing::{instrument, Span}; use crate::{new_error, Result}; -/// The trait representing custom logic to handle the case when -/// a Hypervisor's virtual CPU (vCPU) informs Hyperlight the guest -/// has initiated an outb operation. -pub trait OutBHandlerCaller: Sync + Send { - /// Function that gets called when an outb operation has occurred. - fn call(&mut self, port: u16, payload: u32) -> Result<()>; -} - pub(crate) type OutBHandlerFunction = Box Result<()> + Send>; /// A `OutBHandler` implementation using a `OutBHandlerFunction` @@ -42,9 +34,10 @@ impl From for OutBHandler { } } -impl OutBHandlerCaller for OutBHandler { +impl OutBHandler { + /// Function that gets called when an outb operation has occurred. #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - fn call(&mut self, port: u16, payload: u32) -> Result<()> { + pub fn call(&mut self, port: u16, payload: u32) -> Result<()> { let mut func = self .0 .try_lock() diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index 506753f49..dc71aff64 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -55,7 +55,7 @@ use super::fpu::{FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT}; use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, MshvDebug}; #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; -use super::handlers::{MemAccessHandlerWrapper, OutBHandler, OutBHandlerCaller}; +use super::handlers::{MemAccessHandlerWrapper, OutBHandler}; use super::{ Hypervisor, VirtualCPU, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 799ef115c..186606a39 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -32,7 +32,7 @@ use windows::Win32::System::Hypervisor::{ use super::fpu::{FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT}; #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; -use super::handlers::{MemAccessHandlerWrapper, OutBHandler, OutBHandlerCaller}; +use super::handlers::{MemAccessHandlerWrapper, OutBHandler}; use super::surrogate_process::SurrogateProcess; use super::surrogate_process_manager::*; use super::windows_hypervisor_platform::{VMPartition, VMProcessor}; diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index 469de6177..d32e9d3f6 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -29,7 +29,7 @@ use super::fpu::{FP_CONTROL_WORD_DEFAULT, FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT}; use super::gdb::{DebugCommChannel, DebugMsg, DebugResponse, GuestDebug, KvmDebug, VcpuStopReason}; #[cfg(gdb)] use super::handlers::DbgMemAccessHandlerWrapper; -use super::handlers::{MemAccessHandlerWrapper, OutBHandler, OutBHandlerCaller}; +use super::handlers::{MemAccessHandlerWrapper, OutBHandler}; use super::{ HyperlightExit, Hypervisor, VirtualCPU, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP, CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE, From 8d15b69ae8233668634a2f9e65bc3a98273e5788 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:20:50 +0000 Subject: [PATCH 4/5] Remove dynamic dispatch from OutBHandlerFunction Co-authored-by: simongdavies <1397489+simongdavies@users.noreply.github.com> --- .../src/hypervisor/handlers.rs | 28 +---------- .../src/hypervisor/hyperv_windows.rs | 12 +++-- src/hyperlight_host/src/hypervisor/kvm.rs | 12 +++-- src/hyperlight_host/src/sandbox/outb.rs | 48 ++++++++++++++----- 4 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/handlers.rs b/src/hyperlight_host/src/hypervisor/handlers.rs index 58872139f..95f225c40 100644 --- a/src/hyperlight_host/src/hypervisor/handlers.rs +++ b/src/hyperlight_host/src/hypervisor/handlers.rs @@ -18,34 +18,10 @@ use std::sync::{Arc, Mutex}; use tracing::{instrument, Span}; +/// Re-export OutBHandler from the outb module where it naturally belongs +pub(crate) use crate::sandbox::outb::OutBHandler; use crate::{new_error, Result}; -pub(crate) type OutBHandlerFunction = Box Result<()> + Send>; - -/// A `OutBHandler` implementation using a `OutBHandlerFunction` -/// -/// Note: This handler must live no longer than the `Sandbox` to which it belongs -pub(crate) struct OutBHandler(Arc>); - -impl From for OutBHandler { - #[instrument(skip_all, parent = Span::current(), level= "Trace")] - fn from(func: OutBHandlerFunction) -> Self { - Self(Arc::new(Mutex::new(func))) - } -} - -impl OutBHandler { - /// Function that gets called when an outb operation has occurred. - #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] - pub fn call(&mut self, port: u16, payload: u32) -> Result<()> { - let mut func = self - .0 - .try_lock() - .map_err(|e| new_error!("Error locking at {}:{}: {}", file!(), line!(), e))?; - func(port, payload) - } -} - /// The trait representing custom logic to handle the case when /// a Hypervisor's virtual CPU (vCPU) informs Hyperlight a memory access /// outside the designated address space has occurred. diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 186606a39..34bef6779 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -505,15 +505,21 @@ pub mod tests { use crate::hypervisor::handlers::{MemAccessHandler, OutBHandler}; use crate::hypervisor::tests::test_initialise; + use crate::sandbox::uninitialized::{GuestBinary, UninitializedSandbox}; use crate::Result; + use hyperlight_testing::dummy_guest_as_string; #[test] #[serial] fn test_init() { + let filename = dummy_guest_as_string().expect("Guest Binary Missing"); + let sandbox = UninitializedSandbox::new(GuestBinary::FilePath(filename), None).unwrap(); + let (hshm, gshm) = sandbox.mgr.build(); + drop(gshm); + let host_funcs = sandbox.host_funcs.clone(); + let outb_handler = { - let func: Box Result<()> + Send> = - Box::new(|_, _| -> Result<()> { Ok(()) }); - Arc::new(Mutex::new(OutBHandler::from(func))) + crate::sandbox::outb::outb_handler_wrapper(hshm.clone(), host_funcs) }; let mem_access_handler = { let func: Box Result<()> + Send> = Box::new(|| -> Result<()> { Ok(()) }); diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index d32e9d3f6..96388a7db 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -641,7 +641,9 @@ mod tests { use crate::hypervisor::handlers::DbgMemAccessHandlerCaller; use crate::hypervisor::handlers::{MemAccessHandler, OutBHandler}; use crate::hypervisor::tests::test_initialise; + use crate::sandbox::uninitialized::{GuestBinary, UninitializedSandbox}; use crate::Result; + use hyperlight_testing::dummy_guest_as_string; #[cfg(gdb)] struct DbgMemAccessHandler {} @@ -667,10 +669,14 @@ mod tests { return; } + let filename = dummy_guest_as_string().expect("Guest Binary Missing"); + let sandbox = UninitializedSandbox::new(GuestBinary::FilePath(filename), None).unwrap(); + let (hshm, gshm) = sandbox.mgr.build(); + drop(gshm); + let host_funcs = sandbox.host_funcs.clone(); + let outb_handler: Arc> = { - let func: Box Result<()> + Send> = - Box::new(|_, _| -> Result<()> { Ok(()) }); - Arc::new(Mutex::new(OutBHandler::from(func))) + crate::sandbox::outb::outb_handler_wrapper(hshm.clone(), host_funcs) }; let mem_access_handler = { let func: Box Result<()> + Send> = Box::new(|| -> Result<()> { Ok(()) }); diff --git a/src/hyperlight_host/src/sandbox/outb.rs b/src/hyperlight_host/src/sandbox/outb.rs index 6f04a75e5..5620e6f06 100644 --- a/src/hyperlight_host/src/sandbox/outb.rs +++ b/src/hyperlight_host/src/sandbox/outb.rs @@ -26,11 +26,43 @@ use tracing_log::format_trace; use super::host_funcs::FunctionRegistry; use super::mem_mgr::MemMgrWrapper; -use crate::hypervisor::handlers::{OutBHandler, OutBHandlerFunction}; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::shared_mem::HostSharedMemory; use crate::{new_error, HyperlightError, Result}; +/// A `OutBHandler` implementation that contains the required data directly +/// +/// Note: This handler must live no longer than the `Sandbox` to which it belongs +pub(crate) struct OutBHandler { + mem_mgr_wrapper: MemMgrWrapper, + host_funcs_wrapper: Arc>, +} + +impl OutBHandler { + /// Create a new OutBHandler with the required dependencies + #[instrument(skip_all, parent = Span::current(), level= "Trace")] + pub fn new( + mem_mgr_wrapper: MemMgrWrapper, + host_funcs_wrapper: Arc>, + ) -> Self { + Self { + mem_mgr_wrapper, + host_funcs_wrapper, + } + } + + /// Function that gets called when an outb operation has occurred. + #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] + pub fn call(&mut self, port: u16, payload: u32) -> Result<()> { + handle_outb_impl( + &mut self.mem_mgr_wrapper, + self.host_funcs_wrapper.clone(), + port, + payload, + ) + } +} + #[instrument(err(Debug), skip_all, parent = Span::current(), level="Trace")] pub(super) fn outb_log(mgr: &mut SandboxMemoryManager) -> Result<()> { // This code will create either a logging record or a tracing record for the GuestLogData depending on if the host has set up a tracing subscriber. @@ -146,7 +178,7 @@ fn outb_abort(mem_mgr: &mut MemMgrWrapper, data: u32) -> Resul /// Handles OutB operations from the guest. #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] -fn handle_outb_impl( +pub(crate) fn handle_outb_impl( mem_mgr: &mut MemMgrWrapper, host_funcs: Arc>, port: u16, @@ -189,18 +221,10 @@ fn handle_outb_impl( /// TODO: pass at least the `host_funcs_wrapper` param by reference. #[instrument(skip_all, parent = Span::current(), level= "Trace")] pub(crate) fn outb_handler_wrapper( - mut mem_mgr_wrapper: MemMgrWrapper, + mem_mgr_wrapper: MemMgrWrapper, host_funcs_wrapper: Arc>, ) -> Arc> { - let outb_func: OutBHandlerFunction = Box::new(move |port, payload| { - handle_outb_impl( - &mut mem_mgr_wrapper, - host_funcs_wrapper.clone(), - port, - payload, - ) - }); - let outb_hdl = OutBHandler::from(outb_func); + let outb_hdl = OutBHandler::new(mem_mgr_wrapper, host_funcs_wrapper); Arc::new(Mutex::new(outb_hdl)) } From 7e85790995f06bb8cfef659d89a499c05fa0cffb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 3 Jul 2025 16:43:20 +0000 Subject: [PATCH 5/5] Fix formatting in hypervisor test files Co-authored-by: simongdavies <1397489+simongdavies@users.noreply.github.com> Signed-off-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jsturtevant <648372+jsturtevant@users.noreply.github.com> --- src/hyperlight_host/src/hypervisor/hyperv_windows.rs | 8 +++----- src/hyperlight_host/src/hypervisor/kvm.rs | 10 +++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 34bef6779..8a28a3f17 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -501,13 +501,13 @@ impl Hypervisor for HypervWindowsDriver { pub mod tests { use std::sync::{Arc, Mutex}; + use hyperlight_testing::dummy_guest_as_string; use serial_test::serial; use crate::hypervisor::handlers::{MemAccessHandler, OutBHandler}; use crate::hypervisor::tests::test_initialise; use crate::sandbox::uninitialized::{GuestBinary, UninitializedSandbox}; use crate::Result; - use hyperlight_testing::dummy_guest_as_string; #[test] #[serial] @@ -517,10 +517,8 @@ pub mod tests { let (hshm, gshm) = sandbox.mgr.build(); drop(gshm); let host_funcs = sandbox.host_funcs.clone(); - - let outb_handler = { - crate::sandbox::outb::outb_handler_wrapper(hshm.clone(), host_funcs) - }; + + let outb_handler = { crate::sandbox::outb::outb_handler_wrapper(hshm.clone(), host_funcs) }; let mem_access_handler = { let func: Box Result<()> + Send> = Box::new(|| -> Result<()> { Ok(()) }); Arc::new(Mutex::new(MemAccessHandler::from(func))) diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index 96388a7db..504ecb21e 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -637,13 +637,14 @@ impl Hypervisor for KVMDriver { mod tests { use std::sync::{Arc, Mutex}; + use hyperlight_testing::dummy_guest_as_string; + #[cfg(gdb)] use crate::hypervisor::handlers::DbgMemAccessHandlerCaller; use crate::hypervisor::handlers::{MemAccessHandler, OutBHandler}; use crate::hypervisor::tests::test_initialise; use crate::sandbox::uninitialized::{GuestBinary, UninitializedSandbox}; use crate::Result; - use hyperlight_testing::dummy_guest_as_string; #[cfg(gdb)] struct DbgMemAccessHandler {} @@ -674,10 +675,9 @@ mod tests { let (hshm, gshm) = sandbox.mgr.build(); drop(gshm); let host_funcs = sandbox.host_funcs.clone(); - - let outb_handler: Arc> = { - crate::sandbox::outb::outb_handler_wrapper(hshm.clone(), host_funcs) - }; + + let outb_handler: Arc> = + { crate::sandbox::outb::outb_handler_wrapper(hshm.clone(), host_funcs) }; let mem_access_handler = { let func: Box Result<()> + Send> = Box::new(|| -> Result<()> { Ok(()) }); Arc::new(Mutex::new(MemAccessHandler::from(func)))