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