mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
hypervisor: Set destination vCPU TSC frequency to source
Include the TSC frequency as part of the KVM state so that it will be restored at the destination. This ensures migration works correctly between hosts that have a different TSC frequency if the guest is running with TSC as the source of timekeeping. Fixes: #5786 Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
This commit is contained in:
parent
18d8c5669f
commit
44f200d67d
@ -252,6 +252,11 @@ pub enum HypervisorCpuError {
|
||||
///
|
||||
#[error("Failed to get TSC frequency: {0}")]
|
||||
GetTscKhz(#[source] anyhow::Error),
|
||||
///
|
||||
/// Error setting TSC frequency
|
||||
///
|
||||
#[error("Failed to set TSC frequency: {0}")]
|
||||
SetTscKhz(#[source] anyhow::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -447,6 +452,7 @@ pub trait Vcpu: Send + Sync {
|
||||
/// Return the list of initial MSR entries for a VCPU
|
||||
///
|
||||
fn boot_msr_entries(&self) -> Vec<MsrEntry>;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Get the frequency of the TSC if available
|
||||
@ -454,4 +460,11 @@ pub trait Vcpu: Send + Sync {
|
||||
fn tsc_khz(&self) -> Result<Option<u32>> {
|
||||
Ok(None)
|
||||
}
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Set the frequency of the TSC if available
|
||||
///
|
||||
fn set_tsc_khz(&self, _freq: u32) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -1890,6 +1890,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
};
|
||||
|
||||
let vcpu_events = self.get_vcpu_events()?;
|
||||
let tsc_khz = self.tsc_khz()?;
|
||||
|
||||
Ok(VcpuKvmState {
|
||||
cpuid,
|
||||
@ -1902,6 +1903,7 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
xsave,
|
||||
xcrs,
|
||||
mp_state,
|
||||
tsc_khz,
|
||||
}
|
||||
.into())
|
||||
}
|
||||
@ -2004,6 +2006,10 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
self.set_lapic(&state.lapic_state)?;
|
||||
self.set_fpu(&state.fpu)?;
|
||||
|
||||
if let Some(freq) = state.tsc_khz {
|
||||
self.set_tsc_khz(freq)?;
|
||||
}
|
||||
|
||||
// Try to set all MSRs previously stored.
|
||||
// If the number of MSRs set from SET_MSRS is different from the
|
||||
// expected amount, we fallback onto a slower method by setting MSRs
|
||||
@ -2186,6 +2192,23 @@ impl cpu::Vcpu for KvmVcpu {
|
||||
Ok(v) => Ok(Some(v)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
///
|
||||
/// Set the frequency of the TSC if available
|
||||
///
|
||||
fn set_tsc_khz(&self, freq: u32) -> cpu::Result<()> {
|
||||
match self.fd.set_tsc_khz(freq) {
|
||||
Err(e) => {
|
||||
if e.errno() == libc::EIO {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(cpu::HypervisorCpuError::SetTscKhz(e.into()))
|
||||
}
|
||||
}
|
||||
Ok(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KvmVcpu {
|
||||
|
@ -67,6 +67,7 @@ pub struct VcpuKvmState {
|
||||
pub xsave: Xsave,
|
||||
pub xcrs: ExtendedControlRegisters,
|
||||
pub mp_state: MpState,
|
||||
pub tsc_khz: Option<u32>,
|
||||
}
|
||||
|
||||
impl From<StandardRegisters> for kvm_regs {
|
||||
|
@ -366,6 +366,7 @@ fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>
|
||||
const KVM_SET_LAPIC: u64 = 0x4400_ae8f;
|
||||
const KVM_SET_MSRS: u64 = 0x4008_ae89;
|
||||
const KVM_SET_SREGS: u64 = 0x4138_ae84;
|
||||
const KVM_SET_TSC_KHZ: u64 = 0xaea2;
|
||||
const KVM_SET_TSS_ADDR: u64 = 0xae47;
|
||||
const KVM_SET_XCRS: u64 = 0x4188_aea7;
|
||||
const KVM_SET_XSAVE: u64 = 0x5000_aea5;
|
||||
@ -392,6 +393,7 @@ fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_IDENTITY_MAP_ADDR)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_LAPIC)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_SREGS)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_TSC_KHZ)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_TSS_ADDR,)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_MSRS)?],
|
||||
and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_XCRS,)?],
|
||||
|
Loading…
Reference in New Issue
Block a user