summary refs log tree commit diff
path: root/sys_util
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-04-10 13:44:58 +0000
committerAlyssa Ross <hi@alyssa.is>2020-04-10 13:45:14 +0000
commit8404e234c3428a682dfd5ee900936a8032243ba7 (patch)
tree458d0c9db4e145c1ace3ea7e50c3a50a45f020c3 /sys_util
parentd1ea7fc8d6b750ba75df719fb932984ab1ef5f11 (diff)
parent4ee9bffbd5722ac6602abaac6f691917add12f48 (diff)
downloadcrosvm-8404e234c3428a682dfd5ee900936a8032243ba7.tar
crosvm-8404e234c3428a682dfd5ee900936a8032243ba7.tar.gz
crosvm-8404e234c3428a682dfd5ee900936a8032243ba7.tar.bz2
crosvm-8404e234c3428a682dfd5ee900936a8032243ba7.tar.lz
crosvm-8404e234c3428a682dfd5ee900936a8032243ba7.tar.xz
crosvm-8404e234c3428a682dfd5ee900936a8032243ba7.tar.zst
crosvm-8404e234c3428a682dfd5ee900936a8032243ba7.zip
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'sys_util')
-rw-r--r--sys_util/src/guest_memory.rs10
-rw-r--r--sys_util/src/mmap.rs70
2 files changed, 56 insertions, 24 deletions
diff --git a/sys_util/src/guest_memory.rs b/sys_util/src/guest_memory.rs
index 2390b92..e8f620b 100644
--- a/sys_util/src/guest_memory.rs
+++ b/sys_util/src/guest_memory.rs
@@ -84,7 +84,7 @@ impl Display for Error {
 struct MemoryRegion {
     mapping: MemoryMapping,
     guest_base: GuestAddress,
-    memfd_offset: usize,
+    memfd_offset: u64,
 }
 
 fn region_end(region: &MemoryRegion) -> GuestAddress {
@@ -175,7 +175,7 @@ impl GuestMemory {
                 memfd_offset: offset,
             });
 
-            offset += size;
+            offset += size as u64;
         }
 
         Ok(GuestMemory {
@@ -262,7 +262,7 @@ impl GuestMemory {
     ///  * memfd_offset: usize
     pub fn with_regions<F, E>(&self, mut cb: F) -> result::Result<(), E>
     where
-        F: FnMut(usize, GuestAddress, usize, usize, usize) -> result::Result<(), E>,
+        F: FnMut(usize, GuestAddress, usize, usize, u64) -> result::Result<(), E>,
     {
         for (index, region) in self.regions.iter().enumerate() {
             cb(
@@ -584,10 +584,10 @@ impl GuestMemory {
     ///                .expect("failed to get offset");
     /// assert_eq!(offset, 0x3500);
     /// ```
-    pub fn offset_from_base(&self, guest_addr: GuestAddress) -> Result<usize> {
+    pub fn offset_from_base(&self, guest_addr: GuestAddress) -> Result<u64> {
         for region in self.regions.iter() {
             if guest_addr >= region.guest_base && guest_addr < region_end(region) {
-                return Ok(region.memfd_offset + guest_addr.offset_from(region.guest_base) as usize);
+                return Ok(region.memfd_offset + guest_addr.offset_from(region.guest_base) as u64);
             }
         }
         Err(Error::InvalidGuestAddress(guest_addr))
diff --git a/sys_util/src/mmap.rs b/sys_util/src/mmap.rs
index 18414d5..006b0a8 100644
--- a/sys_util/src/mmap.rs
+++ b/sys_util/src/mmap.rs
@@ -164,36 +164,68 @@ impl MemoryMapping {
         MemoryMapping::from_fd_offset(fd, size, 0)
     }
 
-    pub fn from_fd_offset(fd: &dyn AsRawFd, size: usize, offset: usize) -> Result<MemoryMapping> {
+    pub fn from_fd_offset(fd: &dyn AsRawFd, size: usize, offset: u64) -> Result<MemoryMapping> {
         MemoryMapping::from_fd_offset_protection(fd, size, offset, Protection::read_write())
     }
 
+    /// Maps `size` bytes starting at `offset` from the given `fd` as read/write, and requests
+    /// that the pages are pre-populated.
+    /// # Arguments
+    /// * `fd` - File descriptor to mmap from.
+    /// * `size` - Size of memory region in bytes.
+    /// * `offset` - Offset in bytes from the beginning of `fd` to start the mmap.
+    pub fn from_fd_offset_populate(
+        fd: &dyn AsRawFd,
+        size: usize,
+        offset: u64,
+    ) -> Result<MemoryMapping> {
+        MemoryMapping::from_fd_offset_flags(
+            fd,
+            size,
+            offset,
+            libc::MAP_SHARED | libc::MAP_POPULATE,
+            Protection::read_write(),
+        )
+    }
+
     /// Maps the `size` bytes starting at `offset` bytes of the given `fd` as read/write.
     ///
     /// # Arguments
     /// * `fd` - File descriptor to mmap from.
     /// * `size` - Size of memory region in bytes.
     /// * `offset` - Offset in bytes from the beginning of `fd` to start the mmap.
+    /// * `flags` - flags passed directly to mmap.
     /// * `prot` - Protection (e.g. readable/writable) of the memory region.
-    pub fn from_fd_offset_protection(
+    fn from_fd_offset_flags(
         fd: &dyn AsRawFd,
         size: usize,
-        offset: usize,
+        offset: u64,
+        flags: c_int,
         prot: Protection,
     ) -> Result<MemoryMapping> {
-        // This is safe because we are creating an anonymous mapping in a place not already used by
-        // any other area in this process.
         unsafe {
-            MemoryMapping::try_mmap(
-                None,
-                size,
-                prot.into(),
-                libc::MAP_SHARED,
-                Some((fd, offset)),
-            )
+            // This is safe because we are creating an anonymous mapping in a place not already used
+            // by any other area in this process.
+            MemoryMapping::try_mmap(None, size, prot.into(), flags, Some((fd, offset)))
         }
     }
 
+    /// Maps the `size` bytes starting at `offset` bytes of the given `fd` as read/write.
+    ///
+    /// # Arguments
+    /// * `fd` - File descriptor to mmap from.
+    /// * `size` - Size of memory region in bytes.
+    /// * `offset` - Offset in bytes from the beginning of `fd` to start the mmap.
+    /// * `prot` - Protection (e.g. readable/writable) of the memory region.
+    pub fn from_fd_offset_protection(
+        fd: &dyn AsRawFd,
+        size: usize,
+        offset: u64,
+        prot: Protection,
+    ) -> Result<MemoryMapping> {
+        MemoryMapping::from_fd_offset_flags(fd, size, offset, libc::MAP_SHARED, prot)
+    }
+
     /// Creates an anonymous shared mapping of `size` bytes with `prot` protection.
     /// Unsafe: unmaps any mmap'd regions already present at (addr..addr+size).
     ///
@@ -229,7 +261,7 @@ impl MemoryMapping {
         addr: *mut u8,
         fd: &dyn AsRawFd,
         size: usize,
-        offset: usize,
+        offset: u64,
         prot: Protection,
     ) -> Result<MemoryMapping> {
         MemoryMapping::try_mmap(
@@ -248,7 +280,7 @@ impl MemoryMapping {
         size: usize,
         prot: c_int,
         flags: c_int,
-        fd: Option<(&dyn AsRawFd, usize)>,
+        fd: Option<(&dyn AsRawFd, u64)>,
     ) -> Result<MemoryMapping> {
         let mut flags = flags;
         // If addr is provided, set the FIXED flag, and validate addr alignment
@@ -265,7 +297,7 @@ impl MemoryMapping {
         // If fd is provided, validate fd offset is within bounds
         let (fd, offset) = match fd {
             Some((fd, offset)) => {
-                if offset > libc::off_t::max_value() as usize {
+                if offset > libc::off_t::max_value() as u64 {
                     return Err(Error::InvalidOffset);
                 }
                 (fd.as_raw_fd(), offset as libc::off_t)
@@ -682,7 +714,7 @@ impl MemoryMappingArena {
         offset: usize,
         size: usize,
         fd: &dyn AsRawFd,
-        fd_offset: usize,
+        fd_offset: u64,
     ) -> Result<()> {
         self.add_fd_offset_protection(offset, size, fd, fd_offset, Protection::read_write())
     }
@@ -702,7 +734,7 @@ impl MemoryMappingArena {
         offset: usize,
         size: usize,
         fd: &dyn AsRawFd,
-        fd_offset: usize,
+        fd_offset: u64,
         prot: Protection,
     ) -> Result<()> {
         self.try_add(offset, size, prot, Some((fd, fd_offset)))
@@ -715,7 +747,7 @@ impl MemoryMappingArena {
         offset: usize,
         size: usize,
         prot: Protection,
-        fd: Option<(&dyn AsRawFd, usize)>,
+        fd: Option<(&dyn AsRawFd, u64)>,
     ) -> Result<()> {
         self.validate_range(offset, size)?;
 
@@ -921,7 +953,7 @@ mod tests {
     #[test]
     fn from_fd_offset_invalid() {
         let fd = unsafe { std::fs::File::from_raw_fd(-1) };
-        let res = MemoryMapping::from_fd_offset(&fd, 4096, (libc::off_t::max_value() as usize) + 1)
+        let res = MemoryMapping::from_fd_offset(&fd, 4096, (libc::off_t::max_value() as u64) + 1)
             .unwrap_err();
         match res {
             Error::InvalidOffset => {}