diff --git a/hypervisor/src/arch/x86/mod.rs b/hypervisor/src/arch/x86/mod.rs index 78e4d7cc5..45f820cde 100644 --- a/hypervisor/src/arch/x86/mod.rs +++ b/hypervisor/src/arch/x86/mod.rs @@ -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; diff --git a/hypervisor/src/arch/x86/msr_index.rs b/hypervisor/src/arch/x86/msr_index.rs index 810fe08b9..607ee3b2c 100644 --- a/hypervisor/src/arch/x86/msr_index.rs +++ b/hypervisor/src/arch/x86/msr_index.rs @@ -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; diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index d18785fd9..8b21002d1 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -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 { - 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) } }