summary refs log tree commit diff
path: root/arch/src/lib.rs
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2018-12-12 15:20:30 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-01-18 00:45:57 -0800
commitc195616e3f288672198961c043ba5a2a71b792b9 (patch)
tree4653283a499402428aff150f62ee041c2c80375b /arch/src/lib.rs
parent68d0e7237e8ffac07239032c8d2ef0ccf3f1d312 (diff)
downloadcrosvm-c195616e3f288672198961c043ba5a2a71b792b9.tar
crosvm-c195616e3f288672198961c043ba5a2a71b792b9.tar.gz
crosvm-c195616e3f288672198961c043ba5a2a71b792b9.tar.bz2
crosvm-c195616e3f288672198961c043ba5a2a71b792b9.tar.lz
crosvm-c195616e3f288672198961c043ba5a2a71b792b9.tar.xz
crosvm-c195616e3f288672198961c043ba5a2a71b792b9.tar.zst
crosvm-c195616e3f288672198961c043ba5a2a71b792b9.zip
arch: add generic image loading function
Factor out the common parts of kernel loading code from x86_64 and
aarch64.  This will be used to load initrds as well.

BUG=None
TEST=Boot termina on kevin

Change-Id: I0f61fdaf1067311d25393e8d64340f570f5a6ed7
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1407220
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'arch/src/lib.rs')
-rw-r--r--arch/src/lib.rs64
1 files changed, 63 insertions, 1 deletions
diff --git a/arch/src/lib.rs b/arch/src/lib.rs
index 34f3f3d..057c005 100644
--- a/arch/src/lib.rs
+++ b/arch/src/lib.rs
@@ -13,6 +13,7 @@ extern crate sys_util;
 
 use std::fmt;
 use std::fs::File;
+use std::io::{Read, Seek, SeekFrom};
 use std::os::unix::io::AsRawFd;
 use std::result;
 use std::sync::Arc;
@@ -26,7 +27,7 @@ use io_jail::Minijail;
 use kvm::{IoeventAddress, Kvm, Vcpu, Vm};
 use resources::SystemAllocator;
 use sync::Mutex;
-use sys_util::{syslog, EventFd, GuestMemory};
+use sys_util::{syslog, EventFd, GuestAddress, GuestMemory, GuestMemoryError};
 
 pub type Result<T> = result::Result<T, Box<std::error::Error>>;
 
@@ -194,3 +195,64 @@ pub fn generate_pci_root(
     }
     Ok((root, pci_irqs))
 }
+
+/// Errors for image loading.
+#[derive(Debug)]
+pub enum LoadImageError {
+    Seek(std::io::Error),
+    ImageSizeTooLarge(u64),
+    ReadToMemory(GuestMemoryError),
+}
+
+impl fmt::Display for LoadImageError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            LoadImageError::Seek(e) => write!(f, "Seek failed: {:?}", e),
+            LoadImageError::ImageSizeTooLarge(size) => {
+                write!(f, "Image size too large: {:?}", size)
+            }
+            LoadImageError::ReadToMemory(e) => {
+                write!(f, "Reading image into memory failed: {:?}", e)
+            }
+        }
+    }
+}
+
+/// Load an image from a file into guest memory.
+///
+/// # Arguments
+///
+/// * `guest_mem` - The memory to be used by the guest.
+/// * `guest_addr` - The starting address to load the image in the guest memory.
+/// * `max_size` - The amount of space in bytes available in the guest memory for the image.
+/// * `image` - The file containing the image to be loaded.
+///
+/// The size in bytes of the loaded image is returned.
+pub fn load_image<F>(
+    guest_mem: &GuestMemory,
+    image: &mut F,
+    guest_addr: GuestAddress,
+    max_size: u64,
+) -> std::result::Result<usize, LoadImageError>
+where
+    F: Read + Seek,
+{
+    let size = image.seek(SeekFrom::End(0)).map_err(LoadImageError::Seek)?;
+
+    if size > usize::max_value() as u64 || size > max_size {
+        return Err(LoadImageError::ImageSizeTooLarge(size));
+    }
+
+    // This is safe due to the bounds check above.
+    let size = size as usize;
+
+    image
+        .seek(SeekFrom::Start(0))
+        .map_err(LoadImageError::Seek)?;
+
+    guest_mem
+        .read_to_memory(guest_addr, image, size)
+        .map_err(LoadImageError::ReadToMemory)?;
+
+    Ok(size)
+}