8
8
// Use of this source code is governed by a BSD-style license that can be
9
9
// found in the THIRD-PARTY file.
10
10
11
- //! Traits to track and access guest's physical memory.
11
+ //! Traits to track and access the physical memory of the guest .
12
12
//!
13
13
//! To make the abstraction as generic as possible, all the core traits declared here only define
14
14
//! methods to access guest's memory, and never define methods to manage (create, delete, insert,
15
- //! remove etc) guest's memory. By this way, the guest memory consumers (virtio device drivers,
15
+ //! remove etc) guest's memory. This way, the guest memory consumers (virtio device drivers,
16
16
//! vhost drivers and boot loaders etc) may be decoupled from the guest memory provider (typically
17
17
//! a hypervisor).
18
18
//!
@@ -48,7 +48,7 @@ pub enum Error {
48
48
InvalidGuestAddress ( GuestAddress ) ,
49
49
/// Couldn't read/write from the given source.
50
50
IOError ( io:: Error ) ,
51
- /// Incomplete read or write
51
+ /// Incomplete read or write.
52
52
PartialBuffer { expected : usize , completed : usize } ,
53
53
/// Requested backend address is out of range.
54
54
InvalidBackendAddress ,
@@ -75,7 +75,7 @@ impl From<volatile_memory::Error> for Error {
75
75
}
76
76
}
77
77
78
- /// Result of guest memory operations
78
+ /// Result of guest memory operations.
79
79
pub type Result < T > = std:: result:: Result < T , Error > ;
80
80
81
81
impl std:: error:: Error for Error { }
@@ -104,9 +104,9 @@ impl Display for Error {
104
104
105
105
/// Represents a guest physical address (GPA).
106
106
///
107
- /// Notes:
108
- /// - On ARM64, a 32-bit hypervisor may be used to support a 64-bit guest. For simplicity,
109
- /// u64 is used to store the the raw value no matter if the guest a 32-bit or 64-bit virtual
107
+ /// # Notes:
108
+ /// On ARM64, a 32-bit hypervisor may be used to support a 64-bit guest. For simplicity,
109
+ /// ` u64` is used to store the the raw value no matter if the guest a 32-bit or 64-bit virtual
110
110
/// machine.
111
111
#[ derive( Clone , Copy , Debug , Eq , PartialEq , Ord , PartialOrd ) ]
112
112
pub struct GuestAddress ( pub u64 ) ;
@@ -157,20 +157,19 @@ impl FileOffset {
157
157
/// Represents a continuous region of guest physical memory.
158
158
#[ allow( clippy:: len_without_is_empty) ]
159
159
pub trait GuestMemoryRegion : Bytes < MemoryRegionAddress , E = Error > {
160
- /// Get the size of the region.
160
+ /// Returns the size of the region.
161
161
fn len ( & self ) -> GuestUsize ;
162
162
163
- /// Get minimum (inclusive) address managed by the region.
163
+ /// Returns the minimum (inclusive) address managed by the region.
164
164
fn start_addr ( & self ) -> GuestAddress ;
165
165
166
- /// Get maximum (inclusive) address managed by the region.
166
+ /// Returns the maximum (inclusive) address managed by the region.
167
167
fn last_addr ( & self ) -> GuestAddress {
168
168
// unchecked_add is safe as the region bounds were checked when it was created.
169
169
self . start_addr ( ) . unchecked_add ( self . len ( ) - 1 )
170
170
}
171
171
172
- /// Returns the given address if it is within the memory range accessible
173
- /// through this region.
172
+ /// Returns the given address if it is within this region.
174
173
fn check_address ( & self , addr : MemoryRegionAddress ) -> Option < MemoryRegionAddress > {
175
174
if self . address_in_range ( addr) {
176
175
Some ( addr)
@@ -179,13 +178,12 @@ pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = Error> {
179
178
}
180
179
}
181
180
182
- /// Returns true if the given address is within the memory range accessible
183
- /// through this region.
181
+ /// Returns `true` if the given address is within this region.
184
182
fn address_in_range ( & self , addr : MemoryRegionAddress ) -> bool {
185
183
addr. raw_value ( ) < self . len ( )
186
184
}
187
185
188
- /// Returns the address plus the offset if it is in range .
186
+ /// Returns the address plus the offset if it is in this region .
189
187
fn checked_offset (
190
188
& self ,
191
189
base : MemoryRegionAddress ,
@@ -195,40 +193,49 @@ pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = Error> {
195
193
. and_then ( |addr| self . check_address ( addr) )
196
194
}
197
195
198
- /// Convert an absolute address into an address space (GuestMemory)
199
- /// to a relative address within this region, or return an error if
200
- /// it is out of bounds.
196
+ /// Tries to convert an absolute address to a relative address within this region.
197
+ ///
198
+ /// Returns `None` if `addr` is out of the bounds of this region .
201
199
fn to_region_addr ( & self , addr : GuestAddress ) -> Option < MemoryRegionAddress > {
202
200
addr. checked_offset_from ( self . start_addr ( ) )
203
201
. and_then ( |offset| self . check_address ( MemoryRegionAddress ( offset) ) )
204
202
}
205
203
206
- /// Get the host virtual address corresponding to the region address.
204
+ /// Returns the host virtual address corresponding to the region address.
207
205
///
208
- /// Some GuestMemory backends , like the GuestMemoryMmap backend, have the capability to mmap
209
- /// guest address range into host virtual address space for direct access, so the corresponding
210
- /// host virtual address may be passed to other subsystems.
206
+ /// Some [` GuestMemory`](trait.GuestMemory.html) implementations , like ` GuestMemoryMmap`,
207
+ /// have the capability to mmap guest address range into host virtual address space for
208
+ /// direct access, so the corresponding host virtual address may be passed to other subsystems.
211
209
///
212
- /// Note: the underline guest memory is not protected from memory aliasing, which breaks the
213
- /// rust memory safety model. It's the caller's responsibility to ensure that there's no
214
- /// concurrent accesses to the underline guest memory.
210
+ /// # Note
211
+ /// The underlying guest memory is not protected from memory aliasing, which breaks the
212
+ /// Rust memory safety model. It's the caller's responsibility to ensure that there's no
213
+ /// concurrent accesses to the underlying guest memory.
215
214
fn get_host_address ( & self , _addr : MemoryRegionAddress ) -> Result < * mut u8 > {
216
215
Err ( Error :: HostAddressNotAvailable )
217
216
}
218
217
219
218
/// Returns information regarding the file and offset backing this memory region.
220
219
fn file_offset ( & self ) -> Option < & FileOffset > ;
221
220
222
- /// Return a slice corresponding to the data in the region; unsafe because of
223
- /// possible aliasing. Return None if the region does not support slice-based
224
- /// access.
221
+ /// Returns a slice corresponding to the data in the region.
222
+ ///
223
+ /// Returns `None` if the region does not support slice-based access.
224
+ ///
225
+ /// # Safety
226
+ ///
227
+ /// Unsafe because of possible aliasing.
225
228
unsafe fn as_slice ( & self ) -> Option < & [ u8 ] > {
226
229
None
227
230
}
228
231
229
- /// Return a mutable slice corresponding to the data in the region; unsafe because of
230
- /// possible aliasing. Return None if the region does not support slice-based
231
- /// access.
232
+ /// Returns a mutable slice corresponding to the data in the region.
233
+ ///
234
+ /// Returns `None` if the region does not support slice-based access.
235
+ ///
236
+ /// # Safety
237
+ ///
238
+ /// Unsafe because of possible aliasing.
232
239
unsafe fn as_mut_slice ( & self ) -> Option < & mut [ u8 ] > {
233
240
None
234
241
}
@@ -241,25 +248,27 @@ pub trait GuestMemoryRegion: Bytes<MemoryRegionAddress, E = Error> {
241
248
/// - map a request address to a GuestMemoryRegion object and relay the request to it.
242
249
/// - handle cases where an access request spanning two or more GuestMemoryRegion objects.
243
250
///
244
- /// Note: all regions in a GuestMemory object must not intersect with each other .
251
+ /// Note: the regions inside a [` GuestMemory`](trait.GuestMemory.html) object must not overlap .
245
252
pub trait GuestMemory {
246
253
/// Type of objects hosted by the address space.
247
254
type R : GuestMemoryRegion ;
248
255
249
256
/// Returns the number of regions in the collection.
250
257
fn num_regions ( & self ) -> usize ;
251
258
252
- /// Return the region containing the specified address or None.
259
+ /// Returns the region containing the specified address or ` None` .
253
260
fn find_region ( & self , addr : GuestAddress ) -> Option < & Self :: R > ;
254
261
255
262
/// Perform the specified action on each region.
256
- /// It only walks children of current region and do not step into sub regions.
263
+ ///
264
+ /// It only walks children of current region and does not step into sub regions.
257
265
fn with_regions < F , E > ( & self , cb : F ) -> std:: result:: Result < ( ) , E >
258
266
where
259
267
F : Fn ( usize , & Self :: R ) -> std:: result:: Result < ( ) , E > ;
260
268
261
269
/// Perform the specified action on each region mutably.
262
- /// It only walks children of current region and do not step into sub regions.
270
+ ///
271
+ /// It only walks children of current region and does not step into sub regions.
263
272
fn with_regions_mut < F , E > ( & self , cb : F ) -> std:: result:: Result < ( ) , E >
264
273
where
265
274
F : FnMut ( usize , & Self :: R ) -> std:: result:: Result < ( ) , E > ;
@@ -306,7 +315,8 @@ pub trait GuestMemory {
306
315
F : Fn ( ( usize , & Self :: R ) ) -> T ,
307
316
G : Fn ( T , T ) -> T ;
308
317
309
- /// Get maximum (inclusive) address managed by the region.
318
+ /// Returns the maximum (inclusive) address managed by the
319
+ /// [`GuestMemory`](trait.GuestMemory.html).
310
320
///
311
321
/// # Examples
312
322
///
@@ -333,38 +343,39 @@ pub trait GuestMemory {
333
343
)
334
344
}
335
345
336
- /// Convert an absolute address into an address space (GuestMemory)
337
- /// to a relative address within this region, or return None if
338
- /// it is out of bounds .
346
+ /// Tries to convert an absolute address to a relative address within the corresponding region.
347
+ ///
348
+ /// Returns `None` if `addr` isn't present within the memory of the guest .
339
349
fn to_region_addr ( & self , addr : GuestAddress ) -> Option < ( & Self :: R , MemoryRegionAddress ) > {
340
350
self . find_region ( addr)
341
351
. map ( |r| ( r, r. to_region_addr ( addr) . unwrap ( ) ) )
342
352
}
343
353
344
- /// Returns true if the given address is within the memory range available to the guest.
354
+ /// Returns ` true` if the given address is present within the memory of the guest.
345
355
fn address_in_range ( & self , addr : GuestAddress ) -> bool {
346
356
self . find_region ( addr) . is_some ( )
347
357
}
348
358
349
- /// Returns the given address if it is within the memory range available to the guest.
359
+ /// Returns the given address if it is present within the memory of the guest.
350
360
fn check_address ( & self , addr : GuestAddress ) -> Option < GuestAddress > {
351
361
self . find_region ( addr) . map ( |_| addr)
352
362
}
353
363
354
- /// Returns the address plus the offset if it is in range .
364
+ /// Returns the address plus the offset if it is present within the memory of the guest .
355
365
fn checked_offset ( & self , base : GuestAddress , offset : usize ) -> Option < GuestAddress > {
356
366
base. checked_add ( offset as u64 )
357
367
. and_then ( |addr| self . check_address ( addr) )
358
368
}
359
369
360
- /// Invoke callback `f` to handle data in the address range [addr, addr + count).
370
+ /// Invokes callback `f` to handle data in the address range ` [addr, addr + count)` .
361
371
///
362
- /// The address range [addr, addr + count) may span more than one GuestMemoryRegion objects, or
363
- /// even has holes within it. So try_access() invokes the callback 'f' for each GuestMemoryRegion
364
- /// object involved and returns:
365
- /// - error code returned by the callback 'f'
366
- /// - size of data already handled when encountering the first hole
367
- /// - size of data already handled when the whole range has been handled
372
+ /// /// The address range `[addr, addr + count)` may span more than one
373
+ /// [`GuestMemoryRegion`](trait.GuestMemoryRegion.html) objects, or even have holes in it.
374
+ /// So [`try_access()`](trait.GuestMemory.html#method.try_access) invokes the callback 'f'
375
+ /// for each [`GuestMemoryRegion`](trait.GuestMemoryRegion.html) object involved and returns:
376
+ /// - the error code returned by the callback 'f'
377
+ /// - the size of the already handled data when encountering the first hole
378
+ /// - the size of the already handled data when the whole range has been handled
368
379
fn try_access < F > ( & self , count : usize , addr : GuestAddress , mut f : F ) -> Result < usize >
369
380
where
370
381
F : FnMut ( usize , usize , MemoryRegionAddress , & Self :: R ) -> Result < usize > ,
@@ -403,13 +414,15 @@ pub trait GuestMemory {
403
414
404
415
/// Get the host virtual address corresponding to the guest address.
405
416
///
406
- /// Some GuestMemory backends, like the GuestMemoryMmap backend, have the capability to mmap
407
- /// guest address range into host virtual address space for direct access, so the corresponding
408
- /// host virtual address may be passed to other subsystems.
417
+ /// Some [`GuestMemory`](trait.GuestMemory.html) implementations, like `GuestMemoryMmap`,
418
+ /// have the capability to mmap the guest address range into virtual address space of the host
419
+ /// for direct access, so the corresponding host virtual address may be passed to other
420
+ /// subsystems.
409
421
///
410
- /// Note: the underline guest memory is not protected from memory aliasing, which breaks the
411
- /// rust memory safety model. It's the caller's responsibility to ensure that there's no
412
- /// concurrent accesses to the underline guest memory.
422
+ /// # Note
423
+ /// The underlying guest memory is not protected from memory aliasing, which breaks the
424
+ /// Rust memory safety model. It's the caller's responsibility to ensure that there's no
425
+ /// concurrent accesses to the underlying guest memory.
413
426
///
414
427
/// # Arguments
415
428
/// * `guest_addr` - Guest address to convert.
0 commit comments