@@ -726,27 +726,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
726726#[ cfg( test) ]
727727mod tests {
728728 #![ allow( clippy:: undocumented_unsafe_blocks) ]
729+
729730 use super :: * ;
730- #[ cfg( feature = "backend-mmap" ) ]
731- use crate :: bytes:: ByteValued ;
732- #[ cfg( feature = "backend-mmap" ) ]
733- use crate :: GuestAddress ;
734- #[ cfg( feature = "backend-mmap" ) ]
735731 use std:: time:: { Duration , Instant } ;
736732
737- use vmm_sys_util:: tempfile:: TempFile ;
738-
739- #[ cfg( feature = "backend-mmap" ) ]
740- type GuestMemoryMmap = crate :: GuestMemoryMmap < ( ) > ;
741-
742733 #[ cfg( feature = "backend-mmap" ) ]
743- fn make_image ( size : u8 ) -> Vec < u8 > {
744- let mut image: Vec < u8 > = Vec :: with_capacity ( size as usize ) ;
745- for i in 0 ..size {
746- image. push ( i) ;
747- }
748- image
749- }
734+ use crate :: mmap:: tests:: AnyBackend ;
735+ use crate :: ByteValued ;
736+ use vmm_sys_util:: tempfile:: TempFile ;
750737
751738 #[ test]
752739 fn test_file_offset ( ) {
@@ -761,19 +748,29 @@ mod tests {
761748 }
762749
763750 #[ cfg( feature = "backend-mmap" ) ]
751+ fn make_image ( size : u8 ) -> Vec < u8 > {
752+ let mut image: Vec < u8 > = Vec :: with_capacity ( size as usize ) ;
753+ for i in 0 ..size {
754+ image. push ( i) ;
755+ }
756+ image
757+ }
758+
764759 #[ test]
760+ #[ cfg( feature = "backend-mmap" ) ]
765761 fn checked_read_from ( ) {
766762 let start_addr1 = GuestAddress ( 0x0 ) ;
767763 let start_addr2 = GuestAddress ( 0x40 ) ;
768- let mem = GuestMemoryMmap :: from_ranges ( & [ ( start_addr1, 64 ) , ( start_addr2, 64 ) ] ) . unwrap ( ) ;
769- let image = make_image ( 0x80 ) ;
770- let offset = GuestAddress ( 0x30 ) ;
771- let count: usize = 0x20 ;
772- assert_eq ! (
773- 0x20_usize ,
774- mem. read_volatile_from( offset, & mut image. as_slice( ) , count)
775- . unwrap( )
776- ) ;
764+ for mem in AnyBackend :: all ( & [ ( start_addr1, 64 , None ) , ( start_addr2, 64 , None ) ] ) {
765+ let image = make_image ( 0x80 ) ;
766+ let offset = GuestAddress ( 0x30 ) ;
767+ let count: usize = 0x20 ;
768+ assert_eq ! (
769+ 0x20_usize ,
770+ mem. read_volatile_from( offset, & mut image. as_slice( ) , count)
771+ . unwrap( )
772+ ) ;
773+ }
777774 }
778775
779776 // Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -802,8 +799,8 @@ mod tests {
802799 // flips all the bits of the member with every write, while the reader checks that every byte
803800 // has the same value (and thus it did not do a non-atomic access). The test succeeds if
804801 // no mismatch is detected after performing accesses for a pre-determined amount of time.
805- #[ cfg( feature = "backend-mmap" ) ]
806802 #[ cfg( not( miri) ) ] // This test simulates a race condition between guest and vmm
803+ #[ cfg( feature = "backend-mmap" ) ]
807804 fn non_atomic_access_helper < T > ( )
808805 where
809806 T : ByteValued
@@ -840,69 +837,68 @@ mod tests {
840837 // The address where we start writing/reading a Data<T> value.
841838 let data_start = GuestAddress ( ( region_len - mem:: size_of :: < T > ( ) ) as u64 ) ;
842839
843- let mem = GuestMemoryMmap :: from_ranges ( & [
844- ( start, region_len) ,
845- ( start. unchecked_add ( region_len as u64 ) , region_len) ,
846- ] )
847- . unwrap ( ) ;
848-
849- // Need to clone this and move it into the new thread we create.
850- let mem2 = mem. clone ( ) ;
851- // Just some bytes.
852- let some_bytes = [ 1u8 , 2 , 4 , 16 , 32 , 64 , 128 , 255 ] ;
853-
854- let mut data = Data {
855- val : T :: from ( 0u8 ) ,
856- some_bytes,
857- } ;
858-
859- // Simple check that cross-region write/read is ok.
860- mem. write_obj ( data, data_start) . unwrap ( ) ;
861- let read_data = mem. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
862- assert_eq ! ( read_data, data) ;
863-
864- let t = thread:: spawn ( move || {
865- let mut count: u64 = 0 ;
866-
867- loop_timed ( Duration :: from_secs ( 3 ) , || {
868- let data = mem2. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
869-
870- // Every time data is written to memory by the other thread, the value of
871- // data.val alternates between 0 and T::MAX, so the inner bytes should always
872- // have the same value. If they don't match, it means we read a partial value,
873- // so the access was not atomic.
874- let bytes = data. val . into ( ) . to_le_bytes ( ) ;
875- for i in 1 ..mem:: size_of :: < T > ( ) {
876- if bytes[ 0 ] != bytes[ i] {
877- panic ! (
878- "val bytes don't match {:?} after {} iterations" ,
879- & bytes[ ..mem:: size_of:: <T >( ) ] ,
880- count
881- ) ;
840+ for mem in AnyBackend :: all ( & [
841+ ( start, region_len, None ) ,
842+ ( start. unchecked_add ( region_len as u64 ) , region_len, None ) ,
843+ ] ) {
844+ // Need to clone this and move it into the new thread we create.
845+ let mem2 = mem. clone ( ) ;
846+ // Just some bytes.
847+ let some_bytes = [ 1u8 , 2 , 4 , 16 , 32 , 64 , 128 , 255 ] ;
848+
849+ let mut data = Data {
850+ val : T :: from ( 0u8 ) ,
851+ some_bytes,
852+ } ;
853+
854+ // Simple check that cross-region write/read is ok.
855+ mem. write_obj ( data, data_start) . unwrap ( ) ;
856+ let read_data = mem. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
857+ assert_eq ! ( read_data, data) ;
858+
859+ let t = thread:: spawn ( move || {
860+ let mut count: u64 = 0 ;
861+
862+ loop_timed ( Duration :: from_secs ( 3 ) , || {
863+ let data = mem2. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
864+
865+ // Every time data is written to memory by the other thread, the value of
866+ // data.val alternates between 0 and T::MAX, so the inner bytes should always
867+ // have the same value. If they don't match, it means we read a partial value,
868+ // so the access was not atomic.
869+ let bytes = data. val . into ( ) . to_le_bytes ( ) ;
870+ for i in 1 ..mem:: size_of :: < T > ( ) {
871+ if bytes[ 0 ] != bytes[ i] {
872+ panic ! (
873+ "val bytes don't match {:?} after {} iterations" ,
874+ & bytes[ ..mem:: size_of:: <T >( ) ] ,
875+ count
876+ ) ;
877+ }
882878 }
883- }
884- count += 1 ;
879+ count += 1 ;
880+ } ) ;
885881 } ) ;
886- } ) ;
887882
888- // Write the object while flipping the bits of data.val over and over again.
889- loop_timed ( Duration :: from_secs ( 3 ) , || {
890- mem. write_obj ( data, data_start) . unwrap ( ) ;
891- data. val = !data. val ;
892- } ) ;
883+ // Write the object while flipping the bits of data.val over and over again.
884+ loop_timed ( Duration :: from_secs ( 3 ) , || {
885+ mem. write_obj ( data, data_start) . unwrap ( ) ;
886+ data. val = !data. val ;
887+ } ) ;
893888
894- t. join ( ) . unwrap ( )
889+ t. join ( ) . unwrap ( )
890+ }
895891 }
896892
897- #[ cfg( feature = "backend-mmap" ) ]
898893 #[ test]
899894 #[ cfg( not( miri) ) ]
895+ #[ cfg( feature = "backend-mmap" ) ]
900896 fn test_non_atomic_access ( ) {
901897 non_atomic_access_helper :: < u16 > ( )
902898 }
903899
904- #[ cfg( feature = "backend-mmap" ) ]
905900 #[ test]
901+ #[ cfg( feature = "backend-mmap" ) ]
906902 fn test_zero_length_accesses ( ) {
907903 #[ derive( Default , Clone , Copy ) ]
908904 #[ repr( C ) ]
@@ -913,47 +909,49 @@ mod tests {
913909 unsafe impl ByteValued for ZeroSizedStruct { }
914910
915911 let addr = GuestAddress ( 0x1000 ) ;
916- let mem = GuestMemoryMmap :: from_ranges ( & [ ( addr, 0x1000 ) ] ) . unwrap ( ) ;
917- let obj = ZeroSizedStruct :: default ( ) ;
918- let mut image = make_image ( 0x80 ) ;
912+ for mem in AnyBackend :: all ( & [ ( addr, 0x1000 , None ) ] ) {
913+ let obj = ZeroSizedStruct :: default ( ) ;
914+ let mut image = make_image ( 0x80 ) ;
919915
920- assert_eq ! ( mem. write( & [ ] , addr) . unwrap( ) , 0 ) ;
921- assert_eq ! ( mem. read( & mut [ ] , addr) . unwrap( ) , 0 ) ;
916+ assert_eq ! ( mem. write( & [ ] , addr) . unwrap( ) , 0 ) ;
917+ assert_eq ! ( mem. read( & mut [ ] , addr) . unwrap( ) , 0 ) ;
922918
923- assert ! ( mem. write_slice( & [ ] , addr) . is_ok( ) ) ;
924- assert ! ( mem. read_slice( & mut [ ] , addr) . is_ok( ) ) ;
919+ assert ! ( mem. write_slice( & [ ] , addr) . is_ok( ) ) ;
920+ assert ! ( mem. read_slice( & mut [ ] , addr) . is_ok( ) ) ;
925921
926- assert ! ( mem. write_obj( obj, addr) . is_ok( ) ) ;
927- assert ! ( mem. read_obj:: <ZeroSizedStruct >( addr) . is_ok( ) ) ;
922+ assert ! ( mem. write_obj( obj, addr) . is_ok( ) ) ;
923+ assert ! ( mem. read_obj:: <ZeroSizedStruct >( addr) . is_ok( ) ) ;
928924
929- assert_eq ! (
930- mem. read_volatile_from( addr, & mut image. as_slice( ) , 0 )
931- . unwrap( ) ,
932- 0
933- ) ;
934-
935- assert ! ( mem
936- . read_exact_volatile_from( addr, & mut image. as_slice( ) , 0 )
937- . is_ok( ) ) ;
925+ assert_eq ! (
926+ mem. read_volatile_from( addr, & mut image. as_slice( ) , 0 )
927+ . unwrap( ) ,
928+ 0
929+ ) ;
938930
939- assert_eq ! (
940- mem. write_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
941- . unwrap( ) ,
942- 0
943- ) ;
931+ assert ! ( mem
932+ . read_exact_volatile_from( addr, & mut image. as_slice( ) , 0 )
933+ . is_ok( ) ) ;
944934
945- assert ! ( mem
946- . write_all_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
947- . is_ok( ) ) ;
935+ assert_eq ! (
936+ mem. write_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
937+ . unwrap( ) ,
938+ 0
939+ ) ;
940+
941+ assert ! ( mem
942+ . write_all_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
943+ . is_ok( ) ) ;
944+ }
948945 }
949946
950- #[ cfg( feature = "backend-mmap" ) ]
951947 #[ cfg( target_os = "linux" ) ]
952948 #[ test]
949+ #[ cfg( feature = "backend-mmap" ) ]
953950 fn test_guest_memory_mmap_is_hugetlbfs ( ) {
954951 let addr = GuestAddress ( 0x1000 ) ;
955- let mem = GuestMemoryMmap :: from_ranges ( & [ ( addr, 0x1000 ) ] ) . unwrap ( ) ;
956- let r = mem. find_region ( addr) . unwrap ( ) ;
957- assert_eq ! ( r. is_hugetlbfs( ) , None ) ;
952+ for mem in AnyBackend :: all ( & [ ( addr, 0x1000 , None ) ] ) {
953+ let r = mem. find_region ( addr) . unwrap ( ) ;
954+ assert_eq ! ( r. is_hugetlbfs( ) , None ) ;
955+ }
958956 }
959957}
0 commit comments