@@ -709,27 +709,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
709
709
#[ cfg( test) ]
710
710
mod tests {
711
711
#![ allow( clippy:: undocumented_unsafe_blocks) ]
712
+
712
713
use super :: * ;
713
- #[ cfg( feature = "backend-mmap" ) ]
714
- use crate :: bytes:: ByteValued ;
715
- #[ cfg( feature = "backend-mmap" ) ]
716
- use crate :: GuestAddress ;
717
- #[ cfg( feature = "backend-mmap" ) ]
718
714
use std:: time:: { Duration , Instant } ;
719
715
720
- use vmm_sys_util:: tempfile:: TempFile ;
721
-
722
- #[ cfg( feature = "backend-mmap" ) ]
723
- type GuestMemoryMmap = crate :: GuestMemoryMmap < ( ) > ;
724
-
725
716
#[ cfg( feature = "backend-mmap" ) ]
726
- fn make_image ( size : u8 ) -> Vec < u8 > {
727
- let mut image: Vec < u8 > = Vec :: with_capacity ( size as usize ) ;
728
- for i in 0 ..size {
729
- image. push ( i) ;
730
- }
731
- image
732
- }
717
+ use crate :: mmap:: tests:: AnyBackend ;
718
+ use crate :: ByteValued ;
719
+ use vmm_sys_util:: tempfile:: TempFile ;
733
720
734
721
#[ test]
735
722
fn test_file_offset ( ) {
@@ -744,19 +731,29 @@ mod tests {
744
731
}
745
732
746
733
#[ cfg( feature = "backend-mmap" ) ]
734
+ fn make_image ( size : u8 ) -> Vec < u8 > {
735
+ let mut image: Vec < u8 > = Vec :: with_capacity ( size as usize ) ;
736
+ for i in 0 ..size {
737
+ image. push ( i) ;
738
+ }
739
+ image
740
+ }
741
+
747
742
#[ test]
743
+ #[ cfg( feature = "backend-mmap" ) ]
748
744
fn checked_read_from ( ) {
749
745
let start_addr1 = GuestAddress ( 0x0 ) ;
750
746
let start_addr2 = GuestAddress ( 0x40 ) ;
751
- let mem = GuestMemoryMmap :: from_ranges ( & [ ( start_addr1, 64 ) , ( start_addr2, 64 ) ] ) . unwrap ( ) ;
752
- let image = make_image ( 0x80 ) ;
753
- let offset = GuestAddress ( 0x30 ) ;
754
- let count: usize = 0x20 ;
755
- assert_eq ! (
756
- 0x20_usize ,
757
- mem. read_volatile_from( offset, & mut image. as_slice( ) , count)
758
- . unwrap( )
759
- ) ;
747
+ for mem in AnyBackend :: all ( & [ ( start_addr1, 64 , None ) , ( start_addr2, 64 , None ) ] ) {
748
+ let image = make_image ( 0x80 ) ;
749
+ let offset = GuestAddress ( 0x30 ) ;
750
+ let count: usize = 0x20 ;
751
+ assert_eq ! (
752
+ 0x20_usize ,
753
+ mem. read_volatile_from( offset, & mut image. as_slice( ) , count)
754
+ . unwrap( )
755
+ ) ;
756
+ }
760
757
}
761
758
762
759
// Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -785,8 +782,8 @@ mod tests {
785
782
// flips all the bits of the member with every write, while the reader checks that every byte
786
783
// has the same value (and thus it did not do a non-atomic access). The test succeeds if
787
784
// no mismatch is detected after performing accesses for a pre-determined amount of time.
788
- #[ cfg( feature = "backend-mmap" ) ]
789
785
#[ cfg( not( miri) ) ] // This test simulates a race condition between guest and vmm
786
+ #[ cfg( feature = "backend-mmap" ) ]
790
787
fn non_atomic_access_helper < T > ( )
791
788
where
792
789
T : ByteValued
@@ -823,69 +820,68 @@ mod tests {
823
820
// The address where we start writing/reading a Data<T> value.
824
821
let data_start = GuestAddress ( ( region_len - mem:: size_of :: < T > ( ) ) as u64 ) ;
825
822
826
- let mem = GuestMemoryMmap :: from_ranges ( & [
827
- ( start, region_len) ,
828
- ( start. unchecked_add ( region_len as u64 ) , region_len) ,
829
- ] )
830
- . unwrap ( ) ;
831
-
832
- // Need to clone this and move it into the new thread we create.
833
- let mem2 = mem. clone ( ) ;
834
- // Just some bytes.
835
- let some_bytes = [ 1u8 , 2 , 4 , 16 , 32 , 64 , 128 , 255 ] ;
836
-
837
- let mut data = Data {
838
- val : T :: from ( 0u8 ) ,
839
- some_bytes,
840
- } ;
841
-
842
- // Simple check that cross-region write/read is ok.
843
- mem. write_obj ( data, data_start) . unwrap ( ) ;
844
- let read_data = mem. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
845
- assert_eq ! ( read_data, data) ;
846
-
847
- let t = thread:: spawn ( move || {
848
- let mut count: u64 = 0 ;
849
-
850
- loop_timed ( Duration :: from_secs ( 3 ) , || {
851
- let data = mem2. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
852
-
853
- // Every time data is written to memory by the other thread, the value of
854
- // data.val alternates between 0 and T::MAX, so the inner bytes should always
855
- // have the same value. If they don't match, it means we read a partial value,
856
- // so the access was not atomic.
857
- let bytes = data. val . into ( ) . to_le_bytes ( ) ;
858
- for i in 1 ..mem:: size_of :: < T > ( ) {
859
- if bytes[ 0 ] != bytes[ i] {
860
- panic ! (
861
- "val bytes don't match {:?} after {} iterations" ,
862
- & bytes[ ..mem:: size_of:: <T >( ) ] ,
863
- count
864
- ) ;
823
+ for mem in AnyBackend :: all ( & [
824
+ ( start, region_len, None ) ,
825
+ ( start. unchecked_add ( region_len as u64 ) , region_len, None ) ,
826
+ ] ) {
827
+ // Need to clone this and move it into the new thread we create.
828
+ let mem2 = mem. clone ( ) ;
829
+ // Just some bytes.
830
+ let some_bytes = [ 1u8 , 2 , 4 , 16 , 32 , 64 , 128 , 255 ] ;
831
+
832
+ let mut data = Data {
833
+ val : T :: from ( 0u8 ) ,
834
+ some_bytes,
835
+ } ;
836
+
837
+ // Simple check that cross-region write/read is ok.
838
+ mem. write_obj ( data, data_start) . unwrap ( ) ;
839
+ let read_data = mem. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
840
+ assert_eq ! ( read_data, data) ;
841
+
842
+ let t = thread:: spawn ( move || {
843
+ let mut count: u64 = 0 ;
844
+
845
+ loop_timed ( Duration :: from_secs ( 3 ) , || {
846
+ let data = mem2. read_obj :: < Data < T > > ( data_start) . unwrap ( ) ;
847
+
848
+ // Every time data is written to memory by the other thread, the value of
849
+ // data.val alternates between 0 and T::MAX, so the inner bytes should always
850
+ // have the same value. If they don't match, it means we read a partial value,
851
+ // so the access was not atomic.
852
+ let bytes = data. val . into ( ) . to_le_bytes ( ) ;
853
+ for i in 1 ..mem:: size_of :: < T > ( ) {
854
+ if bytes[ 0 ] != bytes[ i] {
855
+ panic ! (
856
+ "val bytes don't match {:?} after {} iterations" ,
857
+ & bytes[ ..mem:: size_of:: <T >( ) ] ,
858
+ count
859
+ ) ;
860
+ }
865
861
}
866
- }
867
- count += 1 ;
862
+ count += 1 ;
863
+ } ) ;
868
864
} ) ;
869
- } ) ;
870
865
871
- // Write the object while flipping the bits of data.val over and over again.
872
- loop_timed ( Duration :: from_secs ( 3 ) , || {
873
- mem. write_obj ( data, data_start) . unwrap ( ) ;
874
- data. val = !data. val ;
875
- } ) ;
866
+ // Write the object while flipping the bits of data.val over and over again.
867
+ loop_timed ( Duration :: from_secs ( 3 ) , || {
868
+ mem. write_obj ( data, data_start) . unwrap ( ) ;
869
+ data. val = !data. val ;
870
+ } ) ;
876
871
877
- t. join ( ) . unwrap ( )
872
+ t. join ( ) . unwrap ( )
873
+ }
878
874
}
879
875
880
- #[ cfg( feature = "backend-mmap" ) ]
881
876
#[ test]
882
877
#[ cfg( not( miri) ) ]
878
+ #[ cfg( feature = "backend-mmap" ) ]
883
879
fn test_non_atomic_access ( ) {
884
880
non_atomic_access_helper :: < u16 > ( )
885
881
}
886
882
887
- #[ cfg( feature = "backend-mmap" ) ]
888
883
#[ test]
884
+ #[ cfg( feature = "backend-mmap" ) ]
889
885
fn test_zero_length_accesses ( ) {
890
886
#[ derive( Default , Clone , Copy ) ]
891
887
#[ repr( C ) ]
@@ -896,47 +892,49 @@ mod tests {
896
892
unsafe impl ByteValued for ZeroSizedStruct { }
897
893
898
894
let addr = GuestAddress ( 0x1000 ) ;
899
- let mem = GuestMemoryMmap :: from_ranges ( & [ ( addr, 0x1000 ) ] ) . unwrap ( ) ;
900
- let obj = ZeroSizedStruct :: default ( ) ;
901
- let mut image = make_image ( 0x80 ) ;
902
-
903
- assert_eq ! ( mem. write( & [ ] , addr) . unwrap( ) , 0 ) ;
904
- assert_eq ! ( mem. read( & mut [ ] , addr) . unwrap( ) , 0 ) ;
905
-
906
- assert ! ( mem. write_slice( & [ ] , addr) . is_ok( ) ) ;
907
- assert ! ( mem. read_slice( & mut [ ] , addr) . is_ok( ) ) ;
908
-
909
- assert ! ( mem. write_obj( obj, addr) . is_ok( ) ) ;
910
- assert ! ( mem. read_obj:: <ZeroSizedStruct >( addr) . is_ok( ) ) ;
911
-
912
- assert_eq ! (
913
- mem. read_volatile_from( addr, & mut image. as_slice( ) , 0 )
914
- . unwrap( ) ,
915
- 0
916
- ) ;
917
-
918
- assert ! ( mem
919
- . read_exact_volatile_from( addr, & mut image. as_slice( ) , 0 )
920
- . is_ok( ) ) ;
921
-
922
- assert_eq ! (
923
- mem. write_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
924
- . unwrap( ) ,
925
- 0
926
- ) ;
927
-
928
- assert ! ( mem
929
- . write_all_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
930
- . is_ok( ) ) ;
895
+ for mem in AnyBackend :: all ( & [ ( addr, 0x1000 , None ) ] ) {
896
+ let obj = ZeroSizedStruct :: default ( ) ;
897
+ let mut image = make_image ( 0x80 ) ;
898
+
899
+ assert_eq ! ( mem. write( & [ ] , addr) . unwrap( ) , 0 ) ;
900
+ assert_eq ! ( mem. read( & mut [ ] , addr) . unwrap( ) , 0 ) ;
901
+
902
+ assert ! ( mem. write_slice( & [ ] , addr) . is_ok( ) ) ;
903
+ assert ! ( mem. read_slice( & mut [ ] , addr) . is_ok( ) ) ;
904
+
905
+ assert ! ( mem. write_obj( obj, addr) . is_ok( ) ) ;
906
+ assert ! ( mem. read_obj:: <ZeroSizedStruct >( addr) . is_ok( ) ) ;
907
+
908
+ assert_eq ! (
909
+ mem. read_volatile_from( addr, & mut image. as_slice( ) , 0 )
910
+ . unwrap( ) ,
911
+ 0
912
+ ) ;
913
+
914
+ assert ! ( mem
915
+ . read_exact_volatile_from( addr, & mut image. as_slice( ) , 0 )
916
+ . is_ok( ) ) ;
917
+
918
+ assert_eq ! (
919
+ mem. write_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
920
+ . unwrap( ) ,
921
+ 0
922
+ ) ;
923
+
924
+ assert ! ( mem
925
+ . write_all_volatile_to( addr, & mut image. as_mut_slice( ) , 0 )
926
+ . is_ok( ) ) ;
927
+ }
931
928
}
932
929
933
- #[ cfg( feature = "backend-mmap" ) ]
934
930
#[ cfg( target_os = "linux" ) ]
935
931
#[ test]
932
+ #[ cfg( feature = "backend-mmap" ) ]
936
933
fn test_guest_memory_mmap_is_hugetlbfs ( ) {
937
934
let addr = GuestAddress ( 0x1000 ) ;
938
- let mem = GuestMemoryMmap :: from_ranges ( & [ ( addr, 0x1000 ) ] ) . unwrap ( ) ;
939
- let r = mem. find_region ( addr) . unwrap ( ) ;
940
- assert_eq ! ( r. is_hugetlbfs( ) , None ) ;
935
+ for mem in AnyBackend :: all ( & [ ( addr, 0x1000 , None ) ] ) {
936
+ let r = mem. find_region ( addr) . unwrap ( ) ;
937
+ assert_eq ! ( r. is_hugetlbfs( ) , None ) ;
938
+ }
941
939
}
942
940
}
0 commit comments