mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
hypervisor: kvm: preserve guest MTRR MSRs
KVM_GET_MSR_INDEX_LIST does not consistently include all guest-programmable MTRR MSRs. During save/restore while booting, the VMM initially sets only MSR_MTRRdefType, then guest firmware or other early boot code can program additional MTRR state before the snapshot is taken. If those MSRs are missing from the vCPU MSR buffer, snapshot omits part of the guest's MTRR configuration and restore resumes with an incomplete MTRR map. Add the guest-programmable MTRR MSRs to the KVM MSR index list used to build the vCPU MSR buffer so the existing snapshot/restore path preserves the guest's MTRR state. On-behalf-of: SAP leander.kohler@sap.com Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
This commit is contained in:
@@ -28,6 +28,36 @@ pub mod msr_index;
|
||||
// MTRR constants
|
||||
pub const MTRR_ENABLE: u64 = 0x800; // IA32_MTRR_DEF_TYPE MSR: E (MTRRs enabled) flag, bit 11
|
||||
pub const MTRR_MEM_TYPE_WB: u64 = 0x6;
|
||||
pub const MTRR_MSR_INDICES: [u32; 28] = [
|
||||
msr_index::MSR_MTRRdefType,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE0,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK0,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE1,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK1,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE2,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK2,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE3,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK3,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE4,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK4,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE5,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK5,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE6,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK6,
|
||||
msr_index::MSR_IA32_MTRR_PHYSBASE7,
|
||||
msr_index::MSR_IA32_MTRR_PHYSMASK7,
|
||||
msr_index::MSR_MTRRfix64K_00000,
|
||||
msr_index::MSR_MTRRfix16K_80000,
|
||||
msr_index::MSR_MTRRfix16K_A0000,
|
||||
msr_index::MSR_MTRRfix4K_C0000,
|
||||
msr_index::MSR_MTRRfix4K_C8000,
|
||||
msr_index::MSR_MTRRfix4K_D0000,
|
||||
msr_index::MSR_MTRRfix4K_D8000,
|
||||
msr_index::MSR_MTRRfix4K_E0000,
|
||||
msr_index::MSR_MTRRfix4K_E8000,
|
||||
msr_index::MSR_MTRRfix4K_F0000,
|
||||
msr_index::MSR_MTRRfix4K_F8000,
|
||||
];
|
||||
|
||||
// IOAPIC pins
|
||||
pub const NUM_IOAPIC_PINS: usize = 24;
|
||||
|
||||
@@ -85,6 +85,22 @@ pub const MSR_IA32_RTIT_ADDR3_B: ::std::os::raw::c_uint = 0x00000587;
|
||||
pub const MSR_IA32_RTIT_CR3_MATCH: ::std::os::raw::c_uint = 0x00000572;
|
||||
pub const MSR_IA32_RTIT_OUTPUT_BASE: ::std::os::raw::c_uint = 0x00000560;
|
||||
pub const MSR_IA32_RTIT_OUTPUT_MASK: ::std::os::raw::c_uint = 0x00000561;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE0: ::std::os::raw::c_uint = 0x00000200;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK0: ::std::os::raw::c_uint = 0x00000201;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE1: ::std::os::raw::c_uint = 0x00000202;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK1: ::std::os::raw::c_uint = 0x00000203;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE2: ::std::os::raw::c_uint = 0x00000204;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK2: ::std::os::raw::c_uint = 0x00000205;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE3: ::std::os::raw::c_uint = 0x00000206;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK3: ::std::os::raw::c_uint = 0x00000207;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE4: ::std::os::raw::c_uint = 0x00000208;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK4: ::std::os::raw::c_uint = 0x00000209;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE5: ::std::os::raw::c_uint = 0x0000020a;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK5: ::std::os::raw::c_uint = 0x0000020b;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE6: ::std::os::raw::c_uint = 0x0000020c;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK6: ::std::os::raw::c_uint = 0x0000020d;
|
||||
pub const MSR_IA32_MTRR_PHYSBASE7: ::std::os::raw::c_uint = 0x0000020e;
|
||||
pub const MSR_IA32_MTRR_PHYSMASK7: ::std::os::raw::c_uint = 0x0000020f;
|
||||
pub const MSR_MTRRfix64K_00000: ::std::os::raw::c_uint = 0x00000250;
|
||||
pub const MSR_MTRRfix16K_80000: ::std::os::raw::c_uint = 0x00000258;
|
||||
pub const MSR_MTRRfix16K_A0000: ::std::os::raw::c_uint = 0x00000259;
|
||||
|
||||
@@ -70,7 +70,8 @@ pub use x86_64::{CpuId, ExtendedControlRegisters, MsrEntries, VcpuKvmState};
|
||||
use crate::ClockData;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use crate::arch::x86::{
|
||||
CpuIdEntry, FpuState, LapicState, MsrEntry, NUM_IOAPIC_PINS, SpecialRegisters, XsaveState,
|
||||
CpuIdEntry, FpuState, LapicState, MTRR_MSR_INDICES, MsrEntry, NUM_IOAPIC_PINS,
|
||||
SpecialRegisters, XsaveState,
|
||||
};
|
||||
use crate::{CpuState, IoEventAddress, IrqRoutingEntry, MpState, StandardRegisters};
|
||||
// aarch64 dependencies
|
||||
@@ -1128,9 +1129,21 @@ impl KvmHypervisor {
|
||||
/// Retrieve the list of MSRs supported by the hypervisor.
|
||||
///
|
||||
fn get_msr_list(&self) -> hypervisor::Result<MsrList> {
|
||||
self.kvm
|
||||
let mut indices = self
|
||||
.kvm
|
||||
.get_msr_index_list()
|
||||
.map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into()))
|
||||
.map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into()))?
|
||||
.as_slice()
|
||||
.to_vec();
|
||||
|
||||
// KVM_GET_MSR_INDEX_LIST does not include MTRR MSRs, but firmware may update them before an early boot snapshot.
|
||||
indices.extend(MTRR_MSR_INDICES);
|
||||
|
||||
let mut msr_list = MsrList::new(indices.len())
|
||||
.map_err(|e| hypervisor::HypervisorError::GetMsrList(e.into()))?;
|
||||
msr_list.as_mut_slice().copy_from_slice(&indices);
|
||||
|
||||
Ok(msr_list)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user