vmm: Refactor kernel loading to decouple from Vm struct

This will allow the kernel to be loaded from another thread.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-04-28 16:01:03 +01:00
parent ce6d88d187
commit bfeb3120f5

View File

@ -1021,13 +1021,18 @@ impl Vm {
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn load_kernel(&mut self) -> Result<EntryPoint> { fn load_kernel(
mut kernel: File,
cmdline: Cmdline,
memory_manager: Arc<Mutex<MemoryManager>>,
) -> Result<EntryPoint> {
use linux_loader::loader::{elf::Error::InvalidElfMagicNumber, Error::Elf}; use linux_loader::loader::{elf::Error::InvalidElfMagicNumber, Error::Elf};
info!("Loading kernel"); info!("Loading kernel");
let cmdline = Self::generate_cmdline(&self.config)?;
let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory(); let mem = {
let mem = guest_memory.memory(); let guest_memory = memory_manager.lock().as_ref().unwrap().guest_memory();
let mut kernel = self.kernel.as_ref().unwrap(); guest_memory.memory()
};
let entry_addr = match linux_loader::loader::elf::Elf::load( let entry_addr = match linux_loader::loader::elf::Elf::load(
mem.deref(), mem.deref(),
None, None,
@ -1056,7 +1061,7 @@ impl Vm {
size size
); );
self.memory_manager memory_manager
.lock() .lock()
.unwrap() .unwrap()
.add_ram_region(load_address, size as usize) .add_ram_region(load_address, size as usize)
@ -1065,9 +1070,7 @@ impl Vm {
kernel kernel
.seek(SeekFrom::Start(0)) .seek(SeekFrom::Start(0))
.map_err(Error::FirmwareFile)?; .map_err(Error::FirmwareFile)?;
guest_memory mem.read_exact_from(load_address, &mut kernel, size as usize)
.memory()
.read_exact_from(load_address, &mut kernel, size as usize)
.map_err(Error::FirmwareLoad)?; .map_err(Error::FirmwareLoad)?;
return Ok(EntryPoint { entry_addr: None }); return Ok(EntryPoint { entry_addr: None });
@ -2061,8 +2064,14 @@ impl Vm {
return Ok(None); return Ok(None);
} }
Ok(if self.kernel.as_ref().is_some() { Ok(if let Some(kernel) = self.kernel.as_ref() {
Some(self.load_kernel()?) let cmdline = Self::generate_cmdline(&self.config)?;
let entry_point = Self::load_kernel(
kernel.try_clone().unwrap(),
cmdline,
self.memory_manager.clone(),
)?;
Some(entry_point)
} else { } else {
None None
}) })