Skip to content

Commit 0ee10bb

Browse files
committed
refactor: move arch specific KVM code into modules
Follow up of the refactoring we did in the past around vstate/vm.rs, where we separate architecture specific code in modules, keeping only the arch-independent code in 'kvm/mod.rs'. No functional changes intended. Signed-off-by: Babis Chalios <[email protected]>
1 parent 83a9a55 commit 0ee10bb

File tree

3 files changed

+153
-104
lines changed

3 files changed

+153
-104
lines changed

src/vmm/src/vstate/kvm/aarch64.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use std::convert::Infallible;
5+
6+
use kvm_ioctls::Kvm as KvmFd;
7+
8+
use crate::cpu_config::templates::KvmCapability;
9+
10+
/// ['Kvm'] initialization can't fail for Aarch64
11+
pub type KvmArchError = Infallible;
12+
13+
/// Errors associated with the wrappers over KVM ioctls.
14+
/// Needs `rustfmt::skip` to make multiline comments work
15+
/// Optional capabilities.
16+
#[derive(Debug, Default)]
17+
pub struct OptionalCapabilities {
18+
/// KVM_CAP_COUNTER_OFFSET
19+
pub counter_offset: bool,
20+
}
21+
22+
/// Struct with kvm fd and kvm associated parameters.
23+
#[derive(Debug)]
24+
pub struct Kvm {
25+
/// KVM fd.
26+
pub fd: KvmFd,
27+
/// Maximum number of memory slots allowed by KVM.
28+
pub max_memslots: usize,
29+
/// Additional capabilities that were specified in cpu template.
30+
pub kvm_cap_modifiers: Vec<KvmCapability>,
31+
}
32+
33+
impl Kvm {
34+
pub(crate) const DEFAULT_CAPABILITIES: [u32; 7] = [
35+
kvm_bindings::KVM_CAP_IOEVENTFD,
36+
kvm_bindings::KVM_CAP_IRQFD,
37+
kvm_bindings::KVM_CAP_USER_MEMORY,
38+
kvm_bindings::KVM_CAP_ARM_PSCI_0_2,
39+
kvm_bindings::KVM_CAP_DEVICE_CTRL,
40+
kvm_bindings::KVM_CAP_MP_STATE,
41+
kvm_bindings::KVM_CAP_ONE_REG,
42+
];
43+
44+
/// Initialize [`Kvm`] type for Aarch64 architecture
45+
pub fn init_arch(
46+
fd: KvmFd,
47+
max_memslots: usize,
48+
kvm_cap_modifiers: Vec<KvmCapability>,
49+
) -> Result<Self, KvmArchError> {
50+
Ok(Self {
51+
fd,
52+
max_memslots,
53+
kvm_cap_modifiers,
54+
})
55+
}
56+
57+
/// Returns struct with optional capabilities statuses.
58+
pub fn optional_capabilities(&self) -> OptionalCapabilities {
59+
OptionalCapabilities {
60+
counter_offset: self
61+
.fd
62+
.check_extension_raw(kvm_bindings::KVM_CAP_COUNTER_OFFSET.into())
63+
!= 0,
64+
}
65+
}
66+
}

src/vmm/src/vstate/kvm.rs renamed to src/vmm/src/vstate/kvm/mod.rs

Lines changed: 13 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,22 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use kvm_bindings::KVM_API_VERSION;
5-
#[cfg(target_arch = "x86_64")]
6-
use kvm_bindings::{CpuId, KVM_MAX_CPUID_ENTRIES, MsrList};
75
use kvm_ioctls::Kvm as KvmFd;
86
use serde::{Deserialize, Serialize};
97

10-
#[cfg(target_arch = "x86_64")]
11-
use crate::arch::x86_64::xstate::{XstateError, request_dynamic_xstate_features};
128
use crate::cpu_config::templates::KvmCapability;
139
use crate::vstate::memory::{GuestMemory, GuestMemoryMmap};
1410

