1212//!
1313//! This implementation is mmap-ing the memory of the guest into the current process.
1414
15- use std:: borrow:: Borrow ;
1615#[ cfg( unix) ]
1716use std:: io:: { Seek , SeekFrom } ;
18- use std:: ops:: Deref ;
1917use std:: result;
2018
21- use crate :: address:: Address ;
22- use crate :: bitmap:: { Bitmap , BS } ;
23- use crate :: guest_memory:: { self , FileOffset , GuestAddress , GuestUsize , MemoryRegionAddress } ;
24- use crate :: region:: GuestMemoryRegion ;
25- use crate :: volatile_memory:: { VolatileMemory , VolatileSlice } ;
26- use crate :: { Error , GuestRegionCollection } ;
19+ use crate :: bitmap:: Bitmap ;
20+ use crate :: guest_memory:: FileOffset ;
2721
2822#[ cfg( all( not( feature = "xen" ) , unix) ) ]
2923pub use crate :: mmap_unix:: { Error as MmapRegionError , MmapRegion , MmapRegionBuilder } ;
3024
3125#[ cfg( all( feature = "xen" , unix) ) ]
3226pub use crate :: mmap_xen:: { Error as MmapRegionError , MmapRange , MmapRegion , MmapXenFlags } ;
3327
34- #[ cfg( windows) ]
35- pub use crate :: mmap_windows:: MmapRegion ;
36- #[ cfg( windows) ]
37- pub use std:: io:: Error as MmapRegionError ;
38-
3928/// A `Bitmap` that can be created starting from an initial size.
4029pub trait NewBitmap : Bitmap + Default {
4130 /// Create a new object based on the specified length in bytes.
@@ -91,166 +80,18 @@ pub fn check_file_offset(
9180 Ok ( ( ) )
9281}
9382
94- /// [`GuestMemoryRegion`](trait.GuestMemoryRegion.html) implementation that mmaps the guest's
95- /// memory region in the current process.
96- ///
97- /// Represents a continuous region of the guest's physical memory that is backed by a mapping
98- /// in the virtual address space of the calling process.
99- #[ derive( Debug ) ]
100- pub struct GuestRegionMmap < B = ( ) > {
101- mapping : MmapRegion < B > ,
102- guest_base : GuestAddress ,
103- }
104-
105- impl < B > Deref for GuestRegionMmap < B > {
106- type Target = MmapRegion < B > ;
107-
108- fn deref ( & self ) -> & MmapRegion < B > {
109- & self . mapping
110- }
111- }
112-
113- impl < B : Bitmap > GuestRegionMmap < B > {
114- /// Create a new memory-mapped memory region for the guest's physical memory.
115- pub fn new ( mapping : MmapRegion < B > , guest_base : GuestAddress ) -> result:: Result < Self , Error > {
116- if guest_base. 0 . checked_add ( mapping. size ( ) as u64 ) . is_none ( ) {
117- return Err ( Error :: InvalidGuestRegion ) ;
118- }
119-
120- Ok ( GuestRegionMmap {
121- mapping,
122- guest_base,
123- } )
124- }
125- }
126-
127- #[ cfg( not( feature = "xen" ) ) ]
128- impl < B : NewBitmap > GuestRegionMmap < B > {
129- /// Create a new memory-mapped memory region from guest's physical memory, size and file.
130- pub fn from_range (
131- addr : GuestAddress ,
132- size : usize ,
133- file : Option < FileOffset > ,
134- ) -> result:: Result < Self , Error > {
135- let region = if let Some ( ref f_off) = file {
136- MmapRegion :: from_file ( f_off. clone ( ) , size)
137- } else {
138- MmapRegion :: new ( size)
139- }
140- . map_err ( Error :: MmapRegion ) ?;
141-
142- Self :: new ( region, addr)
143- }
144- }
145-
146- #[ cfg( feature = "xen" ) ]
147- impl < B : NewBitmap > GuestRegionMmap < B > {
148- /// Create a new Unix memory-mapped memory region from guest's physical memory, size and file.
149- /// This must only be used for tests, doctests, benches and is not designed for end consumers.
150- pub fn from_range (
151- addr : GuestAddress ,
152- size : usize ,
153- file : Option < FileOffset > ,
154- ) -> result:: Result < Self , Error > {
155- let range = MmapRange :: new_unix ( size, file, addr) ;
156-
157- let region = MmapRegion :: from_range ( range) . map_err ( Error :: MmapRegion ) ?;
158- Self :: new ( region, addr)
159- }
160- }
161-
162- impl < B : Bitmap > GuestMemoryRegion for GuestRegionMmap < B > {
163- type B = B ;
164-
165- fn len ( & self ) -> GuestUsize {
166- self . mapping . size ( ) as GuestUsize
167- }
168-
169- fn start_addr ( & self ) -> GuestAddress {
170- self . guest_base
171- }
172-
173- fn bitmap ( & self ) -> & Self :: B {
174- self . mapping . bitmap ( )
175- }
176-
177- fn get_host_address ( & self , addr : MemoryRegionAddress ) -> guest_memory:: Result < * mut u8 > {
178- // Not sure why wrapping_offset is not unsafe. Anyway this
179- // is safe because we've just range-checked addr using check_address.
180- self . check_address ( addr)
181- . ok_or ( guest_memory:: Error :: InvalidBackendAddress )
182- . map ( |addr| {
183- self . mapping
184- . as_ptr ( )
185- . wrapping_offset ( addr. raw_value ( ) as isize )
186- } )
187- }
188-
189- fn file_offset ( & self ) -> Option < & FileOffset > {
190- self . mapping . file_offset ( )
191- }
192-
193- fn get_slice (
194- & self ,
195- offset : MemoryRegionAddress ,
196- count : usize ,
197- ) -> guest_memory:: Result < VolatileSlice < BS < B > > > {
198- let slice = VolatileMemory :: get_slice ( & self . mapping , offset. raw_value ( ) as usize , count) ?;
199- Ok ( slice)
200- }
201-
202- #[ cfg( target_os = "linux" ) ]
203- fn is_hugetlbfs ( & self ) -> Option < bool > {
204- self . mapping . is_hugetlbfs ( )
205- }
206- }
207-
208- /// [`GuestMemory`](trait.GuestMemory.html) implementation that mmaps the guest's memory
209- /// in the current process.
210- ///
211- /// Represents the entire physical memory of the guest by tracking all its memory regions.
212- /// Each region is an instance of `GuestRegionMmap`, being backed by a mapping in the
213- /// virtual address space of the calling process.
214- pub type GuestMemoryMmap < B = ( ) > = GuestRegionCollection < GuestRegionMmap < B > > ;
215-
216- impl < B : NewBitmap > GuestMemoryMmap < B > {
217- /// Creates a container and allocates anonymous memory for guest memory regions.
218- ///
219- /// Valid memory regions are specified as a slice of (Address, Size) tuples sorted by Address.
220- pub fn from_ranges ( ranges : & [ ( GuestAddress , usize ) ] ) -> result:: Result < Self , Error > {
221- Self :: from_ranges_with_files ( ranges. iter ( ) . map ( |r| ( r. 0 , r. 1 , None ) ) )
222- }
223-
224- /// Creates a container and allocates anonymous memory for guest memory regions.
225- ///
226- /// Valid memory regions are specified as a sequence of (Address, Size, [`Option<FileOffset>`])
227- /// tuples sorted by Address.
228- pub fn from_ranges_with_files < A , T > ( ranges : T ) -> result:: Result < Self , Error >
229- where
230- A : Borrow < ( GuestAddress , usize , Option < FileOffset > ) > ,
231- T : IntoIterator < Item = A > ,
232- {
233- Self :: from_regions (
234- ranges
235- . into_iter ( )
236- . map ( |x| {
237- GuestRegionMmap :: from_range ( x. borrow ( ) . 0 , x. borrow ( ) . 1 , x. borrow ( ) . 2 . clone ( ) )
238- } )
239- . collect :: < result:: Result < Vec < _ > , Error > > ( ) ?,
240- )
241- }
242- }
243-
24483#[ cfg( test) ]
24584pub ( crate ) mod tests {
24685 #![ allow( clippy:: undocumented_unsafe_blocks) ]
24786 extern crate vmm_sys_util;
24887
24988 use super :: * ;
25089
251- use crate :: bitmap:: tests:: test_guest_memory_and_region;
252- use crate :: bitmap:: AtomicBitmap ;
253- use crate :: { Bytes , GuestMemory , GuestMemoryError } ;
90+ use crate :: bitmap:: BS ;
91+ use crate :: {
92+ guest_memory, Address , Bytes , GuestAddress , GuestMemory , GuestMemoryError ,
93+ GuestMemoryRegion , GuestUsize , MemoryRegionAddress , VolatileMemory , VolatileSlice ,
94+ } ;
25495
25596 use std:: io:: Write ;
25697 use std:: mem;
@@ -312,9 +153,9 @@ pub(crate) mod tests {
312153
313154 any_backend ! {
314155 #[ cfg( all( windows, feature = "backend-mmap" ) ) ]
315- Windows [ GuestRegionMmap <( ) >] ,
156+ Windows [ crate :: mmap_windows :: GuestRegionWindows <( ) >] ,
316157 #[ cfg( all( unix, feature = "backend-mmap" , not( feature = "xen" ) ) ) ]
317- Mmap [ GuestRegionMmap <( ) >] ,
158+ Mmap [ crate :: mmap_unix :: GuestRegionMmap <( ) >] ,
318159 #[ cfg( all( unix, feature = "backend-mmap" , feature = "xen" ) ) ]
319160 Xen [ crate :: mmap_xen:: MmapRegion ]
320161 }
@@ -326,13 +167,19 @@ pub(crate) mod tests {
326167 let mut regions = Vec :: new ( ) ;
327168 #[ cfg( all( windows, feature = "backend-mmap" ) ) ]
328169 regions. push ( AnyRegion :: Windows (
329- GuestRegionMmap :: new ( MmapRegion :: from_file ( f_off. clone ( ) , size) . unwrap ( ) , addr)
330- . unwrap ( ) ,
170+ crate :: mmap_windows:: GuestRegionWindows :: new (
171+ crate :: mmap_windows:: MmapRegion :: from_file ( f_off. clone ( ) , size) . unwrap ( ) ,
172+ addr,
173+ )
174+ . unwrap ( ) ,
331175 ) ) ;
332176 #[ cfg( all( unix, feature = "backend-mmap" , not( feature = "xen" ) ) ) ]
333177 regions. push ( AnyRegion :: Mmap (
334- GuestRegionMmap :: new ( MmapRegion :: from_file ( f_off. clone ( ) , size) . unwrap ( ) , addr)
335- . unwrap ( ) ,
178+ crate :: mmap_unix:: GuestRegionMmap :: new (
179+ MmapRegion :: from_file ( f_off. clone ( ) , size) . unwrap ( ) ,
180+ addr,
181+ )
182+ . unwrap ( ) ,
336183 ) ) ;
337184 #[ cfg( all( unix, feature = "backend-mmap" , feature = "xen" ) ) ]
338185 regions. push ( AnyRegion :: Xen (
@@ -350,11 +197,16 @@ pub(crate) mod tests {
350197 } ;
351198 #[ cfg( all( windows, feature = "backend-mmap" ) ) ]
352199 regions. push ( AnyRegion :: Windows (
353- GuestRegionMmap :: new ( MmapRegion :: new ( size) . unwrap ( ) , addr) . unwrap ( ) ,
200+ crate :: mmap_windows:: GuestRegionWindows :: new (
201+ crate :: mmap_windows:: MmapRegion :: new ( size) . unwrap ( ) ,
202+ addr,
203+ )
204+ . unwrap ( ) ,
354205 ) ) ;
355206 #[ cfg( all( unix, feature = "backend-mmap" , not( feature = "xen" ) ) ) ]
356207 regions. push ( AnyRegion :: Mmap (
357- GuestRegionMmap :: new ( MmapRegion :: new ( size) . unwrap ( ) , addr) . unwrap ( ) ,
208+ crate :: mmap_unix:: GuestRegionMmap :: new ( MmapRegion :: new ( size) . unwrap ( ) , addr)
209+ . unwrap ( ) ,
358210 ) ) ;
359211 #[ cfg( all( unix, feature = "backend-mmap" , feature = "xen" ) ) ]
360212 regions. push ( AnyRegion :: Xen (
@@ -731,12 +583,4 @@ pub(crate) mod tests {
731583 ) ;
732584 }
733585 }
734-
735- #[ test]
736- fn test_dirty_tracking ( ) {
737- test_guest_memory_and_region ( || {
738- crate :: GuestMemoryMmap :: < AtomicBitmap > :: from_ranges ( & [ ( GuestAddress ( 0 ) , 0x1_0000 ) ] )
739- . unwrap ( )
740- } ) ;
741- }
742586}
0 commit comments