@@ -30,6 +30,8 @@ use crate::error::HyperlightError::{GuestOffsetIsInvalid, MemoryRequestTooBig};
3030use crate :: sandbox:: SandboxConfiguration ;
3131use crate :: { Result , new_error} ;
3232
33+ // +-------------------------------------------+
34+ // | User Memory | (guest blob size)
3335// +-------------------------------------------+
3436// | Guest (User) Stack |
3537// +-------------------------------------------+
@@ -95,6 +97,7 @@ pub(crate) struct SandboxMemoryLayout {
9597 guest_heap_buffer_offset : usize ,
9698 guard_page_offset : usize ,
9799 guest_user_stack_buffer_offset : usize , // the lowest address of the user stack
100+ user_memory_offset : usize ,
98101
99102 // other
100103 pub ( crate ) peb_address : usize ,
@@ -165,6 +168,10 @@ impl Debug for SandboxMemoryLayout {
165168 "Guest User Stack Buffer Offset" ,
166169 & format_args ! ( "{:#x}" , self . guest_user_stack_buffer_offset) ,
167170 )
171+ . field (
172+ "User Memory Offset" ,
173+ & format_args ! ( "{:#x}" , self . user_memory_offset) ,
174+ )
168175 . field (
169176 "Page Table Size" ,
170177 & format_args ! ( "{:#x}" , self . total_page_table_size) ,
@@ -252,6 +259,7 @@ impl SandboxMemoryLayout {
252259 let guest_user_stack_buffer_offset = guard_page_offset + PAGE_SIZE_USIZE ;
253260 // round up stack size to page size. This is needed for MemoryRegion
254261 let stack_size_rounded = round_up_to ( stack_size, PAGE_SIZE_USIZE ) ;
262+ let user_memory_offset = guest_user_stack_buffer_offset + stack_size_rounded;
255263
256264 Ok ( Self {
257265 peb_offset,
@@ -274,6 +282,7 @@ impl SandboxMemoryLayout {
274282 guard_page_offset,
275283 total_page_table_size,
276284 guest_code_offset,
285+ user_memory_offset,
277286 } )
278287 }
279288
@@ -403,7 +412,11 @@ impl SandboxMemoryLayout {
403412 /// layout.
404413 #[ instrument( skip_all, parent = Span :: current( ) , level= "Trace" ) ]
405414 fn get_unaligned_memory_size ( & self ) -> usize {
406- self . get_top_of_user_stack_offset ( ) + self . stack_size
415+ if self . sandbox_memory_config . get_guest_memory_size ( ) == 0 {
416+ self . user_memory_offset
417+ } else {
418+ self . sandbox_memory_config . get_guest_memory_size ( )
419+ }
407420 }
408421
409422 /// get the code offset
@@ -620,12 +633,34 @@ impl SandboxMemoryLayout {
620633 }
621634
622635 // stack
623- let final_offset = builder. push_page_aligned (
636+ let user_memory_offset = builder. push_page_aligned (
624637 self . get_guest_stack_size ( ) ,
625638 MemoryRegionFlags :: READ | MemoryRegionFlags :: WRITE ,
626639 Stack ,
627640 ) ;
628641
642+ let expected_user_memory_offset = TryInto :: < usize > :: try_into ( self . user_memory_offset ) ?;
643+
644+ if user_memory_offset != expected_user_memory_offset {
645+ return Err ( new_error ! (
646+ "User Memory offset does not match expected User Memory offset expected: {}, actual: {}" ,
647+ expected_user_memory_offset,
648+ user_memory_offset
649+ ) ) ;
650+ }
651+
652+ let user_region_size = self . get_memory_size ( ) ? - user_memory_offset;
653+
654+ let final_offset = if user_region_size > 0 {
655+ builder. push_page_aligned (
656+ user_region_size,
657+ MemoryRegionFlags :: READ | MemoryRegionFlags :: WRITE | MemoryRegionFlags :: EXECUTE ,
658+ Code ,
659+ )
660+ } else {
661+ user_memory_offset
662+ } ;
663+
629664 let expected_final_offset = TryInto :: < usize > :: try_into ( self . get_memory_size ( ) ?) ?;
630665
631666 if final_offset != expected_final_offset {
@@ -639,6 +674,21 @@ impl SandboxMemoryLayout {
639674 Ok ( builder. build ( ) )
640675 }
641676
677+ #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level= "Trace" ) ]
678+ pub ( crate ) fn write_user_memory (
679+ & self ,
680+ shared_mem : & mut ExclusiveSharedMemory ,
681+ bytes : & [ u8 ] ,
682+ ) -> Result < ( u64 , usize ) > {
683+ if self . user_memory_offset + bytes. len ( ) > self . get_memory_size ( ) ? {
684+ return Err ( new_error ! (
685+ "Not enough memory in shared memory to write user memory, increase guest memory size with set_guest_memory_size"
686+ ) ) ;
687+ }
688+ shared_mem. copy_from_slice ( bytes, self . user_memory_offset ) ?;
689+ Ok ( ( self . user_memory_offset as u64 , bytes. len ( ) ) )
690+ }
691+
642692 /// Write the finished memory layout to `shared_mem` and return
643693 /// `Ok` if successful.
644694 ///
0 commit comments