// Copyright © 2019 Intel Corporation // // SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause // // Copyright © 2020, Microsoft Corporation // // Copyright 2018-2019 CrowdStrike, Inc. // // use vm_memory::GuestAddress; use crate::arch::x86::{msr_index, MTRR_ENABLE, MTRR_MEM_TYPE_WB}; use crate::kvm::{Cap, Kvm, KvmError, KvmResult}; use serde_derive::{Deserialize, Serialize}; /// /// Export generically-named wrappers of kvm-bindings for Unix-based platforms /// pub use { kvm_bindings::kvm_dtable as DescriptorTable, kvm_bindings::kvm_fpu as FpuState, kvm_bindings::kvm_lapic_state as LapicState, kvm_bindings::kvm_mp_state as MpState, kvm_bindings::kvm_msr_entry as MsrEntry, kvm_bindings::kvm_regs as StandardRegisters, kvm_bindings::kvm_segment as SegmentRegister, kvm_bindings::kvm_sregs as SpecialRegisters, kvm_bindings::kvm_vcpu_events as VcpuEvents, kvm_bindings::kvm_xcrs as ExtendedControlRegisters, kvm_bindings::kvm_xsave as Xsave, kvm_bindings::CpuId, kvm_bindings::MsrList, kvm_bindings::Msrs as MsrEntries, }; pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffb_d000); macro_rules! msr { ($msr:expr) => { MsrEntry { index: $msr, data: 0x0, ..Default::default() } }; } macro_rules! msr_data { ($msr:expr, $data:expr) => { MsrEntry { index: $msr, data: $data, ..Default::default() } }; } pub fn boot_msr_entries() -> MsrEntries { MsrEntries::from_entries(&[ msr!(msr_index::MSR_IA32_SYSENTER_CS), msr!(msr_index::MSR_IA32_SYSENTER_ESP), msr!(msr_index::MSR_IA32_SYSENTER_EIP), msr!(msr_index::MSR_STAR), msr!(msr_index::MSR_CSTAR), msr!(msr_index::MSR_LSTAR), msr!(msr_index::MSR_KERNEL_GS_BASE), msr!(msr_index::MSR_SYSCALL_MASK), msr!(msr_index::MSR_IA32_TSC), msr_data!( msr_index::MSR_IA32_MISC_ENABLE, msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64 ), msr_data!(msr_index::MSR_MTRRdefType, MTRR_ENABLE | MTRR_MEM_TYPE_WB), ]) } /// /// Check KVM extension for Linux /// pub fn check_required_kvm_extensions(kvm: &Kvm) -> KvmResult<()> { if !kvm.check_extension(Cap::SignalMsi) { return Err(KvmError::CapabilityMissing(Cap::SignalMsi)); } if !kvm.check_extension(Cap::TscDeadlineTimer) { return Err(KvmError::CapabilityMissing(Cap::TscDeadlineTimer)); } if !kvm.check_extension(Cap::SplitIrqchip) { return Err(KvmError::CapabilityMissing(Cap::SplitIrqchip)); } Ok(()) } #[derive(Clone, Serialize, Deserialize)] pub struct VcpuKvmState { pub msrs: MsrEntries, pub vcpu_events: VcpuEvents, pub regs: StandardRegisters, pub sregs: SpecialRegisters, pub fpu: FpuState, pub lapic_state: LapicState, pub xsave: Xsave, pub xcrs: ExtendedControlRegisters, pub mp_state: MpState, }