From 00b30a694fbe40a4917f5f043d7841362e654978 Mon Sep 17 00:00:00 2001 From: Alexandra Iordache Date: Fri, 3 Apr 2020 18:14:34 +0300 Subject: [PATCH] configurator: BootParams struct Added a new struct that encapsulates boot parameters expressed as bytes. * header: section of the parameters that is necessary regardless of boot protocol. For Linux, it's the boot_params struct; for PVH, it's the start_info; for ARM+FDT, it's the device tree blob. * sections: vector of additional boot parameters written at a different address than the header. Unused for Linux & FDT. For PVH, it's the memory map table. * modules: vector of module boot configurations, written at a different address than the header and sections. Unused for Linux & FDT. For PVH, it's (optionally) a vector of 1 modlist_entry containing the initrd configuration, if any. Signed-off-by: Alexandra Iordache --- coverage_config_aarch64.json | 2 +- coverage_config_x86_64.json | 2 +- src/configurator/aarch64/fdt.rs | 72 ++++++++++++--- src/configurator/mod.rs | 148 +++++++++++++++++++++++++++---- src/configurator/x86_64/linux.rs | 57 ++++++------ src/configurator/x86_64/pvh.rs | 142 ++++++++++++++--------------- src/loader/aarch64/pe/mod.rs | 2 +- src/loader/mod.rs | 3 +- src/loader/x86_64/bzimage/mod.rs | 2 +- src/loader/x86_64/elf/mod.rs | 2 +- 10 files changed, 292 insertions(+), 140 deletions(-) diff --git a/coverage_config_aarch64.json b/coverage_config_aarch64.json index 792cfa39..3d96afb3 100644 --- a/coverage_config_aarch64.json +++ b/coverage_config_aarch64.json @@ -1,5 +1,5 @@ { - "coverage_score": 75.7, + "coverage_score": 76.4, "exclude_path": "", "crate_features": "" } diff --git a/coverage_config_x86_64.json b/coverage_config_x86_64.json index 898d1bf0..f199c48b 100644 --- a/coverage_config_x86_64.json +++ b/coverage_config_x86_64.json @@ -1,5 +1,5 @@ { - "coverage_score": 74.8, + "coverage_score": 77.8, "exclude_path": "", "crate_features": "" } diff --git a/src/configurator/aarch64/fdt.rs b/src/configurator/aarch64/fdt.rs index 4d4d6c6d..b75262a7 100644 --- a/src/configurator/aarch64/fdt.rs +++ b/src/configurator/aarch64/fdt.rs @@ -4,12 +4,12 @@ //! Traits and structs for loading the device tree. -use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory}; +use vm_memory::{Bytes, GuestMemory}; use std::error::Error as StdError; use std::fmt; -use super::super::{BootConfigurator, Error as BootConfiguratorError, Result}; +use crate::configurator::{BootConfigurator, BootParams, Error as BootConfiguratorError, Result}; /// Errors specific to the device tree boot protocol configuration. #[derive(Debug, PartialEq)] @@ -51,22 +51,70 @@ impl BootConfigurator for FdtBootConfigurator { /// /// # Arguments /// - /// * `fdt` - flattened device tree. - /// * `sections` - unused. + /// * `params` - boot parameters containing the FDT. /// * `guest_memory` - guest's physical memory. - fn write_bootparams( - fdt: (T, GuestAddress), - _sections: Option<(Vec, GuestAddress)>, - guest_memory: &M, - ) -> Result<()> + fn write_bootparams(params: BootParams, guest_memory: &M) -> Result<()> where - T: ByteValued, - S: ByteValued, M: GuestMemory, { // The VMM has filled an FDT and passed it as a `ByteValued` object. guest_memory - .write_obj(fdt.0, fdt.1) + .write_slice(params.header.0.as_slice(), params.header.1) .map_err(|_| Error::WriteFDTToMemory.into()) } } + +#[cfg(test)] +mod tests { + use super::*; + use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap}; + + const FDT_MAX_SIZE: usize = 0x20; + const MEM_SIZE: u64 = 0x100_0000; + + fn create_guest_mem() -> GuestMemoryMmap { + GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap() + } + + #[derive(Clone, Copy, Default)] + struct FdtPlaceholder([u8; FDT_MAX_SIZE]); + unsafe impl ByteValued for FdtPlaceholder {} + + #[test] + fn test_configure_fdt_boot() { + let fdt = FdtPlaceholder([0u8; FDT_MAX_SIZE]); + let guest_memory = create_guest_mem(); + + // Error case: FDT doesn't fit in guest memory. + let fdt_addr = guest_memory + .last_addr() + .checked_sub(FDT_MAX_SIZE as u64 - 2) + .unwrap(); + assert_eq!( + FdtBootConfigurator::write_bootparams::( + BootParams::new::(&fdt, fdt_addr), + &guest_memory, + ) + .err(), + Some(Error::WriteFDTToMemory.into()) + ); + + let fdt_addr = guest_memory + .last_addr() + .checked_sub(FDT_MAX_SIZE as u64 - 1) + .unwrap(); + assert!(FdtBootConfigurator::write_bootparams::( + BootParams::new::(&fdt, fdt_addr), + &guest_memory, + ) + .is_ok()); + } + + #[test] + fn test_error_messages() { + assert_eq!( + format!("{}", Error::WriteFDTToMemory), + "Device Tree Boot Configurator Error: Error writing FDT in guest memory." + ) + } +} diff --git a/src/configurator/mod.rs b/src/configurator/mod.rs index 20ac64da..da97a8a7 100644 --- a/src/configurator/mod.rs +++ b/src/configurator/mod.rs @@ -90,27 +90,137 @@ pub trait BootConfigurator { /// /// # Arguments /// - /// * `header` - header section of the boot parameters and address where to write it in guest - /// memory. The first element must be a POD struct that implements [`ByteValued`]. - /// For the Linux protocol it's the [`boot_params`] struct, and for PVH the - /// [`hvm_start_info`] struct. - /// * `sections` - vector of sections that compose the boot parameters and address where to - /// write them in guest memory. Unused for the Linux protocol. For PVH, it's the - /// memory map table represented as a vector of [`hvm_memmap_table_entry`]. Must - /// be a `Vec` of POD data structs that implement [`ByteValued`]. + /// * `params` - struct containing the header section of the boot parameters, additional + /// sections and modules, and their associated addresses in guest memory. These + /// vary with the boot protocol used. /// * `guest_memory` - guest's physical memory. + fn write_bootparams(params: BootParams, guest_memory: &M) -> Result<()> + where + M: GuestMemory; +} + +/// Boot parameters to be written in guest memory. +#[derive(Clone)] +pub struct BootParams { + /// "Header section", always written in guest memory irrespective of boot protocol. + pub header: (Vec, GuestAddress), + /// Optional sections containing boot configurations (e.g. E820 map). + pub sections: Option<(Vec, GuestAddress)>, + /// Optional modules specified at boot configuration time. + pub modules: Option<(Vec, GuestAddress)>, +} + +impl BootParams { + /// Creates a new [`BootParams`](struct.BootParams.html) struct with the specified header. + /// + /// # Arguments + /// + /// * `header` - [`ByteValued`] representation of mandatory boot parameters. + /// * `header_addr` - address in guest memory where `header` will be written. + /// + /// [`ByteValued`]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued.html + pub fn new(header: &T, header_addr: GuestAddress) -> Self { + BootParams { + header: (header.as_slice().to_vec(), header_addr), + sections: None, + modules: None, + } + } + + /// Adds or overwrites the boot sections and associated memory address. + /// + /// Unused on `aarch64` and for the Linux boot protocol. + /// For the PVH boot protocol, the sections specify the memory map table in + /// [`hvm_memmap_table_entry`] structs. + /// + /// # Arguments + /// + /// * `sections` - vector of [`ByteValued`] boot configurations. + /// * `sections_addr` - address where the sections will be written in guest memory. /// - /// [`boot_params`]: ../loader/bootparam/struct.boot_e820_entry.html + /// [`ByteValued`]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued.html /// [`hvm_memmap_table_entry`]: ../loader/elf/start_info/struct.hvm_memmap_table_entry.html - /// [`hvm_start_info`]: ../loader/elf/start_info/struct.hvm_start_info.html + pub fn add_sections(&mut self, sections: &Vec, sections_addr: GuestAddress) { + self.sections = Some(( + sections + .iter() + .flat_map(|section| section.as_slice().to_vec()) + .collect(), + sections_addr, + )); + } + + /// Adds or overwrites the boot modules and associated memory address. + /// + /// Unused on `aarch64` and for the Linux boot protocol. + /// For the PVH boot protocol, the modules are specified in [`hvm_modlist_entry`] structs. + /// + /// # Arguments + /// + /// * `modules` - vector of [`ByteValued`] boot configurations. + /// * `modules_addr` - address where the modules will be written in guest memory. + /// /// [`ByteValued`]: https://docs.rs/vm-memory/latest/vm_memory/bytes/trait.ByteValued.html - fn write_bootparams( - header: (T, GuestAddress), - sections: Option<(Vec, GuestAddress)>, - guest_memory: &M, - ) -> Result<()> - where - T: ByteValued, - S: ByteValued, - M: GuestMemory; + /// [`hvm_modlist_entry`]: ../loader/elf/start_info/struct.hvm_modlist_entry.html + pub fn add_modules(&mut self, modules: &Vec, modules_addr: GuestAddress) { + self.modules = Some(( + modules + .iter() + .flat_map(|module| module.as_slice().to_vec()) + .collect(), + modules_addr, + )); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_error_messages() { + #[cfg(target_arch = "x86_64")] + { + // Linux + assert_eq!( + format!("{}", Error::Linux(linux::Error::ZeroPagePastRamEnd)), + "Boot Configurator Error: The zero page extends past the end of guest memory." + ); + assert_eq!( + format!("{}", Error::Linux(linux::Error::ZeroPageSetup)), + "Boot Configurator Error: Error writing to the zero page of guest memory." + ); + + // PVH + assert_eq!( + format!("{}", Error::Pvh(pvh::Error::MemmapTableMissing)), + "Boot Configurator Error: No memory map was passed to the boot configurator." + ); + assert_eq!( + format!("{}", Error::Pvh(pvh::Error::MemmapTablePastRamEnd)), + "Boot Configurator Error: \ + The memory map table extends past the end of guest memory." + ); + assert_eq!( + format!("{}", Error::Pvh(pvh::Error::MemmapTableSetup)), + "Boot Configurator Error: Error writing memory map table to guest memory." + ); + assert_eq!( + format!("{}", Error::Pvh(pvh::Error::StartInfoPastRamEnd)), + "Boot Configurator Error: \ + The hvm_start_info structure extends past the end of guest memory." + ); + assert_eq!( + format!("{}", Error::Pvh(pvh::Error::StartInfoSetup)), + "Boot Configurator Error: Error writing hvm_start_info to guest memory." + ); + } + + #[cfg(target_arch = "aarch64")] + // FDT + assert_eq!( + format!("{}", Error::Fdt(fdt::Error::WriteFDTToMemory)), + "Boot Configurator Error: Error writing FDT in guest memory." + ); + } } diff --git a/src/configurator/x86_64/linux.rs b/src/configurator/x86_64/linux.rs index 3057ad3e..51a7bcaf 100644 --- a/src/configurator/x86_64/linux.rs +++ b/src/configurator/x86_64/linux.rs @@ -12,14 +12,12 @@ //! Traits and structs for configuring and loading boot parameters on `x86_64` using the Linux //! boot protocol. -use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory}; +use vm_memory::{Bytes, GuestMemory}; -use super::super::{BootConfigurator, Error as BootConfiguratorError, Result}; -use crate::loader::bootparam::boot_params; +use crate::configurator::{BootConfigurator, BootParams, Error as BootConfiguratorError, Result}; use std::error::Error as StdError; use std::fmt; -use std::mem; /// Boot configurator for the Linux boot protocol. pub struct LinuxBootConfigurator {} @@ -64,28 +62,22 @@ impl BootConfigurator for LinuxBootConfigurator { /// /// # Arguments /// - /// * `header` - boot parameters encapsulated in a [`boot_params`] struct. - /// * `sections` - unused. + /// * `params` - boot parameters. The header contains a [`boot_params`] struct. The `sections` + /// and `modules` are unused. /// * `guest_memory` - guest's physical memory. /// - /// [`boot_params`]: ../loader/bootparam/struct.boot_e820_entry.html - fn write_bootparams( - header: (T, GuestAddress), - _sections: Option<(Vec, GuestAddress)>, - guest_memory: &M, - ) -> Result<()> + /// [`boot_params`]: ../loader/bootparam/struct.boot_params.html + fn write_bootparams(params: BootParams, guest_memory: &M) -> Result<()> where - T: ByteValued, - S: ByteValued, M: GuestMemory, { // The VMM has filled a `boot_params` struct and its e820 map. // This will be written in guest memory at the zero page. guest_memory - .checked_offset(header.1, mem::size_of::()) + .checked_offset(params.header.1, params.header.0.len()) .ok_or(Error::ZeroPagePastRamEnd)?; guest_memory - .write_obj(header.0, header.1) + .write_slice(params.header.0.as_slice(), params.header.1) .map_err(|_| Error::ZeroPageSetup)?; Ok(()) @@ -95,6 +87,7 @@ impl BootConfigurator for LinuxBootConfigurator { #[cfg(test)] mod tests { use super::*; + use crate::loader::bootparam::boot_params; use std::mem; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; @@ -102,7 +95,7 @@ mod tests { const KERNEL_HDR_MAGIC: u32 = 0x53726448; const KERNEL_LOADER_OTHER: u8 = 0xff; const KERNEL_MIN_ALIGNMENT_BYTES: u32 = 0x1000000; - const MEM_SIZE: u64 = 0x1000000; + const MEM_SIZE: u64 = 0x100_0000; fn create_guest_mem() -> GuestMemoryMmap { GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap() @@ -130,10 +123,10 @@ mod tests { let bad_zeropg_addr = GuestAddress( guest_memory.last_addr().raw_value() - mem::size_of::() as u64 + 1, ); + let mut bootparams = BootParams::new::(¶ms, bad_zeropg_addr); assert_eq!( - LinuxBootConfigurator::write_bootparams::( - (params, bad_zeropg_addr), - None, + LinuxBootConfigurator::write_bootparams::( + bootparams.clone(), &guest_memory, ) .err(), @@ -141,13 +134,23 @@ mod tests { ); // Success case. - assert!( - LinuxBootConfigurator::write_bootparams::( - (params, zero_page_addr), - None, - &guest_memory - ) - .is_ok() + bootparams.header.1 = zero_page_addr; + assert!(LinuxBootConfigurator::write_bootparams::( + bootparams, + &guest_memory, + ) + .is_ok()); + } + + #[test] + fn test_error_messages() { + assert_eq!( + format!("{}", Error::ZeroPagePastRamEnd), + "Linux Boot Configurator Error: The zero page extends past the end of guest memory." + ); + assert_eq!( + format!("{}", Error::ZeroPageSetup), + "Linux Boot Configurator Error: Error writing to the zero page of guest memory." ); } } diff --git a/src/configurator/x86_64/pvh.rs b/src/configurator/x86_64/pvh.rs index 9484b37a..af9b2911 100644 --- a/src/configurator/x86_64/pvh.rs +++ b/src/configurator/x86_64/pvh.rs @@ -12,14 +12,13 @@ //! Traits and structs for configuring and loading boot parameters on `x86_64` using the PVH boot //! protocol. -use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory}; +use vm_memory::{ByteValued, Bytes, GuestMemory}; -use super::super::{BootConfigurator, Error as BootConfiguratorError, Result}; -use crate::loader::elf::start_info::{hvm_memmap_table_entry, hvm_start_info}; +use crate::configurator::{BootConfigurator, BootParams, Error as BootConfiguratorError, Result}; +use crate::loader::elf::start_info::{hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info}; use std::error::Error as StdError; use std::fmt; -use std::mem; /// Boot configurator for the PVH boot protocol. pub struct PvhBootConfigurator {} @@ -43,7 +42,7 @@ impl StdError for Error { fn description(&self) -> &str { use Error::*; match self { - MemmapTableMissing => "No memory map wasn't passed to the boot configurator.", + MemmapTableMissing => "No memory map was passed to the boot configurator.", MemmapTablePastRamEnd => "The memory map table extends past the end of guest memory.", MemmapTableSetup => "Error writing memory map table to guest memory.", StartInfoPastRamEnd => { @@ -72,53 +71,44 @@ impl From for BootConfiguratorError { unsafe impl ByteValued for hvm_start_info {} unsafe impl ByteValued for hvm_memmap_table_entry {} +unsafe impl ByteValued for hvm_modlist_entry {} impl BootConfigurator for PvhBootConfigurator { /// Writes the boot parameters (configured elsewhere) into guest memory. /// /// # Arguments /// - /// * `header` - boot parameters encapsulated in a [`hvm_start_info`] struct. - /// * `sections` - memory map table represented as a vector of [`hvm_memmap_table_entry`]. + /// * `params` - boot parameters. The header contains a [`hvm_start_info`] struct. The + /// sections contain the memory map in a vector of [`hvm_memmap_table_entry`] + /// structs. The modules, if specified, contain [`hvm_modlist_entry`] structs. /// * `guest_memory` - guest's physical memory. /// - /// [`hvm_start_info`]: ../loader/elf/start_info/struct.hvm_start_info + /// [`hvm_start_info`]: ../loader/elf/start_info/struct.hvm_start_info.html /// [`hvm_memmap_table_entry`]: ../loader/elf/start_info/struct.hvm_memmap_table_entry.html - fn write_bootparams( - header: (T, GuestAddress), - sections: Option<(Vec, GuestAddress)>, - guest_memory: &M, - ) -> Result<()> + /// [`hvm_modlist_entry`]: ../loader/elf/start_info/struct.hvm_modlist_entry.html + fn write_bootparams(params: BootParams, guest_memory: &M) -> Result<()> where - T: ByteValued, - S: ByteValued, M: GuestMemory, { // The VMM has filled an `hvm_start_info` struct and a `Vec` // and has passed them on to this function. // The `hvm_start_info` will be written at `addr` and the memmap entries at // `start_info.0.memmap_paddr`. - let (memmap_entries, mut memmap_start_addr) = sections.ok_or(Error::MemmapTableMissing)?; + let memmap = params.sections.ok_or(Error::MemmapTableMissing)?; + let header = params.header; + guest_memory - .checked_offset( - memmap_start_addr, - mem::size_of::() * memmap_entries.len(), - ) + .checked_offset(memmap.1, memmap.0.len()) .ok_or(Error::MemmapTablePastRamEnd)?; - - for memmap_entry in memmap_entries { - guest_memory - .write_obj(memmap_entry, memmap_start_addr) - .map_err(|_| Error::MemmapTableSetup)?; - memmap_start_addr = - memmap_start_addr.unchecked_add(mem::size_of::() as u64); - } + guest_memory + .write_slice(memmap.0.as_slice(), memmap.1) + .map_err(|_| Error::MemmapTableSetup)?; guest_memory - .checked_offset(header.1, mem::size_of::()) + .checked_offset(header.1, header.0.len()) .ok_or(Error::StartInfoPastRamEnd)?; guest_memory - .write_obj(header.0, header.1) + .write_slice(header.0.as_slice(), header.1) .map_err(|_| Error::StartInfoSetup)?; Ok(()) @@ -128,59 +118,51 @@ impl BootConfigurator for PvhBootConfigurator { #[cfg(test)] mod tests { use super::*; + use std::mem; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578; - const MEM_SIZE: u64 = 0x1000000; + const MEM_SIZE: u64 = 0x100_0000; const E820_RAM: u32 = 1; fn create_guest_mem() -> GuestMemoryMmap { GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap() } - fn add_memmap_entry( - memmap_entries: &mut Vec, - addr: GuestAddress, - size: u64, - mem_type: u32, - ) { - // Add the table entry to the vector - memmap_entries.push(hvm_memmap_table_entry { - addr: addr.raw_value(), - size, - type_: mem_type, - reserved: 0, - }); - } - fn build_bootparams_common() -> (hvm_start_info, Vec) { let mut start_info = hvm_start_info::default(); - let memmap_entries: Vec = vec![]; + let memmap_entry = hvm_memmap_table_entry { + addr: 0x7000, + size: 0, + type_: E820_RAM, + reserved: 0, + }; start_info.magic = XEN_HVM_START_MAGIC_VALUE; start_info.version = 1; start_info.nr_modules = 0; start_info.memmap_entries = 0; - (start_info, memmap_entries) + (start_info, vec![memmap_entry]) } #[test] fn test_configure_pvh_boot() { - let (mut start_info, mut memmap_entries) = build_bootparams_common(); + let (mut start_info, memmap_entries) = build_bootparams_common(); let guest_memory = create_guest_mem(); let start_info_addr = GuestAddress(0x6000); let memmap_addr = GuestAddress(0x7000); start_info.memmap_paddr = memmap_addr.raw_value(); + let mut boot_params = BootParams::new::(&start_info, start_info_addr); + // Error case: configure without memory map. assert_eq!( - PvhBootConfigurator::write_bootparams::< - hvm_start_info, - hvm_memmap_table_entry, - GuestMemoryMmap, - >((start_info, start_info_addr), None, &guest_memory,) + PvhBootConfigurator::write_bootparams::( + boot_params.clone(), + &guest_memory, + ) .err(), Some(Error::MemmapTableMissing.into()) ); @@ -189,14 +171,11 @@ mod tests { let bad_start_info_addr = GuestAddress( guest_memory.last_addr().raw_value() - mem::size_of::() as u64 + 1, ); + boot_params.add_sections::(&memmap_entries, memmap_addr); + boot_params.header.1 = bad_start_info_addr; assert_eq!( - PvhBootConfigurator::write_bootparams::< - hvm_start_info, - hvm_memmap_table_entry, - GuestMemoryMmap, - >( - (start_info, bad_start_info_addr), - Some((memmap_entries.clone(), memmap_addr)), + PvhBootConfigurator::write_bootparams::( + boot_params.clone(), &guest_memory, ) .err(), @@ -205,34 +184,45 @@ mod tests { // Error case: memory map doesn't fit in guest memory. let himem_start = GuestAddress(0x100000); - add_memmap_entry(&mut memmap_entries, himem_start, 0, E820_RAM); + boot_params.header.1 = himem_start; let bad_memmap_addr = GuestAddress( guest_memory.last_addr().raw_value() - mem::size_of::() as u64 + 1, ); + boot_params.add_sections::(&memmap_entries, bad_memmap_addr); + assert_eq!( - PvhBootConfigurator::write_bootparams::< - hvm_start_info, - hvm_memmap_table_entry, - GuestMemoryMmap, - >( - (start_info, start_info_addr), - Some((memmap_entries.clone(), bad_memmap_addr)), + PvhBootConfigurator::write_bootparams::( + boot_params.clone(), &guest_memory, ) .err(), Some(Error::MemmapTablePastRamEnd.into()) ); - assert!(PvhBootConfigurator::write_bootparams::< - hvm_start_info, - hvm_memmap_table_entry, - GuestMemoryMmap, - >( - (start_info, start_info_addr), - Some((memmap_entries.clone(), memmap_addr)), + boot_params.add_sections::(&memmap_entries, memmap_addr); + assert!(PvhBootConfigurator::write_bootparams::( + boot_params, &guest_memory, ) .is_ok()); } + + #[test] + fn test_error_messages() { + assert_eq!( + format!("{}", Error::MemmapTableMissing), + "PVH Boot Configurator Error: No memory map was passed to the boot configurator." + ); + assert_eq!(format!("{}", Error::MemmapTablePastRamEnd), "PVH Boot Configurator Error: The memory map table extends past the end of guest memory."); + assert_eq!( + format!("{}", Error::MemmapTableSetup), + "PVH Boot Configurator Error: Error writing memory map table to guest memory." + ); + assert_eq!(format!("{}", Error::StartInfoPastRamEnd), "PVH Boot Configurator Error: The hvm_start_info structure extends past the end of guest memory."); + assert_eq!( + format!("{}", Error::StartInfoSetup), + "PVH Boot Configurator Error: Error writing hvm_start_info to guest memory." + ); + } } diff --git a/src/loader/aarch64/pe/mod.rs b/src/loader/aarch64/pe/mod.rs index feae0bc8..280a9882 100644 --- a/src/loader/aarch64/pe/mod.rs +++ b/src/loader/aarch64/pe/mod.rs @@ -195,7 +195,7 @@ mod tests { use std::io::Cursor; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; - const MEM_SIZE: u64 = 0x1000000; + const MEM_SIZE: u64 = 0x100_0000; fn create_guest_mem() -> GuestMemoryMmap { GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap() diff --git a/src/loader/mod.rs b/src/loader/mod.rs index 81e70c53..73767a68 100644 --- a/src/loader/mod.rs +++ b/src/loader/mod.rs @@ -157,6 +157,7 @@ pub trait KernelLoader { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] unsafe impl ByteValued for bootparam::setup_header {} +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] unsafe impl ByteValued for bootparam::boot_params {} /// Writes the command line string to the given guest memory slice. @@ -195,7 +196,7 @@ mod tests { use super::*; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; - const MEM_SIZE: u64 = 0x1000000; + const MEM_SIZE: u64 = 0x100_0000; fn create_guest_mem() -> GuestMemoryMmap { GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap() diff --git a/src/loader/x86_64/bzimage/mod.rs b/src/loader/x86_64/bzimage/mod.rs index dc37f9d3..b387053a 100644 --- a/src/loader/x86_64/bzimage/mod.rs +++ b/src/loader/x86_64/bzimage/mod.rs @@ -179,7 +179,7 @@ mod tests { use std::io::Cursor; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; - const MEM_SIZE: u64 = 0x1000000; + const MEM_SIZE: u64 = 0x100_0000; fn create_guest_mem() -> GuestMemoryMmap { GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap() diff --git a/src/loader/x86_64/elf/mod.rs b/src/loader/x86_64/elf/mod.rs index 4b6de40b..1b319d7f 100644 --- a/src/loader/x86_64/elf/mod.rs +++ b/src/loader/x86_64/elf/mod.rs @@ -359,7 +359,7 @@ mod tests { use std::io::Cursor; use vm_memory::{Address, GuestAddress, GuestMemoryMmap}; - const MEM_SIZE: u64 = 0x1000000; + const MEM_SIZE: u64 = 0x100_0000; fn create_guest_mem() -> GuestMemoryMmap { GuestMemoryMmap::from_ranges(&[(GuestAddress(0x0), (MEM_SIZE as usize))]).unwrap()