11+
#[cfg(target_arch = "aarch64")]
12+
mod aarch64;
13+
#[cfg(target_arch = "x86_64")]
14+
mod x86_64;
15+
16+
#[cfg(target_arch = "aarch64")]
17+
pub use aarch64::{Kvm, KvmArchError, OptionalCapabilities};
18+
#[cfg(target_arch = "x86_64")]
19+
pub use x86_64::{Kvm, KvmArchError};
20+
1521
/// Errors associated with the wrappers over KVM ioctls.
1622
/// Needs `rustfmt::skip` to make multiline comments work
1723
#[rustfmt::skip]
@@ -24,29 +30,10 @@ pub enum KvmError {
2430
/** Error creating KVM object: {0} Make sure the user launching the firecracker process is \
2531
configured on the /dev/kvm file's ACL. */
2632
Kvm(kvm_ioctls::Error),
27-
#[cfg(target_arch = "x86_64")]
28-
/// Failed to get supported cpuid: {0}
29-
GetSupportedCpuId(kvm_ioctls::Error),
3033
/// The number of configured slots is bigger than the maximum reported by KVM
3134
NotEnoughMemorySlots,
32-
#[cfg(target_arch = "x86_64")]
33-
/// Failed to request permission for dynamic XSTATE features: {0}
34-
XstateFeatures(XstateError),
35-
}
36-
37-
/// Struct with kvm fd and kvm associated paramenters.
38-
#[derive(Debug)]
39-
pub struct Kvm {
40-
/// KVM fd.
41-
pub fd: KvmFd,
42-
/// Maximum number of memory slots allowed by KVM.
43-
pub max_memslots: usize,
44-
/// Additional capabilities that were specified in cpu template.
45-
pub kvm_cap_modifiers: Vec<KvmCapability>,
46-
47-
#[cfg(target_arch = "x86_64")]
48-
/// Supported CpuIds.
49-
pub supported_cpuid: CpuId,
35+
/// Architecture specific error: {0}
36+
ArchError(#[from] KvmArchError)
5037
}
5138

5239
impl Kvm {
@@ -67,36 +54,7 @@ impl Kvm {
6754

6855
let max_memslots = kvm_fd.get_nr_memslots();
6956

70-
#[cfg(target_arch = "aarch64")]
71-
{
72-
Ok(Self {
73-
fd: kvm_fd,
74-
max_memslots,
75-
kvm_cap_modifiers,
76-
})
77-
}
78-
79-
#[cfg(target_arch = "x86_64")]
80-
{
81-
request_dynamic_xstate_features().map_err(KvmError::XstateFeatures)?;
82-
83-
let supported_cpuid = kvm_fd
84-
.get_supported_cpuid(KVM_MAX_CPUID_ENTRIES)
85-
.map_err(KvmError::GetSupportedCpuId)?;
86-
87-
Ok(Kvm {
88-
fd: kvm_fd,
89-
max_memslots,
90-
kvm_cap_modifiers,
91-
supported_cpuid,
92-
})
93-
}
94-
}
95-
96-
/// Msrs needed to be saved on snapshot creation.
97-
#[cfg(target_arch = "x86_64")]
98-
pub fn msrs_to_save(&self) -> Result<MsrList, crate::arch::x86_64::msr::MsrError> {
99-
crate::arch::x86_64::msr::get_msrs_to_save(&self.fd)
57+
Ok(Kvm::init_arch(kvm_fd, max_memslots, kvm_cap_modifiers)?)
10058
}
10159

10260
/// Check guest memory does not have more regions than kvm allows.
@@ -144,55 +102,6 @@ impl Kvm {
144102
}
145103
}
146104
}
147-
#[cfg(target_arch = "aarch64")]
148-
/// Optional capabilities.
149-
#[derive(Debug, Default)]
150-
pub struct OptionalCapabilities {
151-
/// KVM_CAP_COUNTER_OFFSET
152-
pub counter_offset: bool,
153-
}
154-
#[cfg(target_arch = "aarch64")]
155-
impl Kvm {
156-
const DEFAULT_CAPABILITIES: [u32; 7] = [
157-
kvm_bindings::KVM_CAP_IOEVENTFD,
158-
kvm_bindings::KVM_CAP_IRQFD,
159-
kvm_bindings::KVM_CAP_USER_MEMORY,
160-
kvm_bindings::KVM_CAP_ARM_PSCI_0_2,
161-
kvm_bindings::KVM_CAP_DEVICE_CTRL,
162-
kvm_bindings::KVM_CAP_MP_STATE,
163-
kvm_bindings::KVM_CAP_ONE_REG,
164-
];
165-
166-
/// Returns struct with optional capabilities statuses.
167-
pub fn optional_capabilities(&self) -> OptionalCapabilities {
168-
OptionalCapabilities {
169-
counter_offset: self
170-
.fd
171-
.check_extension_raw(kvm_bindings::KVM_CAP_COUNTER_OFFSET.into())
172-
!= 0,
173-
}
174-
}
175-
}
176-
177-
#[cfg(target_arch = "x86_64")]
178-
impl Kvm {
179-
const DEFAULT_CAPABILITIES: [u32; 14] = [
180-
kvm_bindings::KVM_CAP_IRQCHIP,
181-
kvm_bindings::KVM_CAP_IOEVENTFD,
182-
kvm_bindings::KVM_CAP_IRQFD,
183-
kvm_bindings::KVM_CAP_USER_MEMORY,
184-
kvm_bindings::KVM_CAP_SET_TSS_ADDR,
185-
kvm_bindings::KVM_CAP_PIT2,
186-
kvm_bindings::KVM_CAP_PIT_STATE2,
187-
kvm_bindings::KVM_CAP_ADJUST_CLOCK,
188-
kvm_bindings::KVM_CAP_DEBUGREGS,
189-
kvm_bindings::KVM_CAP_MP_STATE,
190-
kvm_bindings::KVM_CAP_VCPU_EVENTS,
191-
kvm_bindings::KVM_CAP_XCRS,
192-
kvm_bindings::KVM_CAP_XSAVE,
193-
kvm_bindings::KVM_CAP_EXT_CPUID,
194-
];
195-
}
196105

