vmm: harmonize bootpath across architectures

On aarch64 and RISC-V, calling load_firmware() through load_kernel()
provides no benefit and only duplicates checks already performed in
load_payload(). load_payload() now directly invokes load_firmware() or
load_kernel(), removing unnecessary indirection and redundancy.

Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
Philipp Schuster
2025-08-12 12:39:38 +02:00
committed by Bo Chen
parent 1a63b4b2ff
commit 2c6426460e
+14 -14
View File
@@ -1173,18 +1173,22 @@ impl Vm {
} }
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
fn load_firmware(mut firmware: &File, memory_manager: Arc<Mutex<MemoryManager>>) -> Result<()> { fn load_firmware(
mut firmware: &File,
memory_manager: Arc<Mutex<MemoryManager>>,
) -> Result<EntryPoint> {
let uefi_flash = memory_manager.lock().as_ref().unwrap().uefi_flash(); let uefi_flash = memory_manager.lock().as_ref().unwrap().uefi_flash();
let mem = uefi_flash.memory(); let mem = uefi_flash.memory();
arch::uefi::load_uefi(mem.deref(), arch::layout::UEFI_START, &mut firmware) arch::uefi::load_uefi(mem.deref(), arch::layout::UEFI_START, &mut firmware)
.map_err(Error::UefiLoad)?; .map_err(Error::UefiLoad)?;
Ok(()) Ok(EntryPoint {
entry_addr: arch::layout::UEFI_START,
})
} }
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
fn load_kernel( fn load_kernel(
firmware: Option<File>, mut kernel: File,
kernel: Option<File>,
memory_manager: Arc<Mutex<MemoryManager>>, memory_manager: Arc<Mutex<MemoryManager>>,
) -> Result<EntryPoint> { ) -> Result<EntryPoint> {
let guest_memory = memory_manager.lock().as_ref().unwrap().guest_memory(); let guest_memory = memory_manager.lock().as_ref().unwrap().guest_memory();
@@ -1192,8 +1196,7 @@ impl Vm {
let alignment = 0x20_0000; let alignment = 0x20_0000;
let aligned_kernel_addr = let aligned_kernel_addr =
(arch::layout::KERNEL_START.0 + (alignment - 1)) & !(alignment - 1); (arch::layout::KERNEL_START.0 + (alignment - 1)) & !(alignment - 1);
let entry_addr = match (firmware, kernel) { let entry_addr = {
(None, Some(mut kernel)) => {
match linux_loader::loader::pe::PE::load( match linux_loader::loader::pe::PE::load(
mem.deref(), mem.deref(),
Some(GuestAddress(aligned_kernel_addr)), Some(GuestAddress(aligned_kernel_addr)),
@@ -1212,12 +1215,6 @@ impl Vm {
return Err(Error::KernelLoad(e)); return Err(Error::KernelLoad(e));
} }
} }
}
(Some(firmware), None) => {
Self::load_firmware(&firmware, memory_manager)?;
arch::layout::UEFI_START
}
_ => unreachable!("Unsupported boot configuration: programming error from 'PayloadConfigError::validate()'"),
}; };
Ok(EntryPoint { entry_addr }) Ok(EntryPoint { entry_addr })
@@ -1254,6 +1251,9 @@ impl Vm {
Ok(entry_point) Ok(entry_point)
} }
/// Loads the kernel or a firmware file.
///
/// For x86_64, the boot path is the same.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
fn load_kernel( fn load_kernel(
mut kernel: File, mut kernel: File,
@@ -1357,11 +1357,11 @@ impl Vm {
match (&payload.firmware, &payload.kernel) { match (&payload.firmware, &payload.kernel) {
(Some(firmware), None) => { (Some(firmware), None) => {
let firmware = File::open(firmware).map_err(Error::FirmwareFile)?; let firmware = File::open(firmware).map_err(Error::FirmwareFile)?;
Self::load_kernel(Some(firmware), None, memory_manager) Self::load_firmware(&firmware, memory_manager)
} }
(None, Some(kernel)) => { (None, Some(kernel)) => {
let kernel = File::open(kernel).map_err(Error::KernelFile)?; let kernel = File::open(kernel).map_err(Error::KernelFile)?;
Self::load_kernel(None, Some(kernel), memory_manager) Self::load_kernel(kernel, memory_manager)
} }
_ => unreachable!("Unsupported boot configuration: programming error from 'PayloadConfigError::validate()'"), _ => unreachable!("Unsupported boot configuration: programming error from 'PayloadConfigError::validate()'"),
} }