From 3a5ef152b5e803998e6ec5a1e7172c01fcce8bcf Mon Sep 17 00:00:00 2001 From: l00484210 Date: Wed, 11 Dec 2024 20:23:47 +0800 Subject: [PATCH] snapshot: bugfix VM run failed from memory snapshot The kernel does not need to be loaded for snapshot restoration. Signed-off-by: Mingwang Li --- cpu/src/lib.rs | 22 ++++++++------- cpu/src/x86_64/mod.rs | 2 +- devices/src/acpi/cpu_controller.rs | 4 +-- machine/src/aarch64/micro.rs | 40 +++++++++++++++------------ machine/src/aarch64/standard.rs | 44 ++++++++++++++++++------------ machine/src/lib.rs | 2 +- machine/src/x86_64/micro.rs | 9 ++++-- machine/src/x86_64/standard.rs | 13 +++++++-- 8 files changed, 83 insertions(+), 53 deletions(-) diff --git a/cpu/src/lib.rs b/cpu/src/lib.rs index 7a11629..7698132 100644 --- a/cpu/src/lib.rs +++ b/cpu/src/lib.rs @@ -118,7 +118,7 @@ pub trait CPUInterface { /// Realize `CPU` structure, set registers value for `CPU`. fn realize( &self, - boot: &CPUBootConfig, + boot: &Option, topology: &CPUTopology, #[cfg(target_arch = "aarch64")] features: &CPUFeatures, ) -> Result<()>; @@ -310,7 +310,7 @@ impl CPU { impl CPUInterface for CPU { fn realize( &self, - boot: &CPUBootConfig, + boot: &Option, topology: &CPUTopology, #[cfg(target_arch = "aarch64")] config: &CPUFeatures, ) -> Result<()> { @@ -323,14 +323,16 @@ impl CPUInterface for CPU { )))); } - self.hypervisor_cpu - .set_boot_config( - self.arch_cpu.clone(), - boot, - #[cfg(target_arch = "aarch64")] - config, - ) - .with_context(|| "Failed to realize arch cpu")?; + if let Some(boot) = boot { + self.hypervisor_cpu + .set_boot_config( + self.arch_cpu.clone(), + boot, + #[cfg(target_arch = "aarch64")] + config, + ) + .with_context(|| "Failed to realize arch cpu")?; + } self.arch_cpu .lock() diff --git a/cpu/src/x86_64/mod.rs b/cpu/src/x86_64/mod.rs index 0a8ad16..acb6fb2 100644 --- a/cpu/src/x86_64/mod.rs +++ b/cpu/src/x86_64/mod.rs @@ -75,7 +75,7 @@ pub enum X86RegsIndex { /// X86 CPU booting configure information #[allow(clippy::upper_case_acronyms)] -#[derive(Default, Clone, Debug)] +#[derive(Default, Clone, Debug, Copy)] pub struct X86CPUBootConfig { pub prot64_mode: bool, /// Register %rip value diff --git a/devices/src/acpi/cpu_controller.rs b/devices/src/acpi/cpu_controller.rs index 1259e8d..73f2601 100644 --- a/devices/src/acpi/cpu_controller.rs +++ b/devices/src/acpi/cpu_controller.rs @@ -157,8 +157,8 @@ impl CpuController { None } - pub fn get_boot_config(&self) -> &CPUBootConfig { - &self.cpu_config.as_ref().unwrap().boot_config + pub fn get_boot_config(&self) -> CPUBootConfig { + self.cpu_config.as_ref().unwrap().boot_config } pub fn get_hotplug_cpu_info(&self) -> (String, u8) { diff --git a/machine/src/aarch64/micro.rs b/machine/src/aarch64/micro.rs index 42e9171..3e7cf38 100644 --- a/machine/src/aarch64/micro.rs +++ b/machine/src/aarch64/micro.rs @@ -20,7 +20,7 @@ use address_space::{AddressSpace, GuestAddress, Region}; use cpu::CPUTopology; use devices::{legacy::PL031, ICGICConfig, ICGICv2Config, ICGICv3Config, GIC_IRQ_MAX}; use hypervisor::kvm::aarch64::*; -use machine_manager::config::{SerialConfig, VmConfig}; +use machine_manager::config::{MigrateMode, SerialConfig, VmConfig}; use migration::{MigrationManager, MigrationStatus}; use util::{ device_tree::{self, CompileFDT, FdtBuilder}, @@ -160,8 +160,12 @@ impl MachineOps for LightMachine { vm_config.machine_config.nr_cpus, )?; - let boot_config = - locked_vm.load_boot_source(None, MEM_LAYOUT[LayoutEntryType::Mem as usize].0)?; + let migrate_info = locked_vm.get_migrate_info(); + let boot_config = if migrate_info.0 == MigrateMode::Unknown { + Some(locked_vm.load_boot_source(None, MEM_LAYOUT[LayoutEntryType::Mem as usize].0)?) + } else { + None + }; let cpu_config = locked_vm.load_cpu_features(vm_config)?; let hypervisor = locked_vm.base.hypervisor.clone(); @@ -186,20 +190,22 @@ impl MachineOps for LightMachine { locked_vm.add_devices(vm_config)?; trace::replaceable_info(&locked_vm.replaceable_info); - let mut fdt_helper = FdtBuilder::new(); - locked_vm - .generate_fdt_node(&mut fdt_helper) - .with_context(|| MachineError::GenFdtErr)?; - let fdt_vec = fdt_helper.finish()?; - locked_vm - .base - .sys_mem - .write( - &mut fdt_vec.as_slice(), - GuestAddress(boot_config.fdt_addr), - fdt_vec.len() as u64, - ) - .with_context(|| MachineError::WrtFdtErr(boot_config.fdt_addr, fdt_vec.len()))?; + if let Some(boot_cfg) = boot_config { + let mut fdt_helper = FdtBuilder::new(); + locked_vm + .generate_fdt_node(&mut fdt_helper) + .with_context(|| MachineError::GenFdtErr)?; + let fdt_vec = fdt_helper.finish()?; + locked_vm + .base + .sys_mem + .write( + &mut fdt_vec.as_slice(), + GuestAddress(boot_cfg.fdt_addr), + fdt_vec.len() as u64, + ) + .with_context(|| MachineError::WrtFdtErr(boot_cfg.fdt_addr, fdt_vec.len()))?; + } MigrationManager::register_vm_instance(vm.clone()); MigrationManager::register_migration_instance(locked_vm.base.migration_hypervisor.clone()); diff --git a/machine/src/aarch64/standard.rs b/machine/src/aarch64/standard.rs index 8544a2b..416298a 100644 --- a/machine/src/aarch64/standard.rs +++ b/machine/src/aarch64/standard.rs @@ -606,8 +606,16 @@ impl MachineOps for StdMachine { .with_context(|| MachineError::InitPCIeHostErr)?; let fwcfg = locked_vm.add_fwcfg_device(nr_cpus)?; - let boot_config = locked_vm - .load_boot_source(fwcfg.as_ref(), MEM_LAYOUT[LayoutEntryType::Mem as usize].0)?; + let migrate = locked_vm.get_migrate_info(); + let boot_config = + if migrate.0 == MigrateMode::Unknown { + Some(locked_vm.load_boot_source( + fwcfg.as_ref(), + MEM_LAYOUT[LayoutEntryType::Mem as usize].0, + )?) + } else { + None + }; let cpu_config = locked_vm.load_cpu_features(vm_config)?; let hypervisor = locked_vm.base.hypervisor.clone(); @@ -632,21 +640,23 @@ impl MachineOps for StdMachine { .add_devices(vm_config) .with_context(|| "Failed to add devices")?; - let mut fdt_helper = FdtBuilder::new(); - locked_vm - .generate_fdt_node(&mut fdt_helper) - .with_context(|| MachineError::GenFdtErr)?; - let fdt_vec = fdt_helper.finish()?; - locked_vm.dtb_vec = fdt_vec.clone(); - locked_vm - .base - .sys_mem - .write( - &mut fdt_vec.as_slice(), - GuestAddress(boot_config.fdt_addr), - fdt_vec.len() as u64, - ) - .with_context(|| MachineError::WrtFdtErr(boot_config.fdt_addr, fdt_vec.len()))?; + if let Some(boot_cfg) = boot_config { + let mut fdt_helper = FdtBuilder::new(); + locked_vm + .generate_fdt_node(&mut fdt_helper) + .with_context(|| MachineError::GenFdtErr)?; + let fdt_vec = fdt_helper.finish()?; + locked_vm.dtb_vec = fdt_vec.clone(); + locked_vm + .base + .sys_mem + .write( + &mut fdt_vec.as_slice(), + GuestAddress(boot_cfg.fdt_addr), + fdt_vec.len() as u64, + ) + .with_context(|| MachineError::WrtFdtErr(boot_cfg.fdt_addr, fdt_vec.len()))?; + } // If it is direct kernel boot mode, the ACPI can not be enabled. if let Some(fw_cfg) = fwcfg { diff --git a/machine/src/lib.rs b/machine/src/lib.rs index 6c13c03..c1c0c22 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -465,7 +465,7 @@ pub trait MachineOps { nr_cpus: u8, #[cfg(target_arch = "x86_64")] max_cpus: u8, topology: &CPUTopology, - boot_cfg: &CPUBootConfig, + boot_cfg: &Option, #[cfg(target_arch = "aarch64")] vcpu_cfg: &CPUFeatures, ) -> Result>> where diff --git a/machine/src/x86_64/micro.rs b/machine/src/x86_64/micro.rs index 7b4e08e..77ea440 100644 --- a/machine/src/x86_64/micro.rs +++ b/machine/src/x86_64/micro.rs @@ -22,7 +22,7 @@ use cpu::{CPUBootConfig, CPUTopology}; use devices::legacy::FwCfgOps; use hypervisor::kvm::x86_64::*; use hypervisor::kvm::*; -use machine_manager::config::{SerialConfig, VmConfig}; +use machine_manager::config::{MigrateMode, SerialConfig, VmConfig}; use migration::{MigrationManager, MigrationStatus}; use util::seccomp::{BpfRule, SeccompCmpOpt}; use virtio::VirtioMmioDevice; @@ -174,7 +174,12 @@ impl MachineOps for LightMachine { locked_vm.add_devices(vm_config)?; trace::replaceable_info(&locked_vm.replaceable_info); - let boot_config = locked_vm.load_boot_source(None)?; + let migrate_info = locked_vm.get_migrate_info(); + let boot_config = if migrate_info.0 == MigrateMode::Unknown { + Some(locked_vm.load_boot_source(None)?) + } else { + None + }; let hypervisor = locked_vm.base.hypervisor.clone(); locked_vm.base.cpus.extend(::init_vcpu( vm.clone(), diff --git a/machine/src/x86_64/standard.rs b/machine/src/x86_64/standard.rs index 790e542..3aac836 100644 --- a/machine/src/x86_64/standard.rs +++ b/machine/src/x86_64/standard.rs @@ -371,7 +371,7 @@ impl StdMachineOps for StdMachine { hypervisor, self.base.cpu_topo.max_cpus, )?; - vcpu.realize(boot_cfg, topology).with_context(|| { + vcpu.realize(&Some(boot_cfg), topology).with_context(|| { format!( "Failed to realize arch cpu register/features for CPU {}", vcpu_id @@ -559,7 +559,12 @@ impl MachineOps for StdMachine { locked_vm.add_devices(vm_config)?; let fwcfg = locked_vm.add_fwcfg_device(nr_cpus, max_cpus)?; - let boot_config = locked_vm.load_boot_source(fwcfg.as_ref())?; + let migrate = locked_vm.get_migrate_info(); + let boot_config = if migrate.0 == MigrateMode::Unknown { + Some(locked_vm.load_boot_source(fwcfg.as_ref())?) + } else { + None + }; let topology = CPUTopology::new().set_topology(( vm_config.machine_config.nr_threads, vm_config.machine_config.nr_cores, @@ -575,7 +580,9 @@ impl MachineOps for StdMachine { &boot_config, )?); - locked_vm.init_cpu_controller(boot_config, topology, vm.clone())?; + if migrate.0 == MigrateMode::Unknown { + locked_vm.init_cpu_controller(boot_config.unwrap(), topology, vm.clone())?; + } if let Some(fw_cfg) = fwcfg { locked_vm -- 2.33.0