@@ -403,6 +403,10 @@ impl GuestMemoryRegion for GuestRegionMmap {
403
403
let slice = self . mapping . get_slice ( offset. raw_value ( ) as usize , count) ?;
404
404
Ok ( slice)
405
405
}
406
+
407
+ fn is_hugepages ( & self ) -> bool {
408
+ self . mapping . hugepages ( )
409
+ }
406
410
}
407
411
408
412
/// [`GuestMemory`](trait.GuestMemory.html) implementation that mmaps the guest's memory
@@ -434,6 +438,22 @@ impl GuestMemoryMmap {
434
438
/// Valid memory regions are specified as a sequence of (Address, Size, Option<FileOffset>)
435
439
/// tuples sorted by Address.
436
440
pub fn from_ranges_with_files < A , T > ( ranges : T ) -> result:: Result < Self , Error >
441
+ where
442
+ A : Borrow < ( GuestAddress , usize , Option < FileOffset > ) > ,
443
+ T : IntoIterator < Item = A > ,
444
+ {
445
+ Self :: from_ranges_with_files_and_hugepages ( ranges, false )
446
+ }
447
+
448
+ /// Creates a container and allocates anonymous memory for guest memory regions.
449
+ /// And set guest memory regions hugepages.
450
+ ///
451
+ /// Valid memory regions are specified as a sequence of (Address, Size, Option<FileOffset>)
452
+ /// tuples sorted by Address.
453
+ pub fn from_ranges_with_files_and_hugepages < A , T > (
454
+ ranges : T ,
455
+ hugepages : bool ,
456
+ ) -> result:: Result < Self , Error >
437
457
where
438
458
A : Borrow < ( GuestAddress , usize , Option < FileOffset > ) > ,
439
459
T : IntoIterator < Item = A > ,
@@ -445,13 +465,15 @@ impl GuestMemoryMmap {
445
465
let guest_base = x. borrow ( ) . 0 ;
446
466
let size = x. borrow ( ) . 1 ;
447
467
448
- if let Some ( ref f_off) = x. borrow ( ) . 2 {
468
+ let mut r = if let Some ( ref f_off) = x. borrow ( ) . 2 {
449
469
MmapRegion :: from_file ( f_off. clone ( ) , size)
450
470
} else {
451
471
MmapRegion :: new ( size)
452
472
}
453
- . map_err ( Error :: MmapRegion )
454
- . and_then ( |r| GuestRegionMmap :: new ( r, guest_base) )
473
+ . map_err ( Error :: MmapRegion ) ?;
474
+ r. set_hugepages ( hugepages) ;
475
+
476
+ GuestRegionMmap :: new ( r, guest_base)
455
477
} )
456
478
. collect :: < result:: Result < Vec < _ > , Error > > ( ) ?,
457
479
)
@@ -989,6 +1011,64 @@ mod tests {
989
1011
}
990
1012
}
991
1013
1014
+ #[ cfg( all( feature = "backend-mmap" , unix) ) ]
1015
+ #[ test]
1016
+ fn test_get_host_address_and_hugepages ( ) {
1017
+ let f1 = TempFile :: new ( ) . unwrap ( ) . into_file ( ) ;
1018
+ f1. set_len ( 0x400 ) . unwrap ( ) ;
1019
+ let f2 = TempFile :: new ( ) . unwrap ( ) . into_file ( ) ;
1020
+ f2. set_len ( 0x400 ) . unwrap ( ) ;
1021
+
1022
+ let start_addr1 = GuestAddress ( 0x0 ) ;
1023
+ let start_addr2 = GuestAddress ( 0x800 ) ;
1024
+ let guest_mem =
1025
+ GuestMemoryMmap :: from_ranges ( & [ ( start_addr1, 0x400 ) , ( start_addr2, 0x400 ) ] ) . unwrap ( ) ;
1026
+ let guest_mem_backed_by_file = GuestMemoryMmap :: from_ranges_with_files_and_hugepages (
1027
+ & [
1028
+ ( start_addr1, 0x400 , Some ( FileOffset :: new ( f1, 0 ) ) ) ,
1029
+ ( start_addr2, 0x400 , Some ( FileOffset :: new ( f2, 0 ) ) ) ,
1030
+ ] ,
1031
+ true ,
1032
+ )
1033
+ . unwrap ( ) ;
1034
+
1035
+ let guest_mem_list = vec ! [ guest_mem] ;
1036
+ for guest_mem in guest_mem_list. iter ( ) {
1037
+ assert ! ( guest_mem. get_host_address( GuestAddress ( 0x600 ) ) . is_err( ) ) ;
1038
+ let ( ptr0, ptr0_huge) = guest_mem
1039
+ . get_host_address_and_hugepages ( GuestAddress ( 0x800 ) )
1040
+ . unwrap ( ) ;
1041
+ let ( ptr1, ptr1_huge) = guest_mem
1042
+ . get_host_address_and_hugepages ( GuestAddress ( 0xa00 ) )
1043
+ . unwrap ( ) ;
1044
+ assert_eq ! (
1045
+ ptr0,
1046
+ guest_mem. find_region( GuestAddress ( 0x800 ) ) . unwrap( ) . as_ptr( )
1047
+ ) ;
1048
+ assert_eq ! ( ptr0_huge, false ) ;
1049
+ assert_eq ! ( ptr1_huge, false ) ;
1050
+ assert_eq ! ( unsafe { ptr0. offset( 0x200 ) } , ptr1) ;
1051
+ }
1052
+
1053
+ let guest_mem_list = vec ! [ guest_mem_backed_by_file] ;
1054
+ for guest_mem in guest_mem_list. iter ( ) {
1055
+ assert ! ( guest_mem. get_host_address( GuestAddress ( 0x600 ) ) . is_err( ) ) ;
1056
+ let ( ptr0, ptr0_huge) = guest_mem
1057
+ . get_host_address_and_hugepages ( GuestAddress ( 0x800 ) )
1058
+ . unwrap ( ) ;
1059
+ let ( ptr1, ptr1_huge) = guest_mem
1060
+ . get_host_address_and_hugepages ( GuestAddress ( 0xa00 ) )
1061
+ . unwrap ( ) ;
1062
+ assert_eq ! (
1063
+ ptr0,
1064
+ guest_mem. find_region( GuestAddress ( 0x800 ) ) . unwrap( ) . as_ptr( )
1065
+ ) ;
1066
+ assert_eq ! ( ptr0_huge, true ) ;
1067
+ assert_eq ! ( ptr1_huge, true ) ;
1068
+ assert_eq ! ( unsafe { ptr0. offset( 0x200 ) } , ptr1) ;
1069
+ }
1070
+ }
1071
+
992
1072
#[ test]
993
1073
fn test_deref ( ) {
994
1074
let f = TempFile :: new ( ) . unwrap ( ) . into_file ( ) ;
0 commit comments