From a3dc80d17577cecf4ea9fc76a0443cc9da669114 Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Thu, 20 Nov 2025 14:22:37 -0800 Subject: [PATCH 1/4] Remove mem_mgr and host_func from drivers struct Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .../src/hypervisor/hyperv_linux.rs | 75 +++++------------ .../src/hypervisor/hyperv_windows.rs | 80 +++++-------------- src/hyperlight_host/src/hypervisor/kvm.rs | 75 +++++------------ src/hyperlight_host/src/hypervisor/mod.rs | 30 ++++--- .../src/sandbox/initialized_multi_use.rs | 7 +- src/hyperlight_host/src/sandbox/mod.rs | 2 +- src/hyperlight_host/src/sandbox/outb.rs | 5 +- .../src/sandbox/uninitialized.rs | 10 +-- .../src/sandbox/uninitialized_evolve.rs | 6 +- 9 files changed, 95 insertions(+), 195 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index 7649aae2e..bc157db82 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -274,8 +274,6 @@ pub(crate) struct HypervLinuxDriver { orig_rsp: GuestPtr, entrypoint: u64, interrupt_handle: Arc, - mem_mgr: Option>, - host_funcs: Option>>, sandbox_regions: Vec, // Initially mapped regions when sandbox is created mmap_regions: Vec, // Later mapped regions @@ -405,8 +403,6 @@ impl HypervLinuxDriver { entrypoint: entrypoint_ptr.absolute()?, orig_rsp: rsp_ptr, interrupt_handle: interrupt_handle.clone(), - mem_mgr: None, - host_funcs: None, #[cfg(gdb)] debug, #[cfg(gdb)] @@ -467,13 +463,11 @@ impl Hypervisor for HypervLinuxDriver { peb_addr: RawPtr, seed: u64, page_size: u32, - mem_mgr: SandboxMemoryManager, - host_funcs: Arc>, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, max_guest_log_level: Option, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()> { - self.mem_mgr = Some(mem_mgr); - self.host_funcs = Some(host_funcs); self.page_size = page_size as usize; let max_guest_log_level: u64 = match max_guest_log_level { @@ -501,6 +495,8 @@ impl Hypervisor for HypervLinuxDriver { VirtualCPU::run( self.as_mut_hypervisor(), interrupt_handle, + mem_mgr, + host_funcs, #[cfg(gdb)] dbg_mem_access_fn, ) @@ -545,6 +541,8 @@ impl Hypervisor for HypervLinuxDriver { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()> { // Reset general purpose registers, then set RIP and RSP @@ -565,6 +563,8 @@ impl Hypervisor for HypervLinuxDriver { VirtualCPU::run( self.as_mut_hypervisor(), interrupt_handle, + mem_mgr, + host_funcs, #[cfg(gdb)] dbg_mem_access_fn, ) @@ -577,47 +577,15 @@ impl Hypervisor for HypervLinuxDriver { data: Vec, rip: u64, instruction_length: u64, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, ) -> Result<()> { let mut padded = [0u8; 4]; let copy_len = data.len().min(4); padded[..copy_len].copy_from_slice(&data[..copy_len]); let val = u32::from_le_bytes(padded); - #[cfg(feature = "mem_profile")] - { - // We need to handle the borrow checker issue where we need both: - // - &mut SandboxMemoryManager (from self.mem_mgr) - // - &mut dyn Hypervisor (from self) - // We'll use a temporary approach to extract the mem_mgr temporarily - let mem_mgr_option = self.mem_mgr.take(); - let mut mem_mgr = mem_mgr_option - .ok_or_else(|| new_error!("mem_mgr should be initialized before handling IO"))?; - let host_funcs = self - .host_funcs - .as_ref() - .ok_or_else(|| new_error!("host_funcs should be initialized before handling IO"))? - .clone(); - - handle_outb(&mut mem_mgr, host_funcs, self, port, val)?; - - // Put the mem_mgr back - self.mem_mgr = Some(mem_mgr); - } - - #[cfg(not(feature = "mem_profile"))] - { - let mem_mgr = self - .mem_mgr - .as_mut() - .ok_or_else(|| new_error!("mem_mgr should be initialized before handling IO"))?; - let host_funcs = self - .host_funcs - .as_ref() - .ok_or_else(|| new_error!("host_funcs should be initialized before handling IO"))? - .clone(); - - handle_outb(mem_mgr, host_funcs, port, val)?; - } + handle_outb(mem_mgr, host_funcs, port, val, self)?; // update rip self.vcpu_fd.set_reg(&[hv_register_assoc { @@ -985,23 +953,18 @@ impl Hypervisor for HypervLinuxDriver { Ok(()) } - fn check_stack_guard(&self) -> Result { - if let Some(mgr) = self.mem_mgr.as_ref() { - mgr.check_stack_guard() - } else { - Err(new_error!("Memory manager is not initialized")) - } + fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result { + mem_mgr.check_stack_guard() } #[cfg(feature = "trace_guest")] - fn handle_trace(&mut self, tc: &mut crate::sandbox::trace::TraceContext) -> Result<()> { + fn handle_trace( + &mut self, + tc: &mut crate::sandbox::trace::TraceContext, + mem_mgr: &mut SandboxMemoryManager, + ) -> Result<()> { let regs = self.regs()?; - tc.handle_trace( - ®s, - self.mem_mgr.as_mut().ok_or_else(|| { - new_error!("Memory manager is not initialized before handling trace") - })?, - ) + tc.handle_trace(®s, mem_mgr) } #[cfg(feature = "mem_profile")] diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 1be0ea502..590409005 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -54,7 +54,9 @@ use crate::sandbox::outb::handle_outb; use crate::sandbox::trace::MemTraceInfo; #[cfg(crashdump)] use crate::sandbox::uninitialized::SandboxRuntimeConfig; -use crate::{Result, debug, log_then_return, new_error}; +use crate::{Result, debug, log_then_return}; +#[cfg(gdb)] +use crate::new_error; #[cfg(gdb)] mod debug { @@ -261,8 +263,6 @@ pub(crate) struct HypervWindowsDriver { entrypoint: u64, orig_rsp: GuestPtr, interrupt_handle: Arc, - mem_mgr: Option>, - host_funcs: Option>>, sandbox_regions: Vec, // Initially mapped regions when sandbox is created mmap_regions: Vec, // Later mapped regions @@ -335,8 +335,6 @@ impl HypervWindowsDriver { entrypoint, orig_rsp: GuestPtr::try_from(RawPtr::from(rsp))?, interrupt_handle: interrupt_handle.clone(), - mem_mgr: None, - host_funcs: None, sandbox_regions: mem_regions, mmap_regions: Vec::new(), #[cfg(gdb)] @@ -408,14 +406,11 @@ impl Hypervisor for HypervWindowsDriver { peb_address: RawPtr, seed: u64, page_size: u32, - mem_mgr: SandboxMemoryManager, - host_funcs: Arc>, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, max_guest_log_level: Option, #[cfg(gdb)] dbg_mem_access_hdl: Arc>>, ) -> Result<()> { - self.mem_mgr = Some(mem_mgr); - self.host_funcs = Some(host_funcs); - let max_guest_log_level: u64 = match max_guest_log_level { Some(level) => level as u64, None => self.get_max_log_level().into(), @@ -440,6 +435,8 @@ impl Hypervisor for HypervWindowsDriver { VirtualCPU::run( self.as_mut_hypervisor(), interrupt_handle, + mem_mgr, + host_funcs, #[cfg(gdb)] dbg_mem_access_hdl, ) @@ -463,6 +460,8 @@ impl Hypervisor for HypervWindowsDriver { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, #[cfg(gdb)] dbg_mem_access_hdl: Arc>>, ) -> Result<()> { // Reset general purpose registers, then set RIP and RSP @@ -481,6 +480,8 @@ impl Hypervisor for HypervWindowsDriver { VirtualCPU::run( self.as_mut_hypervisor(), interrupt_handle, + mem_mgr, + host_funcs, #[cfg(gdb)] dbg_mem_access_hdl, ) @@ -493,47 +494,15 @@ impl Hypervisor for HypervWindowsDriver { data: Vec, rip: u64, instruction_length: u64, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, ) -> Result<()> { let mut padded = [0u8; 4]; let copy_len = data.len().min(4); padded[..copy_len].copy_from_slice(&data[..copy_len]); let val = u32::from_le_bytes(padded); - #[cfg(feature = "mem_profile")] - { - // We need to handle the borrow checker issue where we need both: - // - &mut SandboxMemoryManager (from self.mem_mgr.as_mut()) - // - &mut dyn Hypervisor (from self) - // We'll use a temporary approach to extract the mem_mgr temporarily - let mem_mgr_option = self.mem_mgr.take(); - let mut mem_mgr = mem_mgr_option - .ok_or_else(|| new_error!("mem_mgr should be initialized before handling IO"))?; - let host_funcs = self - .host_funcs - .as_ref() - .ok_or_else(|| new_error!("host_funcs should be initialized before handling IO"))? - .clone(); - - handle_outb(&mut mem_mgr, host_funcs, self, port, val)?; - - // Put the mem_mgr back - self.mem_mgr = Some(mem_mgr); - } - - #[cfg(not(feature = "mem_profile"))] - { - let mem_mgr = self - .mem_mgr - .as_mut() - .ok_or_else(|| new_error!("mem_mgr should be initialized before handling IO"))?; - let host_funcs = self - .host_funcs - .as_ref() - .ok_or_else(|| new_error!("host_funcs should be initialized before handling IO"))? - .clone(); - - handle_outb(mem_mgr, host_funcs, port, val)?; - } + handle_outb(mem_mgr, host_funcs, port, val, self)?; let mut regs = self.regs()?; regs.rip = rip + instruction_length; @@ -879,23 +848,18 @@ impl Hypervisor for HypervWindowsDriver { Ok(()) } - fn check_stack_guard(&self) -> Result { - if let Some(mgr) = self.mem_mgr.as_ref() { - mgr.check_stack_guard() - } else { - Err(new_error!("Memory manager is not initialized")) - } + fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result { + mem_mgr.check_stack_guard() } #[cfg(feature = "trace_guest")] - fn handle_trace(&mut self, tc: &mut crate::sandbox::trace::TraceContext) -> Result<()> { + fn handle_trace( + &mut self, + tc: &mut crate::sandbox::trace::TraceContext, + mem_mgr: &mut SandboxMemoryManager, + ) -> Result<()> { let regs = self.regs()?; - tc.handle_trace( - ®s, - self.mem_mgr.as_mut().ok_or_else(|| { - new_error!("Memory manager is not initialized before handling trace") - })?, - ) + tc.handle_trace(®s, mem_mgr) } #[cfg(feature = "mem_profile")] diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index 032468d2d..e6b31da0b 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -272,8 +272,6 @@ pub(crate) struct KVMDriver { entrypoint: u64, orig_rsp: GuestPtr, interrupt_handle: Arc, - mem_mgr: Option>, - host_funcs: Option>>, sandbox_regions: Vec, // Initially mapped regions when sandbox is created mmap_regions: Vec<(MemoryRegion, u32)>, // Later mapped regions (region, slot number) @@ -365,8 +363,6 @@ impl KVMDriver { mmap_regions: Vec::new(), freed_slots: Vec::new(), interrupt_handle: interrupt_handle.clone(), - mem_mgr: None, - host_funcs: None, #[cfg(gdb)] debug, #[cfg(gdb)] @@ -428,13 +424,11 @@ impl Hypervisor for KVMDriver { peb_addr: RawPtr, seed: u64, page_size: u32, - mem_mgr: SandboxMemoryManager, - host_funcs: Arc>, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, max_guest_log_level: Option, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()> { - self.mem_mgr = Some(mem_mgr); - self.host_funcs = Some(host_funcs); self.page_size = page_size as usize; let max_guest_log_level: u64 = match max_guest_log_level { @@ -461,6 +455,8 @@ impl Hypervisor for KVMDriver { VirtualCPU::run( self.as_mut_hypervisor(), interrupt_handle, + mem_mgr, + host_funcs, #[cfg(gdb)] dbg_mem_access_fn, ) @@ -529,6 +525,8 @@ impl Hypervisor for KVMDriver { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()> { // Reset general purpose registers, then set RIP and RSP @@ -548,6 +546,8 @@ impl Hypervisor for KVMDriver { VirtualCPU::run( self.as_mut_hypervisor(), interrupt_handle, + mem_mgr, + host_funcs, #[cfg(gdb)] dbg_mem_access_fn, )?; @@ -562,6 +562,8 @@ impl Hypervisor for KVMDriver { data: Vec, _rip: u64, _instruction_length: u64, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, ) -> Result<()> { // KVM does not need RIP or instruction length, as it automatically sets the RIP @@ -576,41 +578,7 @@ impl Hypervisor for KVMDriver { padded[..copy_len].copy_from_slice(&data[..copy_len]); let value = u32::from_le_bytes(padded); - #[cfg(feature = "mem_profile")] - { - // We need to handle the borrow checker issue where we need both: - // - &mut SandboxMemoryManager (from self.mem_mgr.as_mut()) - // - &mut dyn Hypervisor (from self) - // We'll use a temporary approach to extract the mem_mgr temporarily - let mem_mgr_option = self.mem_mgr.take(); - let mut mem_mgr = - mem_mgr_option.ok_or_else(|| new_error!("mem_mgr not initialized"))?; - let host_funcs = self - .host_funcs - .as_ref() - .ok_or_else(|| new_error!("host_funcs not initialized"))? - .clone(); - - handle_outb(&mut mem_mgr, host_funcs, self, port, value)?; - - // Put the mem_mgr back - self.mem_mgr = Some(mem_mgr); - } - - #[cfg(not(feature = "mem_profile"))] - { - let mem_mgr = self - .mem_mgr - .as_mut() - .ok_or_else(|| new_error!("mem_mgr not initialized"))?; - let host_funcs = self - .host_funcs - .as_ref() - .ok_or_else(|| new_error!("host_funcs not initialized"))? - .clone(); - - handle_outb(mem_mgr, host_funcs, port, value)?; - } + handle_outb(mem_mgr, host_funcs, port, value, self)?; } Ok(()) @@ -942,23 +910,18 @@ impl Hypervisor for KVMDriver { Ok(()) } - fn check_stack_guard(&self) -> Result { - if let Some(mgr) = self.mem_mgr.as_ref() { - mgr.check_stack_guard() - } else { - Err(new_error!("Memory manager is not initialized")) - } + fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result { + mem_mgr.check_stack_guard() } #[cfg(feature = "trace_guest")] - fn handle_trace(&mut self, tc: &mut crate::sandbox::trace::TraceContext) -> Result<()> { + fn handle_trace( + &mut self, + tc: &mut crate::sandbox::trace::TraceContext, + mem_mgr: &mut SandboxMemoryManager, + ) -> Result<()> { let regs = self.regs()?; - tc.handle_trace( - ®s, - self.mem_mgr.as_mut().ok_or_else(|| { - new_error!("Memory manager is not initialized before handling trace") - })?, - ) + tc.handle_trace(®s, mem_mgr) } #[cfg(feature = "mem_profile")] diff --git a/src/hyperlight_host/src/hypervisor/mod.rs b/src/hyperlight_host/src/hypervisor/mod.rs index 7a4c31014..95b627fee 100644 --- a/src/hyperlight_host/src/hypervisor/mod.rs +++ b/src/hyperlight_host/src/hypervisor/mod.rs @@ -131,8 +131,8 @@ pub(crate) trait Hypervisor: Debug + Send { peb_addr: RawPtr, seed: u64, page_size: u32, - mem_mgr: SandboxMemoryManager, - host_funcs: Arc>, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, guest_max_log_level: Option, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()>; @@ -161,6 +161,8 @@ pub(crate) trait Hypervisor: Debug + Send { fn dispatch_call_from_host( &mut self, dispatch_func_addr: RawPtr, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()>; @@ -171,6 +173,8 @@ pub(crate) trait Hypervisor: Debug + Send { data: Vec, rip: u64, instruction_length: u64, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, ) -> Result<()>; /// Run the vCPU @@ -320,10 +324,14 @@ pub(crate) trait Hypervisor: Debug + Send { } /// Check stack guard to see if the stack is still valid - fn check_stack_guard(&self) -> Result; + fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result; #[cfg(feature = "trace_guest")] - fn handle_trace(&mut self, tc: &mut crate::sandbox::trace::TraceContext) -> Result<()>; + fn handle_trace( + &mut self, + tc: &mut crate::sandbox::trace::TraceContext, + mem_mgr: &mut SandboxMemoryManager, + ) -> Result<()>; /// Get a mutable reference of the trace info for the guest #[cfg(feature = "mem_profile")] @@ -362,6 +370,8 @@ impl VirtualCPU { pub(crate) fn run( hv: &mut dyn Hypervisor, interrupt_handle: Arc, + mem_mgr: &mut SandboxMemoryManager, + host_funcs: &Arc>, #[cfg(gdb)] dbg_mem_access_fn: Arc>>, ) -> Result<()> { // Keeps the trace context and open spans @@ -398,7 +408,7 @@ impl VirtualCPU { // Handle the guest trace data if any #[cfg(feature = "trace_guest")] - if let Err(e) = hv.handle_trace(&mut tc) { + if let Err(e) = hv.handle_trace(&mut tc, mem_mgr) { // If no trace data is available, we just log a message and continue // Is this the right thing to do? log::debug!("Error handling guest trace: {:?}", e); @@ -437,13 +447,13 @@ impl VirtualCPU { break; } Ok(HyperlightExit::IoOut(port, data, rip, instruction_length)) => { - hv.handle_io(port, data, rip, instruction_length)? + hv.handle_io(port, data, rip, instruction_length, mem_mgr, host_funcs)? } Ok(HyperlightExit::Mmio(addr)) => { #[cfg(crashdump)] crashdump::generate_crashdump(hv)?; - if !hv.check_stack_guard()? { + if !hv.check_stack_guard(mem_mgr)? { log_then_return!(StackOverflow()); } @@ -890,7 +900,7 @@ pub(crate) mod tests { let rt_cfg: SandboxRuntimeConfig = Default::default(); let sandbox = UninitializedSandbox::new(GuestBinary::FilePath(filename.clone()), Some(config))?; - let (mem_mgr, mut gshm) = sandbox.mgr.build(); + let (mut mem_mgr, mut gshm) = sandbox.mgr.build(); let mut vm = set_up_hypervisor_partition( &mut gshm, &config, @@ -914,8 +924,8 @@ pub(crate) mod tests { peb_addr, seed, page_size, - mem_mgr, - host_funcs, + &mut mem_mgr, + &host_funcs, guest_max_log_level, #[cfg(gdb)] dbg_mem_access_fn, diff --git a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs index d66779c7e..f1d71fad9 100644 --- a/src/hyperlight_host/src/sandbox/initialized_multi_use.rs +++ b/src/hyperlight_host/src/sandbox/initialized_multi_use.rs @@ -95,8 +95,7 @@ pub struct MultiUseSandbox { id: u64, /// Whether this sandbox is poisoned poisoned: bool, - // We need to keep a reference to the host functions, even if the compiler marks it as unused. The compiler cannot detect our dynamic usages of the host function in `HyperlightFunction::call`. - pub(super) _host_funcs: Arc>, + pub(super) host_funcs: Arc>, pub(crate) mem_mgr: SandboxMemoryManager, vm: Box, dispatch_ptr: RawPtr, @@ -124,7 +123,7 @@ impl MultiUseSandbox { Self { id: SANDBOX_ID_COUNTER.fetch_add(1, Ordering::Relaxed), poisoned: false, - _host_funcs: host_funcs, + host_funcs, mem_mgr: mgr, vm, dispatch_ptr, @@ -597,6 +596,8 @@ impl MultiUseSandbox { self.vm.dispatch_call_from_host( self.dispatch_ptr.clone(), + &mut self.mem_mgr, + &self.host_funcs, #[cfg(gdb)] self.dbg_mem_access_fn.clone(), )?; diff --git a/src/hyperlight_host/src/sandbox/mod.rs b/src/hyperlight_host/src/sandbox/mod.rs index 7ff940a23..93bae12a8 100644 --- a/src/hyperlight_host/src/sandbox/mod.rs +++ b/src/hyperlight_host/src/sandbox/mod.rs @@ -177,7 +177,7 @@ mod tests { .pop() .unwrap_or_else(|| panic!("Failed to pop Sandbox thread {}", i)); let host_funcs = sandbox - ._host_funcs + .host_funcs .try_lock() .map_err(|_| new_error!("Error locking")); diff --git a/src/hyperlight_host/src/sandbox/outb.rs b/src/hyperlight_host/src/sandbox/outb.rs index e5e938ae3..5d292cc9d 100644 --- a/src/hyperlight_host/src/sandbox/outb.rs +++ b/src/hyperlight_host/src/sandbox/outb.rs @@ -25,7 +25,6 @@ use tracing::{Span, instrument}; use tracing_log::format_trace; use super::host_funcs::FunctionRegistry; -#[cfg(feature = "mem_profile")] use crate::hypervisor::Hypervisor; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::shared_mem::HostSharedMemory; @@ -147,10 +146,10 @@ fn outb_abort(mem_mgr: &mut SandboxMemoryManager, data: u32) - #[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")] pub(crate) fn handle_outb( mem_mgr: &mut SandboxMemoryManager, - host_funcs: Arc>, - #[cfg(feature = "mem_profile")] _hv: &mut dyn Hypervisor, + host_funcs: &Arc>, port: u16, data: u32, + _hv: &mut dyn Hypervisor, ) -> Result<()> { match port.try_into()? { OutBAction::Log => outb_log(mem_mgr), diff --git a/src/hyperlight_host/src/sandbox/uninitialized.rs b/src/hyperlight_host/src/sandbox/uninitialized.rs index fb09572a9..cd7077062 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized.rs @@ -448,7 +448,7 @@ mod tests { let sandbox = sandbox.unwrap(); let host_funcs = sandbox - ._host_funcs + .host_funcs .try_lock() .map_err(|_| new_error!("Error locking")); @@ -473,7 +473,7 @@ mod tests { let sandbox = sandbox.unwrap(); let host_funcs = sandbox - ._host_funcs + .host_funcs .try_lock() .map_err(|_| new_error!("Error locking")); @@ -506,7 +506,7 @@ mod tests { let sandbox = sandbox.unwrap(); let host_funcs = sandbox - ._host_funcs + .host_funcs .try_lock() .map_err(|_| new_error!("Error locking")); @@ -524,7 +524,7 @@ mod tests { let sandbox = sandbox.unwrap(); let host_funcs = sandbox - ._host_funcs + .host_funcs .try_lock() .map_err(|_| new_error!("Error locking")); @@ -766,7 +766,7 @@ mod tests { .unwrap_or_else(|| panic!("Failed to pop Sandbox thread {}", i)); let host_funcs = sandbox - ._host_funcs + .host_funcs .try_lock() .map_err(|_| new_error!("Error locking")); diff --git a/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs b/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs index a2f9edffb..ba4680617 100644 --- a/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs +++ b/src/hyperlight_host/src/sandbox/uninitialized_evolve.rs @@ -44,7 +44,7 @@ use crate::{MultiUseSandbox, Result, UninitializedSandbox, log_then_return, new_ #[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")] pub(super) fn evolve_impl_multi_use(u_sbox: UninitializedSandbox) -> Result { - let (hshm, mut gshm) = u_sbox.mgr.build(); + let (mut hshm, mut gshm) = u_sbox.mgr.build(); let mut vm = set_up_hypervisor_partition( &mut gshm, &u_sbox.config, @@ -74,8 +74,8 @@ pub(super) fn evolve_impl_multi_use(u_sbox: UninitializedSandbox) -> Result Date: Thu, 20 Nov 2025 14:27:48 -0800 Subject: [PATCH 2/4] Remove Hypervisor::check_stack_guard and handle_trace Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .../src/hypervisor/hyperv_linux.rs | 14 ----------- .../src/hypervisor/hyperv_windows.rs | 14 ----------- src/hyperlight_host/src/hypervisor/kvm.rs | 14 ----------- src/hyperlight_host/src/hypervisor/mod.rs | 23 +++++++------------ 4 files changed, 8 insertions(+), 57 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index bc157db82..d5db0b15a 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -953,20 +953,6 @@ impl Hypervisor for HypervLinuxDriver { Ok(()) } - fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result { - mem_mgr.check_stack_guard() - } - - #[cfg(feature = "trace_guest")] - fn handle_trace( - &mut self, - tc: &mut crate::sandbox::trace::TraceContext, - mem_mgr: &mut SandboxMemoryManager, - ) -> Result<()> { - let regs = self.regs()?; - tc.handle_trace(®s, mem_mgr) - } - #[cfg(feature = "mem_profile")] fn trace_info_mut(&mut self) -> &mut MemTraceInfo { &mut self.trace_info diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index 590409005..aba319598 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -848,20 +848,6 @@ impl Hypervisor for HypervWindowsDriver { Ok(()) } - fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result { - mem_mgr.check_stack_guard() - } - - #[cfg(feature = "trace_guest")] - fn handle_trace( - &mut self, - tc: &mut crate::sandbox::trace::TraceContext, - mem_mgr: &mut SandboxMemoryManager, - ) -> Result<()> { - let regs = self.regs()?; - tc.handle_trace(®s, mem_mgr) - } - #[cfg(feature = "mem_profile")] fn trace_info_mut(&mut self) -> &mut MemTraceInfo { &mut self.trace_info diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index e6b31da0b..a068b0a91 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -910,20 +910,6 @@ impl Hypervisor for KVMDriver { Ok(()) } - fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result { - mem_mgr.check_stack_guard() - } - - #[cfg(feature = "trace_guest")] - fn handle_trace( - &mut self, - tc: &mut crate::sandbox::trace::TraceContext, - mem_mgr: &mut SandboxMemoryManager, - ) -> Result<()> { - let regs = self.regs()?; - tc.handle_trace(®s, mem_mgr) - } - #[cfg(feature = "mem_profile")] fn trace_info_mut(&mut self) -> &mut MemTraceInfo { &mut self.trace_info diff --git a/src/hyperlight_host/src/hypervisor/mod.rs b/src/hyperlight_host/src/hypervisor/mod.rs index 95b627fee..d4eeeef75 100644 --- a/src/hyperlight_host/src/hypervisor/mod.rs +++ b/src/hyperlight_host/src/hypervisor/mod.rs @@ -323,16 +323,6 @@ pub(crate) trait Hypervisor: Debug + Send { unimplemented!() } - /// Check stack guard to see if the stack is still valid - fn check_stack_guard(&self, mem_mgr: &SandboxMemoryManager) -> Result; - - #[cfg(feature = "trace_guest")] - fn handle_trace( - &mut self, - tc: &mut crate::sandbox::trace::TraceContext, - mem_mgr: &mut SandboxMemoryManager, - ) -> Result<()>; - /// Get a mutable reference of the trace info for the guest #[cfg(feature = "mem_profile")] fn trace_info_mut(&mut self) -> &mut MemTraceInfo; @@ -408,10 +398,13 @@ impl VirtualCPU { // Handle the guest trace data if any #[cfg(feature = "trace_guest")] - if let Err(e) = hv.handle_trace(&mut tc, mem_mgr) { - // If no trace data is available, we just log a message and continue - // Is this the right thing to do? - log::debug!("Error handling guest trace: {:?}", e); + { + let regs = hv.regs()?; + if let Err(e) = tc.handle_trace(®s, mem_mgr) { + // If no trace data is available, we just log a message and continue + // Is this the right thing to do? + log::debug!("Error handling guest trace: {:?}", e); + } } result @@ -453,7 +446,7 @@ impl VirtualCPU { #[cfg(crashdump)] crashdump::generate_crashdump(hv)?; - if !hv.check_stack_guard(mem_mgr)? { + if !mem_mgr.check_stack_guard()? { log_then_return!(StackOverflow()); } From a165f7424fcb0749f0b77a7d22fd776143df75ce Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Thu, 20 Nov 2025 14:50:10 -0800 Subject: [PATCH 3/4] Cargo fmt Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- src/hyperlight_host/src/hypervisor/hyperv_windows.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index aba319598..fad08045e 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -48,6 +48,8 @@ use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags}; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::ptr::{GuestPtr, RawPtr}; use crate::mem::shared_mem::HostSharedMemory; +#[cfg(gdb)] +use crate::new_error; use crate::sandbox::host_funcs::FunctionRegistry; use crate::sandbox::outb::handle_outb; #[cfg(feature = "mem_profile")] @@ -55,8 +57,6 @@ use crate::sandbox::trace::MemTraceInfo; #[cfg(crashdump)] use crate::sandbox::uninitialized::SandboxRuntimeConfig; use crate::{Result, debug, log_then_return}; -#[cfg(gdb)] -use crate::new_error; #[cfg(gdb)] mod debug { From 857a1b4c802139bc1d63e5dc75e96e5862a2d5d3 Mon Sep 17 00:00:00 2001 From: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> Date: Fri, 21 Nov 2025 11:40:39 -0800 Subject: [PATCH 4/4] Dont pass hv to outb_handler Signed-off-by: Ludvig Liljenberg <4257730+ludfjig@users.noreply.github.com> --- .../src/hypervisor/hyperv_linux.rs | 11 +++++++++- .../src/hypervisor/hyperv_windows.rs | 11 +++++++++- src/hyperlight_host/src/hypervisor/kvm.rs | 11 +++++++++- src/hyperlight_host/src/sandbox/outb.rs | 20 ++++++++----------- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs index d5db0b15a..88c27edc3 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_linux.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_linux.rs @@ -585,7 +585,16 @@ impl Hypervisor for HypervLinuxDriver { padded[..copy_len].copy_from_slice(&data[..copy_len]); let val = u32::from_le_bytes(padded); - handle_outb(mem_mgr, host_funcs, port, val, self)?; + #[cfg(feature = "mem_profile")] + { + let regs = self.regs()?; + let trace_info = self.trace_info_mut(); + handle_outb(mem_mgr, host_funcs, port, val, ®s, trace_info)?; + } + #[cfg(not(feature = "mem_profile"))] + { + handle_outb(mem_mgr, host_funcs, port, val)?; + } // update rip self.vcpu_fd.set_reg(&[hv_register_assoc { diff --git a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs index fad08045e..d3bd95f88 100644 --- a/src/hyperlight_host/src/hypervisor/hyperv_windows.rs +++ b/src/hyperlight_host/src/hypervisor/hyperv_windows.rs @@ -502,7 +502,16 @@ impl Hypervisor for HypervWindowsDriver { padded[..copy_len].copy_from_slice(&data[..copy_len]); let val = u32::from_le_bytes(padded); - handle_outb(mem_mgr, host_funcs, port, val, self)?; + #[cfg(feature = "mem_profile")] + { + let regs = self.regs()?; + let trace_info = self.trace_info_mut(); + handle_outb(mem_mgr, host_funcs, port, val, ®s, trace_info)?; + } + #[cfg(not(feature = "mem_profile"))] + { + handle_outb(mem_mgr, host_funcs, port, val)?; + } let mut regs = self.regs()?; regs.rip = rip + instruction_length; diff --git a/src/hyperlight_host/src/hypervisor/kvm.rs b/src/hyperlight_host/src/hypervisor/kvm.rs index a068b0a91..df0fd655b 100644 --- a/src/hyperlight_host/src/hypervisor/kvm.rs +++ b/src/hyperlight_host/src/hypervisor/kvm.rs @@ -578,7 +578,16 @@ impl Hypervisor for KVMDriver { padded[..copy_len].copy_from_slice(&data[..copy_len]); let value = u32::from_le_bytes(padded); - handle_outb(mem_mgr, host_funcs, port, value, self)?; + #[cfg(feature = "mem_profile")] + { + let regs = self.regs()?; + let trace_info = self.trace_info_mut(); + handle_outb(mem_mgr, host_funcs, port, value, ®s, trace_info)?; + } + #[cfg(not(feature = "mem_profile"))] + { + handle_outb(mem_mgr, host_funcs, port, value)?; + } } Ok(()) diff --git a/src/hyperlight_host/src/sandbox/outb.rs b/src/hyperlight_host/src/sandbox/outb.rs index 5d292cc9d..087162a4a 100644 --- a/src/hyperlight_host/src/sandbox/outb.rs +++ b/src/hyperlight_host/src/sandbox/outb.rs @@ -25,9 +25,12 @@ use tracing::{Span, instrument}; use tracing_log::format_trace; use super::host_funcs::FunctionRegistry; -use crate::hypervisor::Hypervisor; +#[cfg(feature = "mem_profile")] +use crate::hypervisor::regs::CommonRegisters; use crate::mem::mgr::SandboxMemoryManager; use crate::mem::shared_mem::HostSharedMemory; +#[cfg(feature = "mem_profile")] +use crate::sandbox::trace::MemTraceInfo; use crate::{HyperlightError, Result, new_error}; #[instrument(err(Debug), skip_all, parent = Span::current(), level="Trace")] @@ -149,7 +152,8 @@ pub(crate) fn handle_outb( host_funcs: &Arc>, port: u16, data: u32, - _hv: &mut dyn Hypervisor, + #[cfg(feature = "mem_profile")] regs: &CommonRegisters, + #[cfg(feature = "mem_profile")] trace_info: &mut MemTraceInfo, ) -> Result<()> { match port.try_into()? { OutBAction::Log => outb_log(mem_mgr), @@ -184,17 +188,9 @@ pub(crate) fn handle_outb( #[cfg(feature = "trace_guest")] OutBAction::TraceBatch => Ok(()), #[cfg(feature = "mem_profile")] - OutBAction::TraceMemoryAlloc => { - let regs = _hv.regs()?; - let trace_info = _hv.trace_info_mut(); - trace_info.handle_trace_mem_alloc(®s, mem_mgr) - } + OutBAction::TraceMemoryAlloc => trace_info.handle_trace_mem_alloc(regs, mem_mgr), #[cfg(feature = "mem_profile")] - OutBAction::TraceMemoryFree => { - let regs = _hv.regs()?; - let trace_info = _hv.trace_info_mut(); - trace_info.handle_trace_mem_free(®s, mem_mgr) - } + OutBAction::TraceMemoryFree => trace_info.handle_trace_mem_free(regs, mem_mgr), } } #[cfg(test)]