diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2018-12-12 15:20:30 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-18 00:45:57 -0800 |
commit | c195616e3f288672198961c043ba5a2a71b792b9 (patch) | |
tree | 4653283a499402428aff150f62ee041c2c80375b /arch/src/lib.rs | |
parent | 68d0e7237e8ffac07239032c8d2ef0ccf3f1d312 (diff) | |
download | crosvm-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.rs | 64 |
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) +} |