@@ -65,7 +65,7 @@ use crate::hypervisor::{InterruptHandle, InterruptHandleImpl, get_max_log_level}
6565use crate :: mem:: memory_region:: { MemoryRegion , MemoryRegionFlags , MemoryRegionType } ;
6666use crate :: mem:: mgr:: SandboxMemoryManager ;
6767use crate :: mem:: ptr:: { GuestPtr , RawPtr } ;
68- use crate :: mem:: shared_mem:: HostSharedMemory ;
68+ use crate :: mem:: shared_mem:: { GuestSharedMemory , HostSharedMemory , SharedMemory } ;
6969use crate :: metrics:: { METRIC_ERRONEOUS_VCPU_KICKS , METRIC_GUEST_CANCELLATION } ;
7070use crate :: sandbox:: SandboxConfiguration ;
7171use crate :: sandbox:: host_funcs:: FunctionRegistry ;
@@ -95,6 +95,10 @@ pub(crate) struct HyperlightVm {
9595 mmap_regions : Vec < ( u32 , MemoryRegion ) > , // Later mapped regions (slot number, region)
9696 next_slot : u32 , // Monotonically increasing slot number
9797 freed_slots : Vec < u32 > , // Reusable slots from unmapped regions
98+ scratch_slot : u32 , // The slot number used for the scratch region
99+ // The current scratch region, used to keep it alive as long as it
100+ // is used & when unmapping
101+ scratch_memory : Option < GuestSharedMemory > ,
98102
99103 #[ cfg( gdb) ]
100104 gdb_conn : Option < DebugCommChannel < DebugResponse , DebugMsg > > ,
@@ -247,6 +251,15 @@ pub enum UnmapRegionError {
247251 UnmapMemory ( #[ from] UnmapMemoryError ) ,
248252}
249253
254+ /// Errors that can occur when updating the scratch mapping
255+ #[ derive( Debug , thiserror:: Error ) ]
256+ pub enum UpdateScratchError {
257+ #[ error( "VM map memory error: {0}" ) ]
258+ MapMemory ( #[ from] MapMemoryError ) ,
259+ #[ error( "VM unmap memory error: {0}" ) ]
260+ UnmapMemory ( #[ from] UnmapMemoryError ) ,
261+ }
262+
250263/// Errors that can occur during HyperlightVm creation
251264#[ derive( Debug , thiserror:: Error ) ]
252265pub enum CreateHyperlightVmError {
@@ -262,6 +275,8 @@ pub enum CreateHyperlightVmError {
262275 SendDbgMsg ( #[ from] SendDbgMsgError ) ,
263276 #[ error( "VM operation error: {0}" ) ]
264277 Vm ( #[ from] VmError ) ,
278+ #[ error( "Set scratch error: {0}" ) ]
279+ UpdateScratch ( #[ from] UpdateScratchError ) ,
265280}
266281
267282/// Errors that can occur during debug exit handling
@@ -311,6 +326,8 @@ pub enum HyperlightVmError {
311326 MapRegion ( #[ from] MapRegionError ) ,
312327 #[ error( "Unmap region error: {0}" ) ]
313328 UnmapRegion ( #[ from] UnmapRegionError ) ,
329+ #[ error( "Update scratch error: {0}" ) ]
330+ UpdateScratch ( #[ from] UpdateScratchError ) ,
314331}
315332
316333impl HyperlightVm {
@@ -319,6 +336,7 @@ impl HyperlightVm {
319336 #[ allow( clippy:: too_many_arguments) ]
320337 pub ( crate ) fn new (
321338 mem_regions : Vec < MemoryRegion > ,
339+ scratch_mem : GuestSharedMemory ,
322340 _pml4_addr : u64 ,
323341 entrypoint : u64 ,
324342 rsp : u64 ,
@@ -395,6 +413,7 @@ impl HyperlightVm {
395413 } ) ,
396414 } ) ;
397415
416+ let scratch_slot = mem_regions. len ( ) as u32 ;
398417 #[ cfg_attr( not( gdb) , allow( unused_mut) ) ]
399418 let mut ret = Self {
400419 vm,
@@ -403,10 +422,12 @@ impl HyperlightVm {
403422 interrupt_handle,
404423 page_size : 0 , // Will be set in `initialise`
405424
406- next_slot : mem_regions . len ( ) as u32 ,
425+ next_slot : scratch_slot + 1 ,
407426 sandbox_regions : mem_regions,
408427 mmap_regions : Vec :: new ( ) ,
409428 freed_slots : Vec :: new ( ) ,
429+ scratch_slot,
430+ scratch_memory : None ,
410431
411432 #[ cfg( gdb) ]
412433 gdb_conn,
@@ -418,6 +439,8 @@ impl HyperlightVm {
418439 rt_cfg,
419440 } ;
420441
442+ ret. update_scratch_mapping ( scratch_mem) ?;
443+
421444 // Send the interrupt handle to the GDB thread if debugging is enabled
422445 // This is used to allow the GDB thread to stop the vCPU
423446 #[ cfg( gdb) ]
@@ -542,6 +565,24 @@ impl HyperlightVm {
542565 self . mmap_regions . iter ( ) . map ( |( _, region) | region)
543566 }
544567
568+ /// Update the scratch mapping to point to a new GuestSharedMemory
569+ pub ( crate ) fn update_scratch_mapping (
570+ & mut self ,
571+ scratch : GuestSharedMemory ,
572+ ) -> Result < ( ) , UpdateScratchError > {
573+ let guest_base = hyperlight_common:: layout:: scratch_base_gpa ( scratch. mem_size ( ) ) ;
574+ let rgn = scratch. mapping_at ( guest_base, MemoryRegionType :: Scratch ) ;
575+
576+ if let Some ( old_scratch) = self . scratch_memory . replace ( scratch) {
577+ let old_base = hyperlight_common:: layout:: scratch_base_gpa ( old_scratch. mem_size ( ) ) ;
578+ let old_rgn = old_scratch. mapping_at ( old_base, MemoryRegionType :: Scratch ) ;
579+ self . vm . unmap_memory ( ( self . scratch_slot , & old_rgn) ) ?;
580+ }
581+ unsafe { self . vm . map_memory ( ( self . scratch_slot , & rgn) ) ? } ;
582+
583+ Ok ( ( ) )
584+ }
585+
545586 /// Dispatch a call from the host to the guest using the given pointer
546587 /// to the dispatch function _in the guest's address space_.
547588 ///
0 commit comments