@@ -18,16 +18,13 @@ use std::io::{Seek, SeekFrom};
1818use std:: ops:: Deref ;
1919use std:: result;
2020use std:: sync:: atomic:: Ordering ;
21- use std:: sync:: Arc ;
2221
2322use crate :: address:: Address ;
2423use crate :: bitmap:: { Bitmap , BS } ;
25- use crate :: guest_memory:: {
26- self , FileOffset , GuestAddress , GuestMemory , GuestUsize , MemoryRegionAddress ,
27- } ;
24+ use crate :: guest_memory:: { self , FileOffset , GuestAddress , GuestUsize , MemoryRegionAddress } ;
2825use crate :: region:: GuestMemoryRegion ;
2926use crate :: volatile_memory:: { VolatileMemory , VolatileSlice } ;
30- use crate :: { AtomicAccess , Bytes , ReadVolatile , WriteVolatile } ;
27+ use crate :: { AtomicAccess , Bytes , Error , GuestRegionCollection , ReadVolatile , WriteVolatile } ;
3128
3229#[ cfg( all( not( feature = "xen" ) , unix) ) ]
3330pub use crate :: mmap_unix:: { Error as MmapRegionError , MmapRegion , MmapRegionBuilder } ;
@@ -50,27 +47,6 @@ impl NewBitmap for () {
5047 fn with_len ( _len : usize ) -> Self { }
5148}
5249
53- /// Errors that can occur when creating a memory map.
54- #[ derive( Debug , thiserror:: Error ) ]
55- pub enum Error {
56- /// Adding the guest base address to the length of the underlying mapping resulted
57- /// in an overflow.
58- #[ error( "Adding the guest base address to the length of the underlying mapping resulted in an overflow" ) ]
59- InvalidGuestRegion ,
60- /// Error creating a `MmapRegion` object.
61- #[ error( "{0}" ) ]
62- MmapRegion ( MmapRegionError ) ,
63- /// No memory region found.
64- #[ error( "No memory region found" ) ]
65- NoMemoryRegion ,
66- /// Some of the memory regions intersect with each other.
67- #[ error( "Some of the memory regions intersect with each other" ) ]
68- MemoryRegionOverlap ,
69- /// The provided memory regions haven't been sorted.
70- #[ error( "The provided memory regions haven't been sorted" ) ]
71- UnsortedMemoryRegions ,
72- }
73-
7450// TODO: use this for Windows as well after we redefine the Error type there.
7551#[ cfg( unix) ]
7652/// Checks if a mapping of `size` bytes fits at the provided `file_offset`.
@@ -367,17 +343,9 @@ impl<B: Bitmap> GuestMemoryRegion for GuestRegionMmap<B> {
367343/// Represents the entire physical memory of the guest by tracking all its memory regions.
368344/// Each region is an instance of `GuestRegionMmap`, being backed by a mapping in the
369345/// virtual address space of the calling process.
370- #[ derive( Clone , Debug , Default ) ]
371- pub struct GuestMemoryMmap < B = ( ) > {
372- regions : Vec < Arc < GuestRegionMmap < B > > > ,
373- }
346+ pub type GuestMemoryMmap < B = ( ) > = GuestRegionCollection < GuestRegionMmap < B > > ;
374347
375348impl < B : NewBitmap > GuestMemoryMmap < B > {
376- /// Creates an empty `GuestMemoryMmap` instance.
377- pub fn new ( ) -> Self {
378- Self :: default ( )
379- }
380-
381349 /// Creates a container and allocates anonymous memory for guest memory regions.
382350 ///
383351 /// Valid memory regions are specified as a slice of (Address, Size) tuples sorted by Address.
@@ -405,111 +373,6 @@ impl<B: NewBitmap> GuestMemoryMmap<B> {
405373 }
406374}
407375
408- impl < B : Bitmap > GuestMemoryMmap < B > {
409- /// Creates a new `GuestMemoryMmap` from a vector of regions.
410- ///
411- /// # Arguments
412- ///
413- /// * `regions` - The vector of regions.
414- /// The regions shouldn't overlap and they should be sorted
415- /// by the starting address.
416- pub fn from_regions ( mut regions : Vec < GuestRegionMmap < B > > ) -> result:: Result < Self , Error > {
417- Self :: from_arc_regions ( regions. drain ( ..) . map ( Arc :: new) . collect ( ) )
418- }
419-
420- /// Creates a new `GuestMemoryMmap` from a vector of Arc regions.
421- ///
422- /// Similar to the constructor `from_regions()` as it returns a
423- /// `GuestMemoryMmap`. The need for this constructor is to provide a way for
424- /// consumer of this API to create a new `GuestMemoryMmap` based on existing
425- /// regions coming from an existing `GuestMemoryMmap` instance.
426- ///
427- /// # Arguments
428- ///
429- /// * `regions` - The vector of `Arc` regions.
430- /// The regions shouldn't overlap and they should be sorted
431- /// by the starting address.
432- pub fn from_arc_regions ( regions : Vec < Arc < GuestRegionMmap < B > > > ) -> result:: Result < Self , Error > {
433- if regions. is_empty ( ) {
434- return Err ( Error :: NoMemoryRegion ) ;
435- }
436-
437- for window in regions. windows ( 2 ) {
438- let prev = & window[ 0 ] ;
439- let next = & window[ 1 ] ;
440-
441- if prev. start_addr ( ) > next. start_addr ( ) {
442- return Err ( Error :: UnsortedMemoryRegions ) ;
443- }
444-
445- if prev. last_addr ( ) >= next. start_addr ( ) {
446- return Err ( Error :: MemoryRegionOverlap ) ;
447- }
448- }
449-
450- Ok ( Self { regions } )
451- }
452-
453- /// Insert a region into the `GuestMemoryMmap` object and return a new `GuestMemoryMmap`.
454- ///
455- /// # Arguments
456- /// * `region`: the memory region to insert into the guest memory object.
457- pub fn insert_region (
458- & self ,
459- region : Arc < GuestRegionMmap < B > > ,
460- ) -> result:: Result < GuestMemoryMmap < B > , Error > {
461- let mut regions = self . regions . clone ( ) ;
462- regions. push ( region) ;
463- regions. sort_by_key ( |x| x. start_addr ( ) ) ;
464-
465- Self :: from_arc_regions ( regions)
466- }
467-
468- /// Remove a region into the `GuestMemoryMmap` object and return a new `GuestMemoryMmap`
469- /// on success, together with the removed region.
470- ///
471- /// # Arguments
472- /// * `base`: base address of the region to be removed
473- /// * `size`: size of the region to be removed
474- pub fn remove_region (
475- & self ,
476- base : GuestAddress ,
477- size : GuestUsize ,
478- ) -> result:: Result < ( GuestMemoryMmap < B > , Arc < GuestRegionMmap < B > > ) , Error > {
479- if let Ok ( region_index) = self . regions . binary_search_by_key ( & base, |x| x. start_addr ( ) ) {
480- if self . regions . get ( region_index) . unwrap ( ) . mapping . size ( ) as GuestUsize == size {
481- let mut regions = self . regions . clone ( ) ;
482- let region = regions. remove ( region_index) ;
483- return Ok ( ( Self { regions } , region) ) ;
484- }
485- }
486-
487- Err ( Error :: InvalidGuestRegion )
488- }
489- }
490-
491- impl < B : Bitmap + ' static > GuestMemory for GuestMemoryMmap < B > {
492- type R = GuestRegionMmap < B > ;
493-
494- fn num_regions ( & self ) -> usize {
495- self . regions . len ( )
496- }
497-
498- fn find_region ( & self , addr : GuestAddress ) -> Option < & GuestRegionMmap < B > > {
499- let index = match self . regions . binary_search_by_key ( & addr, |x| x. start_addr ( ) ) {
500- Ok ( x) => Some ( x) ,
501- // Within the closest region with starting address < addr
502- Err ( x) if ( x > 0 && addr <= self . regions [ x - 1 ] . last_addr ( ) ) => Some ( x - 1 ) ,
503- _ => None ,
504- } ;
505- index. map ( |x| self . regions [ x] . as_ref ( ) )
506- }
507-
508- fn iter ( & self ) -> impl Iterator < Item = & Self :: R > {
509- self . regions . iter ( ) . map ( AsRef :: as_ref)
510- }
511- }
512-
513376#[ cfg( test) ]
514377mod tests {
515378 #![ allow( clippy:: undocumented_unsafe_blocks) ]
@@ -519,16 +382,17 @@ mod tests {
519382
520383 use crate :: bitmap:: tests:: test_guest_memory_and_region;
521384 use crate :: bitmap:: AtomicBitmap ;
522- use crate :: GuestAddressSpace ;
385+ use crate :: { Error , GuestAddressSpace , GuestMemory } ;
523386
524387 use std:: io:: Write ;
525388 use std:: mem;
389+ use std:: sync:: Arc ;
526390 #[ cfg( feature = "rawfd" ) ]
527391 use std:: { fs:: File , path:: Path } ;
528392 use vmm_sys_util:: tempfile:: TempFile ;
529393
530- type GuestMemoryMmap = super :: GuestMemoryMmap < ( ) > ;
531394 type GuestRegionMmap = super :: GuestRegionMmap < ( ) > ;
395+ type GuestMemoryMmap = super :: GuestRegionCollection < GuestRegionMmap > ;
532396 type MmapRegion = super :: MmapRegion < ( ) > ;
533397
534398 #[ test]
@@ -553,9 +417,8 @@ mod tests {
553417 }
554418 assert_eq ! ( guest_mem. last_addr( ) , last_addr) ;
555419 }
556- for ( ( region_addr, region_size) , mmap) in expected_regions_summary
557- . iter ( )
558- . zip ( guest_mem. regions . iter ( ) )
420+ for ( ( region_addr, region_size) , mmap) in
421+ expected_regions_summary. iter ( ) . zip ( guest_mem. iter ( ) )
559422 {
560423 assert_eq ! ( region_addr, & mmap. guest_base) ;
561424 assert_eq ! ( region_size, & mmap. mapping. size( ) ) ;
@@ -746,7 +609,7 @@ mod tests {
746609 let regions_summary = [ ( GuestAddress ( 0 ) , 100_usize ) , ( GuestAddress ( 100 ) , 100_usize ) ] ;
747610
748611 let guest_mem = GuestMemoryMmap :: new ( ) ;
749- assert_eq ! ( guest_mem. regions . len ( ) , 0 ) ;
612+ assert_eq ! ( guest_mem. num_regions ( ) , 0 ) ;
750613
751614 check_guest_memory_mmap ( new_guest_memory_mmap ( & regions_summary) , & regions_summary) ;
752615
@@ -1084,8 +947,10 @@ mod tests {
1084947 . map( |x| ( x. 0 , x. 1 ) )
1085948 . eq( iterated_regions. iter( ) . copied( ) ) ) ;
1086949
1087- assert_eq ! ( gm. regions[ 0 ] . guest_base, regions[ 0 ] . 0 ) ;
1088- assert_eq ! ( gm. regions[ 1 ] . guest_base, regions[ 1 ] . 0 ) ;
950+ let mmap_regions = gm. iter ( ) . collect :: < Vec < _ > > ( ) ;
951+
952+ assert_eq ! ( mmap_regions[ 0 ] . guest_base, regions[ 0 ] . 0 ) ;
953+ assert_eq ! ( mmap_regions[ 1 ] . guest_base, regions[ 1 ] . 0 ) ;
1089954 }
1090955
1091956 #[ test]
@@ -1113,8 +978,10 @@ mod tests {
1113978 . map( |x| ( x. 0 , x. 1 ) )
1114979 . eq( iterated_regions. iter( ) . copied( ) ) ) ;
1115980
1116- assert_eq ! ( gm. regions[ 0 ] . guest_base, regions[ 0 ] . 0 ) ;
1117- assert_eq ! ( gm. regions[ 1 ] . guest_base, regions[ 1 ] . 0 ) ;
981+ let mmap_regions = gm. iter ( ) . collect :: < Vec < _ > > ( ) ;
982+
983+ assert_eq ! ( mmap_regions[ 0 ] . guest_base, regions[ 0 ] . 0 ) ;
984+ assert_eq ! ( mmap_regions[ 1 ] . guest_base, regions[ 1 ] . 0 ) ;
1118985 }
1119986
1120987 #[ test]
@@ -1223,11 +1090,13 @@ mod tests {
12231090 assert_eq ! ( mem_orig. num_regions( ) , 2 ) ;
12241091 assert_eq ! ( gm. num_regions( ) , 5 ) ;
12251092
1226- assert_eq ! ( gm. regions[ 0 ] . start_addr( ) , GuestAddress ( 0x0000 ) ) ;
1227- assert_eq ! ( gm. regions[ 1 ] . start_addr( ) , GuestAddress ( 0x4000 ) ) ;
1228- assert_eq ! ( gm. regions[ 2 ] . start_addr( ) , GuestAddress ( 0x8000 ) ) ;
1229- assert_eq ! ( gm. regions[ 3 ] . start_addr( ) , GuestAddress ( 0xc000 ) ) ;
1230- assert_eq ! ( gm. regions[ 4 ] . start_addr( ) , GuestAddress ( 0x10_0000 ) ) ;
1093+ let regions = gm. iter ( ) . collect :: < Vec < _ > > ( ) ;
1094+
1095+ assert_eq ! ( regions[ 0 ] . start_addr( ) , GuestAddress ( 0x0000 ) ) ;
1096+ assert_eq ! ( regions[ 1 ] . start_addr( ) , GuestAddress ( 0x4000 ) ) ;
1097+ assert_eq ! ( regions[ 2 ] . start_addr( ) , GuestAddress ( 0x8000 ) ) ;
1098+ assert_eq ! ( regions[ 3 ] . start_addr( ) , GuestAddress ( 0xc000 ) ) ;
1099+ assert_eq ! ( regions[ 4 ] . start_addr( ) , GuestAddress ( 0x10_0000 ) ) ;
12311100 }
12321101
12331102 #[ test]
@@ -1248,7 +1117,7 @@ mod tests {
12481117 assert_eq ! ( mem_orig. num_regions( ) , 2 ) ;
12491118 assert_eq ! ( gm. num_regions( ) , 1 ) ;
12501119
1251- assert_eq ! ( gm. regions [ 0 ] . start_addr( ) , GuestAddress ( 0x0000 ) ) ;
1120+ assert_eq ! ( gm. iter ( ) . next ( ) . unwrap ( ) . start_addr( ) , GuestAddress ( 0x0000 ) ) ;
12521121 assert_eq ! ( region. start_addr( ) , GuestAddress ( 0x10_0000 ) ) ;
12531122 }
12541123
0 commit comments