Skip to content

Commit e9b8ec6

Browse files
committed
feat: add find_arc_region for GuestMemoryMmap
This allows GuestMemoryMmap to expose more operation capabilities for GuestRegionMmap. This will make it possible to optimize searches for regions. Signed-off-by: ihciah <[email protected]>
1 parent b611121 commit e9b8ec6

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Upcoming version
44

55
### Added
6+
- [[#293](https://github.com/rust-vmm/vm-memory/pull/293)] Implement `find_arc_region` and `IntoIterator` for `GuestMemoryMmap`.
67
### Changed
78
- [[#275](https://github.com/rust-vmm/vm-memory/pull/275)] Fail builds on non 64-bit platforms.
89
### Fixed

src/mmap.rs

+42-9
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,26 @@ impl<B: Bitmap> GuestMemoryMmap<B> {
611611

612612
Err(Error::InvalidGuestRegion)
613613
}
614+
615+
/// Find the region containing the specified address.
616+
pub fn find_arc_region(&self, addr: GuestAddress) -> Option<Arc<GuestRegionMmap<B>>> {
617+
let index = match self.regions.binary_search_by_key(&addr, |x| x.start_addr()) {
618+
Ok(x) => Some(x),
619+
// Within the closest region with starting address < addr
620+
Err(x) if (x > 0 && addr <= self.regions[x - 1].last_addr()) => Some(x - 1),
621+
_ => None,
622+
};
623+
index.map(|x| self.regions[x].clone())
624+
}
625+
}
626+
627+
impl<B> IntoIterator for GuestMemoryMmap<B> {
628+
type Item = Arc<GuestRegionMmap<B>>;
629+
type IntoIter = std::vec::IntoIter<Self::Item>;
630+
631+
fn into_iter(self) -> Self::IntoIter {
632+
self.regions.into_iter()
633+
}
614634
}
615635

616636
/// An iterator over the elements of `GuestMemoryMmap`.
@@ -704,6 +724,7 @@ mod tests {
704724
assert_eq!(region_size, &mmap.mapping.size());
705725

706726
assert!(guest_mem.find_region(*region_addr).is_some());
727+
assert!(guest_mem.find_arc_region(*region_addr).is_some());
707728
}
708729
}
709730

@@ -951,7 +972,7 @@ mod tests {
951972
])
952973
.unwrap();
953974

954-
let guest_mem_list = vec![guest_mem, guest_mem_backed_by_file];
975+
let guest_mem_list = [guest_mem, guest_mem_backed_by_file];
955976
for guest_mem in guest_mem_list.iter() {
956977
assert!(guest_mem.address_in_range(GuestAddress(0x200)));
957978
assert!(!guest_mem.address_in_range(GuestAddress(0x600)));
@@ -977,7 +998,7 @@ mod tests {
977998
])
978999
.unwrap();
9791000

980-
let guest_mem_list = vec![guest_mem, guest_mem_backed_by_file];
1001+
let guest_mem_list = [guest_mem, guest_mem_backed_by_file];
9811002
for guest_mem in guest_mem_list.iter() {
9821003
assert_eq!(
9831004
guest_mem.check_address(GuestAddress(0x200)),
@@ -1009,7 +1030,7 @@ mod tests {
10091030
])
10101031
.unwrap();
10111032

1012-
let guest_mem_list = vec![guest_mem, guest_mem_backed_by_file];
1033+
let guest_mem_list = [guest_mem, guest_mem_backed_by_file];
10131034
for guest_mem in guest_mem_list.iter() {
10141035
assert!(guest_mem.to_region_addr(GuestAddress(0x600)).is_none());
10151036
let (r0, addr0) = guest_mem.to_region_addr(GuestAddress(0x800)).unwrap();
@@ -1037,7 +1058,7 @@ mod tests {
10371058
])
10381059
.unwrap();
10391060

1040-
let guest_mem_list = vec![guest_mem, guest_mem_backed_by_file];
1061+
let guest_mem_list = [guest_mem, guest_mem_backed_by_file];
10411062
for guest_mem in guest_mem_list.iter() {
10421063
assert!(guest_mem.get_host_address(GuestAddress(0x600)).is_err());
10431064
let ptr0 = guest_mem.get_host_address(GuestAddress(0x800)).unwrap();
@@ -1046,6 +1067,13 @@ mod tests {
10461067
ptr0,
10471068
guest_mem.find_region(GuestAddress(0x800)).unwrap().as_ptr()
10481069
);
1070+
assert_eq!(
1071+
ptr0,
1072+
guest_mem
1073+
.find_arc_region(GuestAddress(0x800))
1074+
.unwrap()
1075+
.as_ptr()
1076+
);
10491077
assert_eq!(unsafe { ptr0.offset(0x200) }, ptr1);
10501078
}
10511079
}
@@ -1064,7 +1092,7 @@ mod tests {
10641092
)])
10651093
.unwrap();
10661094

1067-
let guest_mem_list = vec![guest_mem, guest_mem_backed_by_file];
1095+
let guest_mem_list = [guest_mem, guest_mem_backed_by_file];
10681096
for guest_mem in guest_mem_list.iter() {
10691097
let sample_buf = &[1, 2, 3, 4, 5];
10701098

@@ -1102,7 +1130,7 @@ mod tests {
11021130
])
11031131
.unwrap();
11041132

1105-
let gm_list = vec![gm, gm_backed_by_file];
1133+
let gm_list = [gm, gm_backed_by_file];
11061134
for gm in gm_list.iter() {
11071135
let val1: u64 = 0xaa55_aa55_aa55_aa55;
11081136
let val2: u64 = 0x55aa_55aa_55aa_55aa;
@@ -1142,7 +1170,7 @@ mod tests {
11421170
)])
11431171
.unwrap();
11441172

1145-
let gm_list = vec![gm, gm_backed_by_file];
1173+
let gm_list = [gm, gm_backed_by_file];
11461174
for gm in gm_list.iter() {
11471175
let sample_buf = &[1, 2, 3, 4, 5];
11481176

@@ -1173,7 +1201,7 @@ mod tests {
11731201
)])
11741202
.unwrap();
11751203

1176-
let gm_list = vec![gm, gm_backed_by_file];
1204+
let gm_list = [gm, gm_backed_by_file];
11771205
for gm in gm_list.iter() {
11781206
let addr = GuestAddress(0x1010);
11791207
let mut file = if cfg!(unix) {
@@ -1257,6 +1285,11 @@ mod tests {
12571285

12581286
assert_eq!(gm.regions[0].guest_base, regions[0].0);
12591287
assert_eq!(gm.regions[1].guest_base, regions[1].0);
1288+
GuestMemoryMmap::from_ranges(&regions)
1289+
.unwrap()
1290+
.into_iter()
1291+
.zip(iterated_regions)
1292+
.all(|(x, y)| x.guest_base == y.0);
12601293
}
12611294

12621295
#[test]
@@ -1276,7 +1309,7 @@ mod tests {
12761309
])
12771310
.unwrap();
12781311

1279-
let gm_list = vec![gm, gm_backed_by_file];
1312+
let gm_list = [gm, gm_backed_by_file];
12801313
for gm in gm_list.iter() {
12811314
let sample_buf = &[1, 2, 3, 4, 5];
12821315
assert_eq!(gm.write(sample_buf, GuestAddress(0xffc)).unwrap(), 5);

0 commit comments

Comments
 (0)