@@ -608,27 +608,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
608608#[ cfg( test) ]
609609mod tests {
610610 #![ allow( clippy:: undocumented_unsafe_blocks) ]
611+
611612 use super :: * ;
612- #[ cfg( feature = "backend-mmap" ) ]
613- use crate :: bytes:: ByteValued ;
614- #[ cfg( feature = "backend-mmap" ) ]
615- use crate :: GuestAddress ;
616- #[ cfg( feature = "backend-mmap" ) ]
617613 use std:: time:: { Duration , Instant } ;
618614
619- use vmm_sys_util:: tempfile:: TempFile ;
620-
621- #[ cfg( feature = "backend-mmap" ) ]
622- type GuestMemoryMmap = crate :: GuestMemoryMmap < ( ) > ;
623-
624615 #[ cfg( feature = "backend-mmap" ) ]
625- fn make_image ( size : u8 ) -> Vec < u8 > {
626- let mut image: Vec < u8 > = Vec :: with_capacity ( size as usize ) ;
627- for i in 0 ..size {
628- image. push ( i) ;
629- }
630- image
631- }
616+ use crate :: mmap:: tests:: AnyBackend ;
617+ use crate :: ByteValued ;
618+ use vmm_sys_util:: tempfile:: TempFile ;
632619
633620 #[ test]
634621 fn test_file_offset ( ) {
@@ -643,19 +630,29 @@ mod tests {
643630 }
644631
645632 #[ cfg( feature = "backend-mmap" ) ]
633+ fn make_image ( size : u8 ) -> Vec < u8 > {
634+ let mut image: Vec < u8 > = Vec :: with_capacity ( size as usize ) ;
635+ for i in 0 ..size {
636+ image. push ( i) ;
637+ }
638+ image
639+ }
640+
646641 #[ test]
642+ #[ cfg( feature = "backend-mmap" ) ]
647643 fn checked_read_from ( ) {
648644 let start_addr1 = GuestAddress ( 0x0 ) ;
649645 let start_addr2 = GuestAddress ( 0x40 ) ;
650- let mem = GuestMemoryMmap :: from_ranges ( & [ ( start_addr1, 64 ) , ( start_addr2, 64 ) ] ) . unwrap ( ) ;
651- let image = make_image ( 0x80 ) ;
652- let offset = GuestAddress ( 0x30 ) ;
653- let count: usize = 0x20 ;
654- assert_eq ! (
655- 0x20_usize ,
656- mem. read_volatile_from( offset, & mut image. as_slice( ) , count)
657- . unwrap( )
658- ) ;
646+ for mem in AnyBackend :: all ( & [ ( start_addr1, 64 , None ) , ( start_addr2, 64 , None ) ] ) {
647+ let image = make_image ( 0x80 ) ;
648+ let offset = GuestAddress ( 0x30 ) ;
649+ let count: usize = 0x20 ;
650+ assert_eq ! (
651+ 0x20_usize ,
652+ mem. read_volatile_from( offset, & mut image. as_slice( ) , count)
653+ . unwrap( )
654+ ) ;
655+ }
659656 }
660657
661658 // Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -684,8 +681,8 @@ mod tests {
684681 // flips all the bits of the member with every write, while the reader checks that every byte
685682 // has the same value (and thus it did not do a non-atomic access). The test succeeds if
686683 // no mismatch is detected after performing accesses for a pre-determined amount of time.
687- #[ cfg( feature = "backend-mmap" ) ]
688684 #[ cfg( not( miri) ) ] // This test simulates a race condition between guest and vmm
685+ #[ cfg( feature = "backend-mmap" ) ]
689686 fn non_atomic_access_helper < T > ( )
690687 where
691688 T : ByteValued
@@ -722,69 +719,68 @@ mod tests {
722719 // The address where we start writing/reading a Data<T> value.
723720 let data_start = GuestAddress ( ( region_len - mem:: size_of :: < T > ( ) ) as u64 ) ;
724721
725- let mem = GuestMemoryMmap :: from_ranges ( & [
726- ( start, region_len) ,
727- ( start. unchecked_add ( region_len as u64 ) , region_len) ,
728- ] )
729- . unwrap ( ) ;
730-
731- // Need to clone this and move it into the new thread we create.
732- let mem2 = mem. clone ( ) ;
733- // Just some bytes.
734- let some_bytes = [ 1u8 , 2 , 4 , 16 , 32 , 64 , 128 , 255 ] ;
735-
736- let mut data = Data {
737- val : T :: from ( 0u8 ) ,
738- some_bytes,
739- } ;
740-
741- // Simple check that cross-region write/read is ok.
742- mem. write_obj ( data, data_start) . unwrap ( ) ;
743- let read_data = mem. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
744- assert_eq ! ( read_data, data) ;
745-
746- let t = thread:: spawn ( move || {
747- let mut count: u64 = 0 ;
748-
749- loop_timed ( Duration :: from_secs ( 3 ) , || {
750- let data = mem2. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
751-
752- // Every time data is written to memory by the other thread, the value of
753- // data.val alternates between 0 and T::MAX, so the inner bytes should always
754- // have the same value. If they don't match, it means we read a partial value,
755- // so the access was not atomic.
756- let bytes = data. val . into ( ) . to_le_bytes ( ) ;
757- for i in 1 ..mem:: size_of :: < T > ( ) {
758- if bytes[ 0 ] != bytes[ i] {
759- panic ! (
760- "val bytes don't match {:?} after {} iterations" ,
761- & bytes[ ..mem:: size_of:: <T >( ) ] ,
762- count
763- ) ;
722+ for mem in AnyBackend :: all ( & [
723+ ( start, region_len, None ) ,
724+ ( start. unchecked_add ( region_len as u64 ) , region_len, None ) ,
725+ ] ) {
726+ // Need to clone this and move it into the new thread we create.
727+ let mem2 = mem. clone ( ) ;
728+ // Just some bytes.
729+ let some_bytes = [ 1u8 , 2 , 4 , 16 , 32 , 64 , 128 , 255 ] ;
730+
731+ let mut data = Data {
732+ val : T :: from ( 0u8 ) ,
733+ some_bytes,
734+ } ;
735+
736+ // Simple check that cross-region write/read is ok.
737+ mem. write_obj ( data, data_start) . unwrap ( ) ;
738+ let read_data = mem. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
739+ assert_eq ! ( read_data, data) ;
740+
741+ let t = thread:: spawn ( move || {
742+ let mut count: u64 = 0 ;
743+
744+ loop_timed ( Duration :: from_secs ( 3 ) , || {
745+ let data = mem2. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
746+
747+ // Every time data is written to memory by the other thread, the value of
748+ // data.val alternates between 0 and T::MAX, so the inner bytes should always
749+ // have the same value. If they don't match, it means we read a partial value,
750+ // so the access was not atomic.
751+ let bytes = data. val . into ( ) . to_le_bytes ( ) ;
752+ for i in 1 ..mem:: size_of :: < T > ( ) {
753+ if bytes[ 0 ] != bytes[ i] {
754+ panic ! (
755+ "val bytes don't match {:?} after {} iterations" ,
756+ & bytes[ ..mem:: size_of:: <T >( ) ] ,
757+ count
758+ ) ;
759+ }
764760 }
765- }
766- count += 1 ;
761+ count += 1 ;
762+ } ) ;
767763 } ) ;
768- } ) ;
769764
770- // Write the object while flipping the bits of data.val over and over again.
771- loop_timed ( Duration :: from_secs ( 3 ) , || {
772- mem. write_obj ( data, data_start) . unwrap ( ) ;
773- data. val = !data. val ;
774- } ) ;
765+ // Write the object while flipping the bits of data.val over and over again.
766+ loop_timed ( Duration :: from_secs ( 3 ) , || {
767+ mem. write_obj ( data, data_start) . unwrap ( ) ;
768+ data. val = !data. val ;
769+ } ) ;
775770
776- t. join ( ) . unwrap ( )
771+ t. join ( ) . unwrap ( )
772+ }
777773 }
778774
779- #[ cfg( feature = "backend-mmap" ) ]
780775 #[ test]
781776 #[ cfg( not( miri) ) ]
777+ #[ cfg( feature = "backend-mmap" ) ]
782778 fn test_non_atomic_access ( ) {
783779 non_atomic_access_helper :: < u16 > ( )
784780 }
785781
786- #[ cfg( feature = "backend-mmap" ) ]
787782 #[ test]
783+ #[ cfg( feature = "backend-mmap" ) ]
788784 fn test_zero_length_accesses ( ) {
789785 #[ derive( Default , Clone , Copy ) ]
790786 #[ repr( C ) ]
@@ -795,47 +791,49 @@ mod tests {
795791 unsafe impl ByteValued for ZeroSizedStruct { }
796792
797793 let addr = GuestAddress ( 0x1000 ) ;
798- let mem = GuestMemoryMmap :: from_ranges ( & [ ( addr, 0x1000 ) ] ) . unwrap ( ) ;
799- let obj = ZeroSizedStruct :: default ( ) ;
800- let mut image = make_image ( 0x80 ) ;
801-
802- assert_eq ! ( mem. write( & [ ] , addr) . unwrap( ) , 0 ) ;
803- assert_eq ! ( mem. read( & mut [ ] , addr) . unwrap( ) , 0 ) ;
804-
805- assert ! ( mem. write_slice( & [ ] , addr) . is_ok( ) ) ;
806- assert ! ( mem. read_slice( & mut [ ] , addr) . is_ok( ) ) ;
807-
808- assert ! ( mem. write_obj( obj, addr) . is_ok( ) ) ;
809- assert ! ( mem. read_obj:: <ZeroSizedStruct >( addr) . is_ok( ) ) ;
810-
811- assert_eq ! (
812- mem. read_volatile_from( addr, & mut image. as_slice( ) , 0 )
813- . unwrap( ) ,
814- 0
815- ) ;
816-
817- assert ! ( mem
818- . read_exact_volatile_from( addr, & mut image. as_slice( ) , 0 )
819- . is_ok( ) ) ;
820-
821- assert_eq ! (
822- mem. write_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
823- . unwrap( ) ,
824- 0
825- ) ;
826-
827- assert ! ( mem
828- . write_all_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
829- . is_ok( ) ) ;
794+ for mem in AnyBackend :: all ( & [ ( addr, 0x1000 , None ) ] ) {
795+ let obj = ZeroSizedStruct :: default ( ) ;
796+ let mut image = make_image ( 0x80 ) ;
797+
798+ assert_eq ! ( mem. write( & [ ] , addr) . unwrap( ) , 0 ) ;
799+ assert_eq ! ( mem. read( & mut [ ] , addr) . unwrap( ) , 0 ) ;
800+
801+ assert ! ( mem. write_slice( & [ ] , addr) . is_ok( ) ) ;
802+ assert ! ( mem. read_slice( & mut [ ] , addr) . is_ok( ) ) ;
803+
804+ assert ! ( mem. write_obj( obj, addr) . is_ok( ) ) ;
805+ assert ! ( mem. read_obj:: <ZeroSizedStruct >( addr) . is_ok( ) ) ;
806+
807+ assert_eq ! (
808+ mem. read_volatile_from( addr, & mut image. as_slice( ) , 0 )
809+ . unwrap( ) ,
810+ 0
811+ ) ;
812+
813+ assert ! ( mem
814+ . read_exact_volatile_from( addr, & mut image. as_slice( ) , 0 )
815+ . is_ok( ) ) ;
816+
817+ assert_eq ! (
818+ mem. write_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
819+ . unwrap( ) ,
820+ 0
821+ ) ;
822+
823+ assert ! ( mem
824+ . write_all_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
825+ . is_ok( ) ) ;
826+ }
830827 }
831828
832- #[ cfg( feature = "backend-mmap" ) ]
833829 #[ cfg( target_os = "linux" ) ]
834830 #[ test]
831+ #[ cfg( feature = "backend-mmap" ) ]
835832 fn test_guest_memory_mmap_is_hugetlbfs ( ) {
836833 let addr = GuestAddress ( 0x1000 ) ;
837- let mem = GuestMemoryMmap :: from_ranges ( & [ ( addr, 0x1000 ) ] ) . unwrap ( ) ;
838- let r = mem. find_region ( addr) . unwrap ( ) ;
839- assert_eq ! ( r. is_hugetlbfs( ) , None ) ;
834+ for mem in AnyBackend :: all ( & [ ( addr, 0x1000 , None ) ] ) {
835+ let r = mem. find_region ( addr) . unwrap ( ) ;
836+ assert_eq ! ( r. is_hugetlbfs( ) , None ) ;
837+ }
840838 }
841839}
0 commit comments