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