summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorChirantan Ekbote <chirantan@chromium.org>2020-04-24 19:37:04 +0900
committerCommit Bot <commit-bot@chromium.org>2020-04-29 07:36:36 +0000
commit2d9dde9ee7ac78a9831d1e019e40107b5691f895 (patch)
tree6b055f267adfebdf828cbe680dce0e06c870cdfb /devices
parent887289e5d455d2cd026a2b178002ed009ea8bdd4 (diff)
downloadcrosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.tar
crosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.tar.gz
crosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.tar.bz2
crosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.tar.lz
crosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.tar.xz
crosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.tar.zst
crosvm-2d9dde9ee7ac78a9831d1e019e40107b5691f895.zip
Stop tracking sub-mappings in MemoryMappingArena
The kernel already takes care of tracking all our memory mappings.
Doing it again ourselves doesn't provide any benefit and also adds
additional restrictions (like not being able to overlap with existing
mappings or partially remove mappings).  Additionally, the
`MemoryMappingArena` will already unmap the entire memory mapped region
so there is no need to individually unmap the sub-mappings.

The kernel's mmap api doesn't have these restrictions and as far as I
can tell there are no safety concerns with allowing this behavior so
just stop tracking the sub-mappings.

Safe use of MAP_FIXED only requires that the address is part of a
previously mmaped region so allow any MemoryMapping to be converted into
a MemoryMappedArena.

BUG=b:147341783
TEST=unit tests

Change-Id: Iaf944a971b8ba9333802aab73c1d184fe388af89
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2162542
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/virtio/pmem.rs11
1 files changed, 10 insertions, 1 deletions
diff --git a/devices/src/virtio/pmem.rs b/devices/src/virtio/pmem.rs
index 499e110..cbeecc3 100644
--- a/devices/src/virtio/pmem.rs
+++ b/devices/src/virtio/pmem.rs
@@ -8,8 +8,8 @@ use std::io;
 use std::os::unix::io::{AsRawFd, RawFd};
 use std::thread;
 
-use sys_util::Result as SysResult;
 use sys_util::{error, EventFd, GuestAddress, GuestMemory, PollContext, PollToken};
+use sys_util::{Error as SysError, Result as SysResult};
 
 use data_model::{DataInit, Le32, Le64};
 
@@ -89,6 +89,7 @@ struct Worker {
     memory: GuestMemory,
     pmem_device_socket: VmMsyncRequestSocket,
     mapping_arena_slot: u32,
+    mapping_size: usize,
 }
 
 impl Worker {
@@ -98,6 +99,7 @@ impl Worker {
                 let request = VmMsyncRequest::MsyncArena {
                     slot: self.mapping_arena_slot,
                     offset: 0, // The pmem backing file is always at offset 0 in the arena.
+                    size: self.mapping_size,
                 };
 
                 if let Err(e) = self.pmem_device_socket.send(&request) {
@@ -235,6 +237,10 @@ impl Pmem {
         mapping_size: u64,
         pmem_device_socket: Option<VmMsyncRequestSocket>,
     ) -> SysResult<Pmem> {
+        if mapping_size > usize::max_value() as u64 {
+            return Err(SysError::new(libc::EOVERFLOW));
+        }
+
         Ok(Pmem {
             kill_event: None,
             worker_thread: None,
@@ -308,6 +314,8 @@ impl VirtioDevice for Pmem {
         let queue_event = queue_events.remove(0);
 
         let mapping_arena_slot = self.mapping_arena_slot;
+        // We checked that this fits in a usize in `Pmem::new`.
+        let mapping_size = self.mapping_size as usize;
 
         if let Some(pmem_device_socket) = self.pmem_device_socket.take() {
             let (self_kill_event, kill_event) =
@@ -329,6 +337,7 @@ impl VirtioDevice for Pmem {
                         queue,
                         pmem_device_socket,
                         mapping_arena_slot,
+                        mapping_size,
                     };
                     worker.run(queue_event, kill_event);
                 });