summary refs log tree commit diff
path: root/sys_util
diff options
context:
space:
mode:
authorXiong Zhang <xiong.y.zhang@intel.corp-partner.google.com>2019-10-31 13:16:02 +0800
committerCommit Bot <commit-bot@chromium.org>2019-11-11 09:46:43 +0000
commitd9a54c222ea0e83fc4f237f792b374b2841074c5 (patch)
tree5939006b31f80e045be2d6c05982d7c216c9426e /sys_util
parent3f8599aea9d06af32e3368d45e19edc2666453a8 (diff)
downloadcrosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.tar
crosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.tar.gz
crosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.tar.bz2
crosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.tar.lz
crosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.tar.xz
crosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.tar.zst
crosvm-d9a54c222ea0e83fc4f237f792b374b2841074c5.zip
kvm: Allow low mmio added into kvm
gpa > guest_mem.end_addr() is used to avoid gpa fall into guest ram,
but low mmio maybe below guest_mem.end_addr(), this condition is false,
then low mmio couldn't be added. Since low mmio could be added into kvm
also, this condition is wrong.

This patch iterate all the guest memory reginos, and check whether it
overlap with any of them.

BUG=chromium:992270
TEST=bulld_test

Change-Id: I9560db43f9836f85d0ff927e7eeb92447774568c
Signed-off-by: Xiong Zhang <xiong.y.zhang@intel.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1895235
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'sys_util')
-rw-r--r--sys_util/src/guest_memory.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/sys_util/src/guest_memory.rs b/sys_util/src/guest_memory.rs
index d40b5be..162960f 100644
--- a/sys_util/src/guest_memory.rs
+++ b/sys_util/src/guest_memory.rs
@@ -229,6 +229,14 @@ impl GuestMemory {
             .any(|region| region.guest_base <= addr && addr < region_end(region))
     }
 
+    /// Returns true if the given range (start, end) is overlap with the memory range
+    /// available to the guest.
+    pub fn range_overlap(&self, start: GuestAddress, end: GuestAddress) -> bool {
+        self.regions
+            .iter()
+            .any(|region| region.guest_base < end && start < 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| {
@@ -614,6 +622,19 @@ mod tests {
         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_eq!(gm.address_in_range(GuestAddress(0x6000)), false);
+        assert_eq!(
+            gm.range_overlap(GuestAddress(0x1000), GuestAddress(0x3000)),
+            true
+        );
+        assert_eq!(
+            gm.range_overlap(GuestAddress(0x3000), GuestAddress(0x4000)),
+            false
+        );
+        assert_eq!(
+            gm.range_overlap(GuestAddress(0x3000), GuestAddress(0x7000)),
+            true
+        );
         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());