@@ -291,8 +291,10 @@ pub(crate) struct KVMDriver {
291291 vcpu_fd : VcpuFd ,
292292 entrypoint : u64 ,
293293 orig_rsp : GuestPtr ,
294+ // Regions part of the original sandbox
294295 mem_regions : Vec < MemoryRegion > ,
295- n_initial_regions : usize ,
296+ // Regions that are mapped after sandbox creation
297+ mmap_regions : Vec < MemoryRegion > ,
296298 interrupt_handle : Arc < LinuxInterruptHandle > ,
297299
298300 #[ cfg( gdb) ]
@@ -375,8 +377,8 @@ impl KVMDriver {
375377 vcpu_fd,
376378 entrypoint,
377379 orig_rsp : rsp_gp,
378- n_initial_regions : mem_regions. len ( ) ,
379380 mem_regions,
381+ mmap_regions : Vec :: new ( ) ,
380382 interrupt_handle : interrupt_handle. clone ( ) ,
381383 #[ cfg( gdb) ]
382384 debug,
@@ -507,18 +509,19 @@ impl Hypervisor for KVMDriver {
507509 }
508510
509511 let mut kvm_region: kvm_userspace_memory_region = region. clone ( ) . into ( ) ;
510- kvm_region. slot = self . mem_regions . len ( ) as u32 ;
512+ kvm_region. slot = ( self . mem_regions . len ( ) + self . mmap_regions . len ( ) ) as u32 ;
511513 unsafe { self . vm_fd . set_user_memory_region ( kvm_region) } ?;
512- self . mem_regions . push ( region. to_owned ( ) ) ;
514+ self . mmap_regions . push ( region. to_owned ( ) ) ;
513515 Ok ( ( ) )
514516 }
515517
516518 #[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
517519 unsafe fn unmap_regions ( & mut self , n : u64 ) -> Result < ( ) > {
518- let n_keep = self . mem_regions . len ( ) - n as usize ;
519- for ( k, region) in self . mem_regions . split_off ( n_keep) . iter ( ) . enumerate ( ) {
520+ let n_keep = self . mmap_regions . len ( ) - n as usize ;
521+ let n_sandbox_regions = self . mem_regions . len ( ) ;
522+ for ( k, region) in self . mmap_regions . split_off ( n_keep) . iter ( ) . enumerate ( ) {
520523 let mut kvm_region: kvm_userspace_memory_region = region. clone ( ) . into ( ) ;
521- kvm_region. slot = ( n_keep + k) as u32 ;
524+ kvm_region. slot = ( n_sandbox_regions + n_keep + k) as u32 ;
522525 // Setting memory_size to 0 unmaps the slot's region
523526 // From https://docs.kernel.org/virt/kvm/api.html
524527 // > Deleting a slot is done by passing zero for memory_size.
@@ -756,25 +759,11 @@ impl Hypervisor for KVMDriver {
756759
757760 // TODO: Implement getting additional host-mapped dirty pages.
758761 fn get_and_clear_dirty_pages ( & mut self ) -> Result < Vec < u64 > > {
759- let n_contiguous = self
760- . mem_regions
761- . windows ( 2 )
762- . take_while ( |window| window[ 0 ] . guest_region . end == window[ 1 ] . guest_region . start )
763- . count ( )
764- + 1 ; // +1 because windows(2) gives us n-1 pairs for n regions
765-
766- if n_contiguous != self . n_initial_regions {
767- return Err ( new_error ! (
768- "get_and_clear_dirty_pages: not all regions are contiguous, expected {} but got {}" ,
769- self . n_initial_regions,
770- n_contiguous
771- ) ) ;
772- }
773762 let mut page_indices = vec ! [ ] ;
774763 let mut current_page = 0 ;
775764
776765 // Iterate over all memory regions and get the dirty pages for each region ignoring guard pages which cannot be dirty
777- for ( i, mem_region) in self . mem_regions . iter ( ) . take ( n_contiguous ) . enumerate ( ) {
766+ for ( i, mem_region) in self . mem_regions . iter ( ) . enumerate ( ) {
778767 let num_pages = mem_region. guest_region . len ( ) / PAGE_SIZE_USIZE ;
779768 let bitmap = match mem_region. flags {
780769 MemoryRegionFlags :: READ => {
0 commit comments