Skip to content

Commit 61e8321

Browse files
committed
feat(memory): added FileOffset to the MmapRegions
Now when memory is backed by the file we store `FileOffset` inside each region. This information will be used to set up vhost-user shared memory. Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
1 parent 1b57de0 commit 61e8321

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

src/vmm/src/vstate/memory.rs

+23-18
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ where
8181

8282
/// Creates a GuestMemoryMmap from raw regions with guard pages.
8383
fn from_raw_regions_file(
84-
regions: &[(FileOffset, GuestAddress, usize)],
84+
regions: Vec<(FileOffset, GuestAddress, usize)>,
8585
track_dirty_pages: bool,
8686
shared: bool,
8787
) -> Result<Self, MemoryError>;
@@ -150,7 +150,7 @@ impl GuestMemoryExtension for GuestMemoryMmap {
150150
})
151151
.collect::<Result<Vec<_>, MemoryError>>()?;
152152

153-
Self::from_raw_regions_file(&regions, track_dirty_pages, true)
153+
Self::from_raw_regions_file(regions, track_dirty_pages, true)
154154
}
155155

156156
/// Creates a GuestMemoryMmap with `size` in MiB and guard pages backed by anonymous memory.
@@ -210,7 +210,7 @@ impl GuestMemoryExtension for GuestMemoryMmap {
210210

211211
/// Creates a GuestMemoryMmap from raw regions with guard pages backed by file.
212212
fn from_raw_regions_file(
213-
regions: &[(FileOffset, GuestAddress, usize)],
213+
regions: Vec<(FileOffset, GuestAddress, usize)>,
214214
track_dirty_pages: bool,
215215
shared: bool,
216216
) -> Result<Self, MemoryError> {
@@ -221,16 +221,16 @@ impl GuestMemoryExtension for GuestMemoryMmap {
221221
libc::MAP_NORESERVE | libc::MAP_PRIVATE
222222
};
223223
let regions = regions
224-
.iter()
224+
.into_iter()
225225
.map(|(file_offset, guest_address, region_size)| {
226226
let region = build_guarded_region(
227227
Some(file_offset),
228-
*region_size,
228+
region_size,
229229
prot,
230230
flags,
231231
track_dirty_pages,
232232
)?;
233-
GuestRegionMmap::new(region, *guest_address).map_err(MemoryError::VmMemoryError)
233+
GuestRegionMmap::new(region, guest_address).map_err(MemoryError::VmMemoryError)
234234
})
235235
.collect::<Result<Vec<_>, MemoryError>>()?;
236236

@@ -258,7 +258,7 @@ impl GuestMemoryExtension for GuestMemoryMmap {
258258
.collect::<Result<Vec<_>, std::io::Error>>()
259259
.map_err(MemoryError::FileError)?;
260260

261-
Self::from_raw_regions_file(&regions, track_dirty_pages, false)
261+
Self::from_raw_regions_file(regions, track_dirty_pages, false)
262262
}
263263
None => {
264264
let regions = state
@@ -407,7 +407,7 @@ pub fn create_memfd(size: usize) -> Result<memfd::Memfd, MemoryError> {
407407
/// acts as a safety net for accessing out-of-bounds addresses that are not allocated for the
408408
/// guest's memory.
409409
fn build_guarded_region(
410-
file_offset: Option<&FileOffset>,
410+
file_offset: Option<FileOffset>,
411411
size: usize,
412412
prot: i32,
413413
flags: i32,
@@ -438,7 +438,7 @@ fn build_guarded_region(
438438
}
439439

440440
let (fd, offset) = match file_offset {
441-
Some(file_offset) => {
441+
Some(ref file_offset) => {
442442
check_file_offset(file_offset, size).map_err(MemoryError::MmapRegionError)?;
443443
(file_offset.file().as_raw_fd(), file_offset.start())
444444
}
@@ -473,14 +473,19 @@ fn build_guarded_region(
473473
};
474474

475475
// SAFETY: Safe because the parameters are valid.
476-
unsafe {
476+
let builder = unsafe {
477477
MmapRegionBuilder::new_with_bitmap(size, bitmap)
478478
.with_raw_mmap_pointer(region_addr.cast::<u8>())
479479
.with_mmap_prot(prot)
480480
.with_mmap_flags(flags)
481-
.build()
482-
.map_err(MemoryError::MmapRegionError)
481+
};
482+
483+
match file_offset {
484+
Some(offset) => builder.with_file_offset(offset),
485+
None => builder,
483486
}
487+
.build()
488+
.map_err(MemoryError::MmapRegionError)
484489
}
485490

486491
#[cfg(test)]
@@ -545,11 +550,11 @@ mod tests {
545550
let file_offset = FileOffset::new(file, 0);
546551

547552
let region =
548-
build_guarded_region(Some(&file_offset), region_size, prot, flags, false).unwrap();
553+
build_guarded_region(Some(file_offset), region_size, prot, flags, false).unwrap();
549554

550555
// Verify that the region was built correctly
551556
assert_eq!(region.size(), region_size);
552-
assert!(region.file_offset().is_none());
557+
assert!(region.file_offset().is_some());
553558
assert_eq!(region.prot(), prot);
554559
assert_eq!(region.flags(), flags);
555560

@@ -677,10 +682,10 @@ mod tests {
677682
// Test that all regions are guarded.
678683
{
679684
let guest_memory =
680-
GuestMemoryMmap::from_raw_regions_file(&regions, false, false).unwrap();
685+
GuestMemoryMmap::from_raw_regions_file(regions.clone(), false, false).unwrap();
681686
guest_memory.iter().for_each(|region| {
682687
assert_eq!(region.size(), region_size);
683-
assert!(region.file_offset().is_none());
688+
assert!(region.file_offset().is_some());
684689
assert!(region.bitmap().is_none());
685690
validate_guard_region(region);
686691
});
@@ -689,7 +694,7 @@ mod tests {
689694
// Check dirty page tracking is off.
690695
{
691696
let guest_memory =
692-
GuestMemoryMmap::from_raw_regions_file(&regions, false, false).unwrap();
697+
GuestMemoryMmap::from_raw_regions_file(regions.clone(), false, false).unwrap();
693698
guest_memory.iter().for_each(|region| {
694699
assert!(region.bitmap().is_none());
695700
});
@@ -698,7 +703,7 @@ mod tests {
698703
// Check dirty page tracking is on.
699704
{
700705
let guest_memory =
701-
GuestMemoryMmap::from_raw_regions_file(&regions, true, false).unwrap();
706+
GuestMemoryMmap::from_raw_regions_file(regions, true, false).unwrap();
702707
guest_memory.iter().for_each(|region| {
703708
assert!(region.bitmap().is_some());
704709
});

0 commit comments

Comments
 (0)