vmm: x86_64: Add support for firmware loading

Since our firmware files are still designed to be used via PVH use the
load_kernel() function to load the firmware falling back to legacy
firmware loading if necessary.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2022-08-16 12:41:44 +01:00
parent 8ec5a248cd
commit 0d682e185f

View File

@@ -1037,7 +1037,7 @@ impl Vm {
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn load_kernel( fn load_kernel(
mut kernel: File, mut kernel: File,
cmdline: Cmdline, cmdline: Option<Cmdline>,
memory_manager: Arc<Mutex<MemoryManager>>, memory_manager: Arc<Mutex<MemoryManager>>,
) -> Result<EntryPoint> { ) -> Result<EntryPoint> {
use linux_loader::loader::{elf::Error::InvalidElfMagicNumber, Error::Elf}; use linux_loader::loader::{elf::Error::InvalidElfMagicNumber, Error::Elf};
@@ -1062,8 +1062,10 @@ impl Vm {
}, },
}; };
linux_loader::loader::load_cmdline(mem.deref(), arch::layout::CMDLINE_START, &cmdline) if let Some(cmdline) = cmdline {
.map_err(Error::LoadCmdLine)?; linux_loader::loader::load_cmdline(mem.deref(), arch::layout::CMDLINE_START, &cmdline)
.map_err(Error::LoadCmdLine)?;
}
if let PvhEntryPresent(entry_addr) = entry_addr.pvh_boot_cap { if let PvhEntryPresent(entry_addr) = entry_addr.pvh_boot_cap {
// Use the PVH kernel entry point to boot the guest // Use the PVH kernel entry point to boot the guest
@@ -1081,18 +1083,22 @@ impl Vm {
payload: &PayloadConfig, payload: &PayloadConfig,
memory_manager: Arc<Mutex<MemoryManager>>, memory_manager: Arc<Mutex<MemoryManager>>,
) -> Result<EntryPoint> { ) -> Result<EntryPoint> {
let kernel = payload match (
.kernel &payload.firmware,
.as_ref() &payload.kernel,
.map(File::open) &payload.initramfs,
.transpose() &payload.cmdline,
.map_err(Error::KernelFile)?; ) {
(Some(firmware), None, None, None) => {
if let Some(kernel) = kernel { let firmware = File::open(firmware).map_err(Error::FirmwareFile)?;
let cmdline = Self::generate_cmdline(payload)?; Self::load_kernel(firmware, None, memory_manager)
Self::load_kernel(kernel, cmdline, memory_manager) }
} else { (None, Some(kernel), _, _) => {
Err(Error::InvalidPayload) let kernel = File::open(kernel).map_err(Error::KernelFile)?;
let cmdline = Self::generate_cmdline(payload)?;
Self::load_kernel(kernel, Some(cmdline), memory_manager)
}
_ => Err(Error::InvalidPayload),
} }
} }