@@ -95,13 +95,18 @@ impl vmem::TableOps for GuestPageTableBuffer {
9595 . unwrap_or ( 0 )
9696 }
9797
98- unsafe fn write_entry ( & self , addr : ( usize , usize ) , x : PageTableEntry ) {
98+ unsafe fn write_entry (
99+ & self ,
100+ addr : ( usize , usize ) ,
101+ entry : PageTableEntry ,
102+ ) -> Option < ( usize , usize ) > {
99103 let mut b = self . buffer . borrow_mut ( ) ;
100104 let byte_offset =
101105 ( addr. 0 - self . phys_base / PAGE_TABLE_SIZE ) * PAGE_TABLE_SIZE + addr. 1 * 8 ;
102106 if let Some ( slice) = b. get_mut ( byte_offset..byte_offset + 8 ) {
103- slice. copy_from_slice ( & x . to_ne_bytes ( ) ) ;
107+ slice. copy_from_slice ( & entry . to_ne_bytes ( ) ) ;
104108 }
109+ None
105110 }
106111
107112 fn to_phys ( addr : ( usize , usize ) ) -> PhysAddr {
@@ -229,36 +234,45 @@ impl SandboxMemoryManager<ExclusiveSharedMemory> {
229234 }
230235
231236 /// Wraps ExclusiveSharedMemory::build
237+ // Morally, this should not have to be a Result: this operation is
238+ // infallible. The source of the Result is
239+ // update_scratch_bookkeeping(), which calls functions that can
240+ // fail due to bounds checks (which are statically known to be ok
241+ // in this situation) or due to failing to take the scratch shared
242+ // memory lock, but the scratch shared memory is built in this
243+ // function, its lock does not escape before the end of the
244+ // function, and the lock is taken by no other code path, so we
245+ // know it is not contended.
232246 pub fn build (
233247 self ,
234- ) -> (
248+ ) -> Result < (
235249 SandboxMemoryManager < HostSharedMemory > ,
236250 SandboxMemoryManager < GuestSharedMemory > ,
237- ) {
251+ ) > {
238252 let ( hshm, gshm) = self . shared_mem . build ( ) ;
239253 let ( hscratch, gscratch) = self . scratch_mem . build ( ) ;
240- (
241- SandboxMemoryManager {
242- shared_mem : hshm ,
243- scratch_mem : hscratch ,
244- layout : self . layout ,
245- load_addr : self . load_addr . clone ( ) ,
246- entrypoint_offset : self . entrypoint_offset ,
247- mapped_rgns : self . mapped_rgns ,
248- stack_cookie : self . stack_cookie ,
249- abort_buffer : self . abort_buffer ,
250- } ,
251- SandboxMemoryManager {
252- shared_mem : gshm ,
253- scratch_mem : gscratch ,
254- layout : self . layout ,
255- load_addr : self . load_addr . clone ( ) ,
256- entrypoint_offset : self . entrypoint_offset ,
257- mapped_rgns : self . mapped_rgns ,
258- stack_cookie : self . stack_cookie ,
259- abort_buffer : Vec :: new ( ) , // Guest doesn't need abort buffer
260- } ,
261- )
254+ let mut host_mgr = SandboxMemoryManager {
255+ shared_mem : hshm ,
256+ scratch_mem : hscratch ,
257+ layout : self . layout ,
258+ load_addr : self . load_addr . clone ( ) ,
259+ entrypoint_offset : self . entrypoint_offset ,
260+ mapped_rgns : self . mapped_rgns ,
261+ stack_cookie : self . stack_cookie ,
262+ abort_buffer : self . abort_buffer ,
263+ } ;
264+ let guest_mgr = SandboxMemoryManager {
265+ shared_mem : gshm ,
266+ scratch_mem : gscratch ,
267+ layout : self . layout ,
268+ load_addr : self . load_addr . clone ( ) ,
269+ entrypoint_offset : self . entrypoint_offset ,
270+ mapped_rgns : self . mapped_rgns ,
271+ stack_cookie : self . stack_cookie ,
272+ abort_buffer : Vec :: new ( ) , // Guest doesn't need abort buffer
273+ } ;
274+ host_mgr . update_scratch_bookkeeping ( ) ? ;
275+ Ok ( ( host_mgr , guest_mgr ) )
262276 }
263277}
264278
@@ -400,9 +414,9 @@ impl SandboxMemoryManager<HostSharedMemory> {
400414 }
401415 self . shared_mem . restore_from_snapshot ( snapshot) ?;
402416 let new_scratch_size = snapshot. layout ( ) . get_scratch_size ( ) ;
403- if new_scratch_size == self . scratch_mem . mem_size ( ) {
417+ let gscratch = if new_scratch_size == self . scratch_mem . mem_size ( ) {
404418 self . scratch_mem . zero ( ) ?;
405- Ok ( None )
419+ None
406420 } else {
407421 let new_scratch_mem = ExclusiveSharedMemory :: new ( new_scratch_size) ?;
408422 let ( hscratch, gscratch) = new_scratch_mem. build ( ) ;
@@ -413,8 +427,28 @@ impl SandboxMemoryManager<HostSharedMemory> {
413427 // has been unmapped from the VM.
414428 self . scratch_mem = hscratch;
415429
416- Ok ( Some ( gscratch) )
417- }
430+ Some ( gscratch)
431+ } ;
432+ self . update_scratch_bookkeeping ( ) ?;
433+ Ok ( gscratch)
434+ }
435+
436+ fn update_scratch_bookkeeping ( & mut self ) -> Result < ( ) > {
437+ let scratch_size = self . scratch_mem . mem_size ( ) ;
438+
439+ let size_offset =
440+ scratch_size - hyperlight_common:: layout:: SCRATCH_TOP_SIZE_OFFSET as usize ;
441+ self . scratch_mem
442+ . write :: < u64 > ( size_offset, scratch_size as u64 ) ?;
443+
444+ let alloc_offset =
445+ scratch_size - hyperlight_common:: layout:: SCRATCH_TOP_ALLOCATOR_OFFSET as usize ;
446+ self . scratch_mem . write :: < u64 > (
447+ alloc_offset,
448+ hyperlight_common:: layout:: scratch_base_gpa ( scratch_size) ,
449+ ) ?;
450+
451+ Ok ( ( ) )
418452 }
419453}
420454
0 commit comments