12
12
//!
13
13
//! This implementation is mmap-ing the memory of the guest into the current process.
14
14
15
- use std:: borrow:: Borrow ;
16
15
#[ cfg( unix) ]
17
16
use std:: io:: { Seek , SeekFrom } ;
18
- use std:: ops:: Deref ;
19
17
use std:: result;
20
18
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 ;
27
21
28
22
#[ cfg( all( not( feature = "xen" ) , unix) ) ]
29
23
pub use crate :: mmap_unix:: { Error as MmapRegionError , MmapRegion , MmapRegionBuilder } ;
30
24
31
25
#[ cfg( all( feature = "xen" , unix) ) ]
32
26
pub use crate :: mmap_xen:: { Error as MmapRegionError , MmapRange , MmapRegion , MmapXenFlags } ;
33
27
34
- #[ cfg( windows) ]
35
- pub use crate :: mmap_windows:: MmapRegion ;
36
- #[ cfg( windows) ]
37
- pub use std:: io:: Error as MmapRegionError ;
38
-
39
28
/// A `Bitmap` that can be created starting from an initial size.
40
29
pub trait NewBitmap : Bitmap + Default {
41
30
/// Create a new object based on the specified length in bytes.
@@ -91,166 +80,18 @@ pub fn check_file_offset(
91
80
Ok ( ( ) )
92
81
}
93
82
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
-
244
83
#[ cfg( test) ]
245
84
pub ( crate ) mod tests {
246
85
#![ allow( clippy:: undocumented_unsafe_blocks) ]
247
86
extern crate vmm_sys_util;
248
87
249
88
use super :: * ;
250
89
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
+ } ;
254
95
255
96
use std:: io:: Write ;
256
97
use std:: mem;
@@ -312,9 +153,9 @@ pub(crate) mod tests {
312
153
313
154
any_backend ! {
314
155
#[ cfg( all( windows, feature = "backend-mmap" ) ) ]
315
- Windows [ GuestRegionMmap <( ) >] ,
156
+ Windows [ crate :: mmap_windows :: GuestRegionWindows <( ) >] ,
316
157
#[ cfg( all( unix, feature = "backend-mmap" , not( feature = "xen" ) ) ) ]
317
- Mmap [ GuestRegionMmap <( ) >] ,
158
+ Mmap [ crate :: mmap_unix :: GuestRegionMmap <( ) >] ,
318
159
#[ cfg( all( unix, feature = "backend-mmap" , feature = "xen" ) ) ]
319
160
Xen [ crate :: mmap_xen:: MmapRegion ]
320
161
}
@@ -326,13 +167,19 @@ pub(crate) mod tests {
326
167
let mut regions = Vec :: new ( ) ;
327
168
#[ cfg( all( windows, feature = "backend-mmap" ) ) ]
328
169
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 ( ) ,
331
175
) ) ;
332
176
#[ cfg( all( unix, feature = "backend-mmap" , not( feature = "xen" ) ) ) ]
333
177
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 ( ) ,
336
183
) ) ;
337
184
#[ cfg( all( unix, feature = "backend-mmap" , feature = "xen" ) ) ]
338
185
regions. push ( AnyRegion :: Xen (
@@ -350,11 +197,16 @@ pub(crate) mod tests {
350
197
} ;
351
198
#[ cfg( all( windows, feature = "backend-mmap" ) ) ]
352
199
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 ( ) ,
354
205
) ) ;
355
206
#[ cfg( all( unix, feature = "backend-mmap" , not( feature = "xen" ) ) ) ]
356
207
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 ( ) ,
358
210
) ) ;
359
211
#[ cfg( all( unix, feature = "backend-mmap" , feature = "xen" ) ) ]
360
212
regions. push ( AnyRegion :: Xen (
@@ -731,12 +583,4 @@ pub(crate) mod tests {
731
583
) ;
732
584
}
733
585
}
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
- }
742
586
}
0 commit comments