197106
/// Structure holding an general specific VM state.
198107
#[derive(Debug, Default, Serialize, Deserialize)]

src/vmm/src/vstate/kvm/x86_64.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use kvm_bindings::{CpuId, KVM_MAX_CPUID_ENTRIES, MsrList};
5+
use kvm_ioctls::Kvm as KvmFd;
6+
7+
use crate::arch::x86_64::xstate::{XstateError, request_dynamic_xstate_features};
8+
use crate::cpu_config::templates::KvmCapability;
9+
10+
/// Architecture specific error for KVM initialization
11+
#[derive(Debug, thiserror::Error, displaydoc::Display)]
12+
pub 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)]
21+
pub struct Kvm {
22+
/// KVM fd.
23+
pub fd: KvmFd,
24+
/// Maximum number of memory slots allowed by KVM.
25+
pub max_memslots: usize,
26+
/// Additional capabilities that were specified in cpu template.
27+
pub kvm_cap_modifiers: Vec<KvmCapability>,
28+
/// Supported CpuIds.
29+
pub supported_cpuid: CpuId,
30+
}
31+
32+
impl Kvm {
33+
pub(crate) const DEFAULT_CAPABILITIES: [u32; 14] = [
34+
kvm_bindings::KVM_CAP_IRQCHIP,
35+
kvm_bindings::KVM_CAP_IOEVENTFD,
36+
kvm_bindings::KVM_CAP_IRQFD,
37+
kvm_bindings::KVM_CAP_USER_MEMORY,
38+
kvm_bindings::KVM_CAP_SET_TSS_ADDR,
39+
kvm_bindings::KVM_CAP_PIT2,
40+
kvm_bindings::KVM_CAP_PIT_STATE2,
41+
kvm_bindings::KVM_CAP_ADJUST_CLOCK,
42+
kvm_bindings::KVM_CAP_DEBUGREGS,
43+
kvm_bindings::KVM_CAP_MP_STATE,
44+
kvm_bindings::KVM_CAP_VCPU_EVENTS,
45+
kvm_bindings::KVM_CAP_XCRS,
46+
kvm_bindings::KVM_CAP_XSAVE,
47+
kvm_bindings::KVM_CAP_EXT_CPUID,
48+
];
49+
50+
/// Initialize [`Kvm`] type for x86_64 architecture
51+
pub fn init_arch(
52+
fd: KvmFd,
53+
max_memslots: usize,
54+
kvm_cap_modifiers: Vec<KvmCapability>,
55+
) -> Result<Self, KvmArchError> {
56+
request_dynamic_xstate_features().map_err(KvmArchError::XstateFeatures)?;
57+
58+
let supported_cpuid = fd
59+
.get_supported_cpuid(KVM_MAX_CPUID_ENTRIES)
60+
.map_err(KvmArchError::GetSupportedCpuId)?;
61+
62+
Ok(Kvm {
63+
fd,
64+
max_memslots,
65+
kvm_cap_modifiers,
66+
supported_cpuid,
67+
})
68+
}
69+
70+
/// Msrs needed to be saved on snapshot creation.
71+
pub fn msrs_to_save(&self) -> Result<MsrList, crate::arch::x86_64::msr::MsrError> {
72+
crate::arch::x86_64::msr::get_msrs_to_save(&self.fd)
73+
}
74+
}

0 commit comments

Comments
 (0)