@@ -608,27 +608,14 @@ impl<T: GuestMemory + ?Sized> Bytes<GuestAddress> for T {
608
608
#[ cfg( test) ]
609
609
mod tests {
610
610
#![ allow( clippy:: undocumented_unsafe_blocks) ]
611
+
611
612
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" ) ]
617
613
use std:: time:: { Duration , Instant } ;
618
614
619
- use vmm_sys_util:: tempfile:: TempFile ;
620
-
621
- #[ cfg( feature = "backend-mmap" ) ]
622
- type GuestMemoryMmap = crate :: GuestMemoryMmap < ( ) > ;
623
-
624
615
#[ 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 ;
632
619
633
620
#[ test]
634
621
fn test_file_offset ( ) {
@@ -643,19 +630,29 @@ mod tests {
643
630
}
644
631
645
632
#[ 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
+
646
641
#[ test]
642
+ #[ cfg( feature = "backend-mmap" ) ]
647
643
fn checked_read_from ( ) {
648
644
let start_addr1 = GuestAddress ( 0x0 ) ;
649
645
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
+ }
659
656
}
660
657
661
658
// Runs the provided closure in a loop, until at least `duration` time units have elapsed.
@@ -684,8 +681,8 @@ mod tests {
684
681
// flips all the bits of the member with every write, while the reader checks that every byte
685
682
// has the same value (and thus it did not do a non-atomic access). The test succeeds if
686
683
// no mismatch is detected after performing accesses for a pre-determined amount of time.
687
- #[ cfg( feature = "backend-mmap" ) ]
688
684
#[ cfg( not( miri) ) ] // This test simulates a race condition between guest and vmm
685
+ #[ cfg( feature = "backend-mmap" ) ]
689
686
fn non_atomic_access_helper < T > ( )
690
687
where
691
688
T : ByteValued
@@ -722,69 +719,68 @@ mod tests {
722
719
// The address where we start writing/reading a Data<T> value.
723
720
let data_start = GuestAddress ( ( region_len - mem:: size_of :: < T > ( ) ) as u64 ) ;
724
721
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
+ }
764
760
}
765
- }
766
- count += 1 ;
761
+ count += 1 ;
762
+ } ) ;
767
763
} ) ;
768
- } ) ;
769
764
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
+ } ) ;
775
770
776
- t. join ( ) . unwrap ( )
771
+ t. join ( ) . unwrap ( )
772
+ }
777
773
}
778
774
779
- #[ cfg( feature = "backend-mmap" ) ]
780
775
#[ test]
781
776
#[ cfg( not( miri) ) ]
777
+ #[ cfg( feature = "backend-mmap" ) ]
782
778
fn test_non_atomic_access ( ) {
783
779
non_atomic_access_helper :: < u16 > ( )
784
780
}
785
781
786
- #[ cfg( feature = "backend-mmap" ) ]
787
782
#[ test]
783
+ #[ cfg( feature = "backend-mmap" ) ]
788
784
fn test_zero_length_accesses ( ) {
789
785
#[ derive( Default , Clone , Copy ) ]
790
786
#[ repr( C ) ]
@@ -795,47 +791,49 @@ mod tests {
795
791
unsafe impl ByteValued for ZeroSizedStruct { }
796
792
797
793
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
+ }
830
827
}
831
828
832
- #[ cfg( feature = "backend-mmap" ) ]
833
829
#[ cfg( target_os = "linux" ) ]
834
830
#[ test]
831
+ #[ cfg( feature = "backend-mmap" ) ]
835
832
fn test_guest_memory_mmap_is_hugetlbfs ( ) {
836
833
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
+ }
840
838
}
841
839
}
0 commit comments