mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-27 23:23:09 +00:00
hypervisor: Store all supported MSRs
On x86 architecture, we need to save a list of MSRs as part of the vCPU state. By providing the full list of MSRs supported by KVM, this patch fixes the remaining snapshot/restore issues, as the vCPU is restored with all its previous states. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
49b4fba283
commit
e35d4c5b28
@ -26,8 +26,7 @@ pub mod x86_64;
|
|||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use x86_64::{
|
use x86_64::{
|
||||||
boot_msr_entries, check_required_kvm_extensions, FpuState, SpecialRegisters, StandardRegisters,
|
check_required_kvm_extensions, FpuState, SpecialRegisters, StandardRegisters, KVM_TSS_ADDRESS,
|
||||||
KVM_TSS_ADDRESS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -67,6 +66,8 @@ pub use {
|
|||||||
/// Wrapper over KVM VM ioctls.
|
/// Wrapper over KVM VM ioctls.
|
||||||
pub struct KvmVm {
|
pub struct KvmVm {
|
||||||
fd: Arc<VmFd>,
|
fd: Arc<VmFd>,
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
msrs: MsrEntries,
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
/// Implementation of Vm trait for KVM
|
/// Implementation of Vm trait for KVM
|
||||||
@ -120,7 +121,11 @@ impl vm::Vm for KvmVm {
|
|||||||
.fd
|
.fd
|
||||||
.create_vcpu(id)
|
.create_vcpu(id)
|
||||||
.map_err(|e| vm::HypervisorVmError::CreateVcpu(e.into()))?;
|
.map_err(|e| vm::HypervisorVmError::CreateVcpu(e.into()))?;
|
||||||
let vcpu = KvmVcpu { fd: vc };
|
let vcpu = KvmVcpu {
|
||||||
|
fd: vc,
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
msrs: self.msrs.clone(),
|
||||||
|
};
|
||||||
Ok(Arc::new(vcpu))
|
Ok(Arc::new(vcpu))
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
@ -262,11 +267,9 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
|||||||
/// let vm = hypervisor.create_vm().unwrap()
|
/// let vm = hypervisor.create_vm().unwrap()
|
||||||
///
|
///
|
||||||
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
|
fn create_vm(&self) -> hypervisor::Result<Arc<dyn vm::Vm>> {
|
||||||
let kvm = Kvm::new().map_err(|e| hypervisor::HypervisorError::VmCreate(e.into()))?;
|
|
||||||
|
|
||||||
let fd: VmFd;
|
let fd: VmFd;
|
||||||
loop {
|
loop {
|
||||||
match kvm.create_vm() {
|
match self.kvm.create_vm() {
|
||||||
Ok(res) => fd = res,
|
Ok(res) => fd = res,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.errno() == libc::EINTR {
|
if e.errno() == libc::EINTR {
|
||||||
@ -281,9 +284,27 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let vm_fd = Arc::new(fd);
|
let vm_fd = Arc::new(fd);
|
||||||
let kvm_fd = KvmVm { fd: vm_fd };
|
|
||||||
Ok(Arc::new(kvm_fd))
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
{
|
||||||
|
let msr_list = self.get_msr_list()?;
|
||||||
|
let num_msrs = msr_list.as_fam_struct_ref().nmsrs as usize;
|
||||||
|
let mut msrs = MsrEntries::new(num_msrs);
|
||||||
|
let indices = msr_list.as_slice();
|
||||||
|
let msr_entries = msrs.as_mut_slice();
|
||||||
|
for (pos, index) in indices.iter().enumerate() {
|
||||||
|
msr_entries[pos].index = *index;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Arc::new(KvmVm { fd: vm_fd, msrs }))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
|
||||||
|
{
|
||||||
|
Ok(Arc::new(KvmVm { fd: vm_fd }))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_required_extensions(&self) -> hypervisor::Result<()> {
|
fn check_required_extensions(&self) -> hypervisor::Result<()> {
|
||||||
@ -346,6 +367,8 @@ impl hypervisor::Hypervisor for KvmHypervisor {
|
|||||||
/// Vcpu struct for KVM
|
/// Vcpu struct for KVM
|
||||||
pub struct KvmVcpu {
|
pub struct KvmVcpu {
|
||||||
fd: VcpuFd,
|
fd: VcpuFd,
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
msrs: MsrEntries,
|
||||||
}
|
}
|
||||||
/// Implementation of Vcpu trait for KVM
|
/// Implementation of Vcpu trait for KVM
|
||||||
/// Example:
|
/// Example:
|
||||||
@ -625,7 +648,7 @@ impl cpu::Vcpu for KvmVcpu {
|
|||||||
let xcrs = self.get_xcrs()?;
|
let xcrs = self.get_xcrs()?;
|
||||||
let lapic_state = self.get_lapic()?;
|
let lapic_state = self.get_lapic()?;
|
||||||
let fpu = self.get_fpu()?;
|
let fpu = self.get_fpu()?;
|
||||||
let mut msrs = boot_msr_entries();
|
let mut msrs = self.msrs.clone();
|
||||||
self.get_msrs(&mut msrs)?;
|
self.get_msrs(&mut msrs)?;
|
||||||
let vcpu_events = self.get_vcpu_events()?;
|
let vcpu_events = self.get_vcpu_events()?;
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ const KVM_GET_XCRS: u64 = 0x8188_aea6;
|
|||||||
const KVM_GET_FPU: u64 = 0x81a0_ae8c;
|
const KVM_GET_FPU: u64 = 0x81a0_ae8c;
|
||||||
const KVM_GET_LAPIC: u64 = 0x8400_ae8e;
|
const KVM_GET_LAPIC: u64 = 0x8400_ae8e;
|
||||||
const KVM_GET_XSAVE: u64 = 0x9000_aea4;
|
const KVM_GET_XSAVE: u64 = 0x9000_aea4;
|
||||||
|
const KVM_GET_MSR_INDEX_LIST: u64 = 0xc004_ae02;
|
||||||
const KVM_GET_SUPPORTED_CPUID: u64 = 0xc008_ae05;
|
const KVM_GET_SUPPORTED_CPUID: u64 = 0xc008_ae05;
|
||||||
const KVM_GET_MSRS: u64 = 0xc008_ae88;
|
const KVM_GET_MSRS: u64 = 0xc008_ae88;
|
||||||
const KVM_CREATE_DEVICE: u64 = 0xc00c_aee0;
|
const KVM_CREATE_DEVICE: u64 = 0xc00c_aee0;
|
||||||
@ -131,6 +132,7 @@ fn create_vmm_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, Error> {
|
|||||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_FPU)?],
|
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_LAPIC)?],
|
||||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_MP_STATE)?],
|
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_MP_STATE)?],
|
||||||
|
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_MSR_INDEX_LIST)?],
|
||||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_MSRS)?],
|
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_MSRS)?],
|
||||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_REGS)?],
|
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_REGS)?],
|
||||||
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_SREGS)?],
|
and![Cond::new(1, ArgLen::DWORD, Eq, KVM_GET_SREGS)?],
|
||||||
|
Loading…
Reference in New Issue
Block a user