diff options
Diffstat (limited to 'sys_util/src/guest_memory.rs')
-rw-r--r-- | sys_util/src/guest_memory.rs | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/sys_util/src/guest_memory.rs b/sys_util/src/guest_memory.rs index 1246a9c..d40b5be 100644 --- a/sys_util/src/guest_memory.rs +++ b/sys_util/src/guest_memory.rs @@ -224,13 +224,20 @@ impl GuestMemory { /// Returns true if the given address is within the memory range available to the guest. pub fn address_in_range(&self, addr: GuestAddress) -> bool { - addr < self.end_addr() + self.regions + .iter() + .any(|region| region.guest_base <= addr && addr < region_end(region)) } /// Returns the address plus the offset if it is in range. pub fn checked_offset(&self, addr: GuestAddress, offset: u64) -> Option<GuestAddress> { - addr.checked_add(offset) - .and_then(|a| if a < self.end_addr() { Some(a) } else { None }) + addr.checked_add(offset).and_then(|a| { + if self.address_in_range(a) { + Some(a) + } else { + None + } + }) } /// Returns the size of the memory region in bytes. @@ -599,6 +606,20 @@ mod tests { } #[test] + fn region_hole() { + let start_addr1 = GuestAddress(0x0); + let start_addr2 = GuestAddress(0x4000); + let gm = GuestMemory::new(&vec![(start_addr1, 0x2000), (start_addr2, 0x2000)]).unwrap(); + assert_eq!(gm.address_in_range(GuestAddress(0x1000)), true); + assert_eq!(gm.address_in_range(GuestAddress(0x3000)), false); + assert_eq!(gm.address_in_range(GuestAddress(0x5000)), true); + assert_eq!(gm.address_in_range(GuestAddress(0x6000)), false); + assert!(gm.checked_offset(GuestAddress(0x1000), 0x1000).is_none()); + assert!(gm.checked_offset(GuestAddress(0x5000), 0x800).is_some()); + assert!(gm.checked_offset(GuestAddress(0x5000), 0x1000).is_none()); + } + + #[test] fn test_read_u64() { let start_addr1 = GuestAddress(0x0); let start_addr2 = GuestAddress(0x1000); |