mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm, hypervisor: Fix snapshot/restore for Windows guest
The snasphot/restore feature is not working because some CPU states are not properly saved, which means they can't be restored later on. First thing, we ensure the CPUID is stored so that it can be properly restored later. The code is simplified and pushed down to the hypervisor crate. Second thing, we identify for each vCPU if the Hyper-V SynIC device is emulated or not. In case it is, that means some specific MSRs will be set by the guest. These MSRs must be saved in order to properly restore the VM. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
committed by
Rob Bradford
parent
700f63fad8
commit
28e12e9f3a
@@ -26,9 +26,9 @@ use anyhow::anyhow;
|
||||
use arch::layout;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use arch::x86_64::SgxEpcSection;
|
||||
use arch::EntryPoint;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use arch::{CpuidPatch, CpuidReg};
|
||||
use arch::CpuidPatch;
|
||||
use arch::EntryPoint;
|
||||
use devices::interrupt_controller::InterruptController;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use hypervisor::kvm::kvm_bindings;
|
||||
@@ -688,19 +688,6 @@ impl CpuManager {
|
||||
let vcpu = Vcpu::new(cpu_id, &self.vm, interrupt_controller)?;
|
||||
|
||||
if let Some(snapshot) = snapshot {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
let mut cpuid = self.cpuid.clone();
|
||||
CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(cpu_id));
|
||||
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(cpu_id));
|
||||
|
||||
vcpu.lock()
|
||||
.unwrap()
|
||||
.vcpu
|
||||
.set_cpuid2(&cpuid)
|
||||
.map_err(|e| Error::SetSupportedCpusFailed(e.into()))?;
|
||||
}
|
||||
|
||||
// AArch64 vCPUs should be initialized after created.
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
vcpu.lock().unwrap().init(&self.vm)?;
|
||||
|
||||
@@ -183,6 +183,7 @@ fn create_vmm_ioctl_seccomp_rule_common() -> Result<Vec<SeccompRule>, Error> {
|
||||
fn create_vmm_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, Error> {
|
||||
const KVM_CREATE_PIT2: u64 = 0x4040_ae77;
|
||||
const KVM_GET_CLOCK: u64 = 0x8030_ae7c;
|
||||
const KVM_GET_CPUID2: u64 = 0xc008_ae91;
|
||||
const KVM_GET_FPU: u64 = 0x81a0_ae8c;
|
||||
const KVM_GET_LAPIC: u64 = 0x8400_ae8e;
|
||||
const KVM_GET_MSR_INDEX_LIST: u64 = 0xc004_ae02;
|
||||
@@ -205,6 +206,7 @@ fn create_vmm_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, Error> {
|
||||
let mut arch_rules = or![
|
||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_CREATE_PIT2)?],
|
||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_CLOCK,)?],
|
||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_CPUID2,)?],
|
||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_FPU)?],
|
||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_LAPIC)?],
|
||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_MSR_INDEX_LIST)?],
|
||||
|
||||
Reference in New Issue
Block a user