303 lines
12 KiB
Diff
303 lines
12 KiB
Diff
|
|
From 3a5ef152b5e803998e6ec5a1e7172c01fcce8bcf Mon Sep 17 00:00:00 2001
|
||
|
|
From: l00484210 <l00484210@notesmail.huawei.com/>
|
||
|
|
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 <limingwang@huawei.com>
|
||
|
|
---
|
||
|
|
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<CPUBootConfig>,
|
||
|
|
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<CPUBootConfig>,
|
||
|
|
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<CPUBootConfig>,
|
||
|
|
#[cfg(target_arch = "aarch64")] vcpu_cfg: &CPUFeatures,
|
||
|
|
) -> Result<Vec<Arc<CPU>>>
|
||
|
|
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(<Self as MachineOps>::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
|
||
|
|
|