vmm/arch/x86_64/
kvm.rs

1// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use 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/// Architecture specific error for KVM initialization
11#[derive(Debug, thiserror::Error, displaydoc::Display)]
12pub enum KvmArchError {
13    /// Failed to get supported cpuid: {0}
14    GetSupportedCpuId(kvm_ioctls::Error),
15    /// Failed to request permission for dynamic XSTATE features: {0}
16    XstateFeatures(XstateError),
17}
18
19/// Struct with kvm fd and kvm associated parameters.
20#[derive(Debug)]
21pub struct Kvm {
22    /// KVM fd.
23    pub fd: KvmFd,
24    /// Additional capabilities that were specified in cpu template.
25    pub kvm_cap_modifiers: Vec<KvmCapability>,
26    /// Supported CpuIds.
27    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    /// Initialize [`Kvm`] type for x86_64 architecture
49    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    /// Msrs needed to be saved on snapshot creation.
67    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}