mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: kvm/x86_64: get and set nested guest state
Since the functionality of [0] was backported to kvm-bindings@v0.12.1 and kvm-ioctls@v0.22.1 [1, 2], we can now save nested KVM state. This way, nesting works across state save/resume and live-migration. [0] https://github.com/rust-vmm/kvm/pull/322 [1] https://github.com/rust-vmm/kvm/pull/349 [2] https://github.com/rust-vmm/kvm/pull/350 Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de> On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
4c16285dde
commit
690741de13
@@ -86,6 +86,8 @@ use std::mem;
|
||||
///
|
||||
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
|
||||
pub use kvm_bindings::kvm_vcpu_events as VcpuEvents;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use kvm_bindings::nested::KvmNestedStateBuffer;
|
||||
pub use kvm_bindings::{
|
||||
KVM_GUESTDBG_ENABLE, KVM_GUESTDBG_SINGLESTEP, KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
|
||||
KVM_MEM_LOG_DIRTY_PAGES, KVM_MEM_READONLY, KVM_MSI_VALID_DEVID, kvm_clock_data,
|
||||
@@ -2442,6 +2444,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
let xcrs = self.get_xcrs()?;
|
||||
let lapic_state = self.get_lapic()?;
|
||||
let fpu = self.get_fpu()?;
|
||||
let nested_state = self.nested_state()?;
|
||||
|
||||
// Try to get all MSRs based on the list previously retrieved from KVM.
|
||||
// If the number of MSRs obtained from GET_MSRS is different from the
|
||||
@@ -2516,6 +2519,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
xcrs,
|
||||
mp_state,
|
||||
tsc_khz,
|
||||
nested_state,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
@@ -2683,6 +2687,9 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
self.set_xcrs(&state.xcrs)?;
|
||||
self.set_lapic(&state.lapic_state)?;
|
||||
self.set_fpu(&state.fpu)?;
|
||||
if let Some(nested_state) = state.nested_state {
|
||||
self.set_nested_state(&nested_state)?;
|
||||
}
|
||||
|
||||
if let Some(freq) = state.tsc_khz {
|
||||
self.set_tsc_khz(freq)?;
|
||||
@@ -3036,6 +3043,36 @@ impl KvmVcpu {
|
||||
.set_vcpu_events(events)
|
||||
.map_err(|e| cpu::HypervisorCpuError::SetVcpuEvents(e.into()))
|
||||
}
|
||||
|
||||
/// Get the state of the nested guest from the current vCPU,
|
||||
/// if there is any.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn nested_state(&self) -> cpu::Result<Option<KvmNestedStateBuffer>> {
|
||||
let mut buffer = KvmNestedStateBuffer::empty();
|
||||
|
||||
let maybe_size = self
|
||||
.fd
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get_nested_state(&mut buffer)
|
||||
.map_err(|e| cpu::HypervisorCpuError::GetNestedState(e.into()))?;
|
||||
|
||||
if let Some(_size) = maybe_size {
|
||||
Ok(Some(buffer))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the state of the nested guest for the current vCPU.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn set_nested_state(&self, state: &KvmNestedStateBuffer) -> cpu::Result<()> {
|
||||
self.fd
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_nested_state(state)
|
||||
.map_err(|e| cpu::HypervisorCpuError::GetNestedState(e.into()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user