@@ -45,6 +45,8 @@ pub(crate) const STACK_COOKIE_LEN: usize = 16;
4545pub ( crate ) struct SandboxMemoryManager < S > {
4646 /// Shared memory for the Sandbox
4747 pub ( crate ) shared_mem : S ,
48+ /// Scratch memory for the Sandbox
49+ pub ( crate ) scratch_mem : S ,
4850 /// The memory layout of the underlying shared memory
4951 pub ( crate ) layout : SandboxMemoryLayout ,
5052 /// Pointer to where to load memory from
@@ -145,13 +147,15 @@ where
145147 pub ( crate ) fn new (
146148 layout : SandboxMemoryLayout ,
147149 shared_mem : S ,
150+ scratch_mem : S ,
148151 load_addr : RawPtr ,
149152 entrypoint_offset : Option < Offset > ,
150153 stack_cookie : [ u8 ; STACK_COOKIE_LEN ] ,
151154 ) -> Self {
152155 Self {
153156 layout,
154157 shared_mem,
158+ scratch_mem,
155159 load_addr,
156160 entrypoint_offset,
157161 mapped_rgns : 0 ,
@@ -191,26 +195,22 @@ where
191195 mapped_regions,
192196 )
193197 }
194-
195- /// This function restores a memory snapshot from a given snapshot.
196- pub ( crate ) fn restore_snapshot ( & mut self , snapshot : & Snapshot ) -> Result < ( ) > {
197- self . shared_mem . restore_from_snapshot ( snapshot) ?;
198- Ok ( ( ) )
199- }
200198}
201199
202200impl SandboxMemoryManager < ExclusiveSharedMemory > {
203201 pub ( crate ) fn from_snapshot ( s : & Snapshot ) -> Result < Self > {
204202 let layout = * s. layout ( ) ;
205203 let mut shared_mem = ExclusiveSharedMemory :: new ( s. mem_size ( ) ) ?;
206204 shared_mem. copy_from_slice ( s. memory ( ) , 0 ) ?;
205+ let scratch_mem = ExclusiveSharedMemory :: new ( s. layout ( ) . get_scratch_size ( ) ) ?;
207206 let load_addr: RawPtr = RawPtr :: try_from ( layout. get_guest_code_address ( ) ) ?;
208207 let stack_cookie = rand:: random :: < [ u8 ; STACK_COOKIE_LEN ] > ( ) ;
209208 let entrypoint_gva = s. preinitialise ( ) ;
210209 let entrypoint_offset = entrypoint_gva. map ( |x| ( x - u64:: from ( & load_addr) ) . into ( ) ) ;
211210 Ok ( Self :: new (
212211 layout,
213212 shared_mem,
213+ scratch_mem,
214214 load_addr,
215215 entrypoint_offset,
216216 stack_cookie,
@@ -236,9 +236,11 @@ impl SandboxMemoryManager<ExclusiveSharedMemory> {
236236 SandboxMemoryManager < GuestSharedMemory > ,
237237 ) {
238238 let ( hshm, gshm) = self . shared_mem . build ( ) ;
239+ let ( hscratch, gscratch) = self . scratch_mem . build ( ) ;
239240 (
240241 SandboxMemoryManager {
241242 shared_mem : hshm,
243+ scratch_mem : hscratch,
242244 layout : self . layout ,
243245 load_addr : self . load_addr . clone ( ) ,
244246 entrypoint_offset : self . entrypoint_offset ,
@@ -248,6 +250,7 @@ impl SandboxMemoryManager<ExclusiveSharedMemory> {
248250 } ,
249251 SandboxMemoryManager {
250252 shared_mem : gshm,
253+ scratch_mem : gscratch,
251254 layout : self . layout ,
252255 load_addr : self . load_addr . clone ( ) ,
253256 entrypoint_offset : self . entrypoint_offset ,
@@ -382,6 +385,37 @@ impl SandboxMemoryManager<HostSharedMemory> {
382385 } ;
383386 }
384387 }
388+
389+ /// This function restores a memory snapshot from a given snapshot.
390+ pub ( crate ) fn restore_snapshot (
391+ & mut self ,
392+ snapshot : & Snapshot ,
393+ ) -> Result < Option < GuestSharedMemory > > {
394+ if self . shared_mem . mem_size ( ) != snapshot. mem_size ( ) {
395+ return Err ( new_error ! (
396+ "Snapshot size does not match current memory size: {} != {}" ,
397+ self . shared_mem. raw_mem_size( ) ,
398+ snapshot. mem_size( )
399+ ) ) ;
400+ }
401+ self . shared_mem . restore_from_snapshot ( snapshot) ?;
402+ let new_scratch_size = snapshot. layout ( ) . get_scratch_size ( ) ;
403+ if new_scratch_size == self . scratch_mem . mem_size ( ) {
404+ self . scratch_mem . zero ( ) ?;
405+ Ok ( None )
406+ } else {
407+ let new_scratch_mem = ExclusiveSharedMemory :: new ( new_scratch_size) ?;
408+ let ( hscratch, gscratch) = new_scratch_mem. build ( ) ;
409+ // Even though this destroys the reference to the host
410+ // side of the old scratch mapping, the VM should still
411+ // own the reference to the guest side of the old scratch
412+ // mapping, so it won't actually be deallocated until it
413+ // has been unmapped from the VM.
414+ self . scratch_mem = hscratch;
415+
416+ Ok ( Some ( gscratch) )
417+ }
418+ }
385419}
386420
387421#[ cfg( test) ]
0 commit comments