1use kvm_bindings::{CpuId, KVM_MAX_CPUID_ENTRIES, MsrList};
5use kvm_ioctls::Kvm as KvmFd;
6
7use crate::arch::x86_64::xstate::{XstateError, request_dynamic_xstate_features};
8use crate::cpu_config::templates::KvmCapability;
9
10#[derive(Debug, thiserror::Error, displaydoc::Display)]
12pub enum KvmArchError {
13 GetSupportedCpuId(kvm_ioctls::Error),
15 XstateFeatures(XstateError),
17}
18
19#[derive(Debug)]
21pub struct Kvm {
22 pub fd: KvmFd,
24 pub kvm_cap_modifiers: Vec<KvmCapability>,
26 pub supported_cpuid: CpuId,
28}
29
30impl Kvm {
31 pub(crate) const DEFAULT_CAPABILITIES: [u32; 14] = [
32 kvm_bindings::KVM_CAP_IRQCHIP,
33 kvm_bindings::KVM_CAP_IOEVENTFD,
34 kvm_bindings::KVM_CAP_IRQFD,
35 kvm_bindings::KVM_CAP_USER_MEMORY,
36 kvm_bindings::KVM_CAP_SET_TSS_ADDR,
37 kvm_bindings::KVM_CAP_PIT2,
38 kvm_bindings::KVM_CAP_PIT_STATE2,
39 kvm_bindings::KVM_CAP_ADJUST_CLOCK,
40 kvm_bindings::KVM_CAP_DEBUGREGS,
41 kvm_bindings::KVM_CAP_MP_STATE,
42 kvm_bindings::KVM_CAP_VCPU_EVENTS,
43 kvm_bindings::KVM_CAP_XCRS,
44 kvm_bindings::KVM_CAP_XSAVE,
45 kvm_bindings::KVM_CAP_EXT_CPUID,
46 ];
47
48 pub fn init_arch(
50 fd: KvmFd,
51 kvm_cap_modifiers: Vec<KvmCapability>,
52 ) -> Result<Self, KvmArchError> {
53 request_dynamic_xstate_features().map_err(KvmArchError::XstateFeatures)?;
54
55 let supported_cpuid = fd
56 .get_supported_cpuid(KVM_MAX_CPUID_ENTRIES)
57 .map_err(KvmArchError::GetSupportedCpuId)?;
58
59 Ok(Kvm {
60 fd,
61 kvm_cap_modifiers,
62 supported_cpuid,
63 })
64 }
65
66 pub fn msrs_to_save(&self) -> Result<MsrList, crate::arch::x86_64::msr::MsrError> {
68 crate::arch::x86_64::msr::get_msrs_to_save(&self.fd)
69 }
70}