Skip to content

Commit c2488bf

Browse files
committed
refactor(vmm): move MSR modification for linux boot
Move MSR modification to boot linux from `CpuConfiguration::host()` to `KvmVcpu::configure()`. As CPUID modification is applied in `KvmVcpu::configure()` already, putting MSR modification in the same place is sensible. In addition, with this change, there is no need to contain `msrs_to_save` and `msr_boot_entries` in `CpuConfiguration`. Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent 6c0534c commit c2488bf

File tree

4 files changed

+33
-74
lines changed

4 files changed

+33
-74
lines changed

src/vmm/src/guest_config/x86_64/mod.rs

Lines changed: 4 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,14 @@
44
/// Module with CPU templates for x86_64
55
pub mod static_cpu_templates;
66

7-
use std::collections::{HashMap, HashSet};
7+
use std::collections::HashMap;
88

9-
use kvm_bindings::kvm_msr_entry;
109
use static_cpu_templates::*;
1110

1211
use super::cpuid::{CpuidKey, RawCpuid};
1312
use super::templates::x86_64::CpuidRegister;
1413
use super::templates::{CpuTemplateType, CustomCpuTemplate};
15-
use crate::arch::x86_64::msr::create_boot_msr_entries;
1614
use crate::guest_config::cpuid::Cpuid;
17-
use crate::vstate::vcpu::msr_entries_to_save;
1815
use crate::vstate::vm::Vm;
1916

2017
/// Errors thrown while configuring templates.
@@ -43,12 +40,6 @@ pub struct CpuConfiguration {
4340
/// Key: MSR address
4441
/// Value: MSR value
4542
pub msrs: HashMap<u32, u64>,
46-
47-
/// Set of supported MSRs
48-
pub msrs_to_save: HashSet<u32>,
49-
50-
/// Architectural MSPs required for boot
51-
pub msr_boot_entries: Vec<kvm_msr_entry>,
5243
}
5344

5445
impl CpuConfiguration {
@@ -69,8 +60,6 @@ impl CpuConfiguration {
6960
Ok(Self {
7061
cpuid: supported_cpuid,
7162
msrs: Default::default(),
72-
msrs_to_save: Default::default(),
73-
msr_boot_entries: create_boot_msr_entries(),
7463
})
7564
}
7665

@@ -95,27 +84,12 @@ impl CpuConfiguration {
9584
.include_leaves_from(config.cpuid)
9685
.map_err(Error::CpuidJoin)?;
9786

98-
// TODO: Some MSRs depend on values of other MSRs. This dependency will need to
99-
// be implemented. For now we define known dependencies statically in the CPU
100-
// templates.
101-
102-
// Depending on which CPU template the user selected, we may need to initialize
103-
// additional MSRs for boot to correctly enable some CPU features. As stated in
104-
// the previous comment, we get from the template a static list of MSRs we need
105-
// to save at snapshot as well.
106-
// C3, T2 and T2A currently don't have extra MSRs to save/set.
10787
match template {
10888
StaticCpuTemplate::T2S => {
109-
config.msrs_to_save.extend(msr_entries_to_save());
110-
static_cpu_templates::t2s::update_t2s_msr_entries(
111-
&mut config.msr_boot_entries,
112-
);
89+
static_cpu_templates::t2s::update_t2s_msr_entries(&mut config.msrs);
11390
}
11491
StaticCpuTemplate::T2CL => {
115-
config.msrs_to_save.extend(msr_entries_to_save());
116-
static_cpu_templates::t2cl::update_t2cl_msr_entries(
117-
&mut config.msr_boot_entries,
118-
);
92+
static_cpu_templates::t2cl::update_t2cl_msr_entries(&mut config.msrs);
11993
}
12094
_ => (),
12195
}
@@ -130,8 +104,6 @@ impl CpuConfiguration {
130104
let Self {
131105
mut cpuid,
132106
mut msrs,
133-
msrs_to_save,
134-
msr_boot_entries,
135107
} = self;
136108

137109
let guest_cpuid = match &mut cpuid {
@@ -185,12 +157,7 @@ impl CpuConfiguration {
185157
}
186158
}
187159

188-
Ok(Self {
189-
cpuid,
190-
msrs,
191-
msrs_to_save,
192-
msr_boot_entries,
193-
})
160+
Ok(Self { cpuid, msrs })
194161
}
195162
}
196163

@@ -266,26 +233,20 @@ mod tests {
266233
CpuConfiguration {
267234
cpuid: Cpuid::Intel(IntelCpuid(BTreeMap::new())),
268235
msrs: Default::default(),
269-
msrs_to_save: Default::default(),
270-
msr_boot_entries: Default::default(),
271236
}
272237
}
273238

274239
fn supported_cpu_config() -> CpuConfiguration {
275240
CpuConfiguration {
276241
cpuid: static_cpu_templates::t2::t2(),
277242
msrs: HashMap::from([(0x8000, 0b1000), (0x9999, 0b1010)]),
278-
msrs_to_save: Default::default(),
279-
msr_boot_entries: Default::default(),
280243
}
281244
}
282245

283246
fn unsupported_cpu_config() -> CpuConfiguration {
284247
CpuConfiguration {
285248
cpuid: static_cpu_templates::t2::t2(),
286249
msrs: HashMap::from([(0x8000, 0b1000), (0x8001, 0b1010)]),
287-
msrs_to_save: Default::default(),
288-
msr_boot_entries: Default::default(),
289250
}
290251
}
291252

src/vmm/src/guest_config/x86_64/static_cpu_templates/t2cl.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use kvm_bindings::kvm_msr_entry;
4+
use std::collections::HashMap;
55

66
use crate::arch::x86_64::msr::ArchCapaMSRFlags;
77
use crate::arch_gen::x86::msr_index::MSR_IA32_ARCH_CAPABILITIES;
@@ -10,18 +10,14 @@ use crate::guest_config::cpuid::{Cpuid, CpuidEntry, CpuidKey, CpuidRegisters, In
1010

1111
/// Add the MSR entries specific to this T2S template.
1212
#[inline]
13-
pub fn update_t2cl_msr_entries(msr_entries: &mut Vec<kvm_msr_entry>) {
13+
pub fn update_t2cl_msr_entries(msr_entries: &mut HashMap<u32, u64>) {
1414
let capabilities = ArchCapaMSRFlags::RDCL_NO
1515
| ArchCapaMSRFlags::IBRS_ALL
1616
| ArchCapaMSRFlags::SKIP_L1DFL_VMENTRY
1717
| ArchCapaMSRFlags::MDS_NO
1818
| ArchCapaMSRFlags::IF_PSCHANGE_MC_NO
1919
| ArchCapaMSRFlags::TSX_CTRL;
20-
msr_entries.push(kvm_msr_entry {
21-
index: MSR_IA32_ARCH_CAPABILITIES,
22-
data: capabilities.bits(),
23-
..kvm_msr_entry::default()
24-
});
20+
msr_entries.insert(MSR_IA32_ARCH_CAPABILITIES, capabilities.bits());
2521
}
2622

2723
/// This is translated from `cpuid -r` within a T2CL guest microVM on an ec2 m5.metal instance:

src/vmm/src/guest_config/x86_64/static_cpu_templates/t2s.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use kvm_bindings::kvm_msr_entry;
4+
use std::collections::HashMap;
55

66
use crate::arch::x86_64::msr::ArchCapaMSRFlags;
77
use crate::arch_gen::x86::msr_index::MSR_IA32_ARCH_CAPABILITIES;
@@ -10,17 +10,13 @@ use crate::guest_config::cpuid::{Cpuid, CpuidEntry, CpuidKey, CpuidRegisters, In
1010

1111
/// Add the MSR entries specific to this T2S template.
1212
#[inline]
13-
pub fn update_t2s_msr_entries(msr_entries: &mut Vec<kvm_msr_entry>) {
13+
pub fn update_t2s_msr_entries(msr_entries: &mut HashMap<u32, u64>) {
1414
let capabilities = ArchCapaMSRFlags::RSBA
1515
| ArchCapaMSRFlags::SKIP_L1DFL_VMENTRY
1616
| ArchCapaMSRFlags::IF_PSCHANGE_MC_NO
1717
| ArchCapaMSRFlags::MISC_PACKAGE_CTRLS
1818
| ArchCapaMSRFlags::ENERGY_FILTERING_CTL;
19-
msr_entries.push(kvm_msr_entry {
20-
index: MSR_IA32_ARCH_CAPABILITIES,
21-
data: capabilities.bits(),
22-
..kvm_msr_entry::default()
23-
});
19+
msr_entries.insert(MSR_IA32_ARCH_CAPABILITIES, capabilities.bits());
2420
}
2521

2622
/// This is translated from `cpuid -r` within a T2S guest microVM on an ec2 m5.metal instance:

src/vmm/src/vstate/vcpu/x86_64.rs

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use versionize_derive::Versionize;
1818
use vm_memory::{Address, GuestAddress, GuestMemoryMmap};
1919

2020
use crate::arch::x86_64::interrupts;
21-
use crate::arch::x86_64::msr::{SetMsrsError, MSR_IA32_ARCH_CAPABILITIES};
21+
use crate::arch::x86_64::msr::{create_boot_msr_entries, SetMsrsError};
2222
use crate::arch::x86_64::regs::{SetupFpuError, SetupRegistersError, SetupSpecialRegistersError};
2323
use crate::vstate::vcpu::{VcpuConfig, VcpuEmulation};
2424
use crate::vstate::vm::Vm;
@@ -29,16 +29,6 @@ use crate::vstate::vm::Vm;
2929
// https://bugzilla.redhat.com/show_bug.cgi?id=1839095
3030
const TSC_KHZ_TOL: f64 = 250.0 / 1_000_000.0;
3131

32-
#[allow(clippy::missing_docs_in_private_items)]
33-
static EXTRA_MSR_ENTRIES: &[u32] = &[MSR_IA32_ARCH_CAPABILITIES];
34-
35-
/// Return a list of MSRs specific to this T2S template.
36-
#[inline]
37-
#[must_use]
38-
pub fn msr_entries_to_save() -> &'static [u32] {
39-
EXTRA_MSR_ENTRIES
40-
}
41-
4232
/// Errors associated with the wrappers over KVM ioctls.
4333
#[derive(Debug, thiserror::Error)]
4434
pub enum Error {
@@ -228,12 +218,8 @@ impl KvmVcpu {
228218
vcpu_config: &VcpuConfig,
229219
) -> std::result::Result<(), KvmVcpuConfigureError> {
230220
let mut cpuid = vcpu_config.cpu_config.cpuid.clone();
231-
self.msrs_to_save
232-
.extend(vcpu_config.cpu_config.msrs_to_save.iter());
233-
let msr_boot_entries = vcpu_config.cpu_config.msr_boot_entries.clone();
234221

235222
// Apply machine specific changes to CPUID.
236-
// config_cpuid
237223
cpuid
238224
.normalize(
239225
// The index of the current logical CPU in the range [0..cpu_count].
@@ -246,14 +232,22 @@ impl KvmVcpu {
246232
.map_err(KvmVcpuConfigureError::NormalizeCpuidError)?;
247233

248234
// Set CPUID.
249-
// let kvm_cpuid = kvm_bindings::CpuId::from(joined_cpuid);
250235
let kvm_cpuid = kvm_bindings::CpuId::from(cpuid);
251236

252237
// Set CPUID in the KVM
253238
self.fd
254239
.set_cpuid2(&kvm_cpuid)
255240
.map_err(KvmVcpuConfigureError::SetCpuid)?;
256241

242+
// Clone MSR entries that are modified by CPU template from `VcpuConfig`.
243+
let mut msrs = vcpu_config.cpu_config.msrs.clone();
244+
self.msrs_to_save.extend(msrs.keys());
245+
246+
// Apply MSR modification to comply the linux boot protocol.
247+
create_boot_msr_entries().into_iter().for_each(|entry| {
248+
msrs.insert(entry.index, entry.data);
249+
});
250+
257251
// TODO - Add/amend MSRs for vCPUs based on cpu_config
258252
// By this point the Guest CPUID is established. Some CPU features require MSRs
259253
// to configure and interact with those features. If a MSR is writable from
@@ -266,11 +260,23 @@ impl KvmVcpu {
266260
.map_err(KvmVcpuConfigureError::MsrsToSaveByCpuid)?;
267261
self.msrs_to_save.extend(extra_msrs);
268262

263+
// TODO: Some MSRs depend on values of other MSRs. This dependency will need to
264+
// be implemented.
265+
269266
// By this point we know that at snapshot, the list of MSRs we need to
270267
// save is `architectural MSRs` + `MSRs inferred through CPUID` + `other
271268
// MSRs defined by the template`
272269

273-
crate::arch::x86_64::msr::set_msrs(&self.fd, &msr_boot_entries)?;
270+
let kvm_msrs = msrs
271+
.into_iter()
272+
.map(|entry| kvm_bindings::kvm_msr_entry {
273+
index: entry.0,
274+
data: entry.1,
275+
..Default::default()
276+
})
277+
.collect::<Vec<_>>();
278+
279+
crate::arch::x86_64::msr::set_msrs(&self.fd, &kvm_msrs)?;
274280
crate::arch::x86_64::regs::setup_regs(&self.fd, kernel_start_addr.raw_value())?;
275281
crate::arch::x86_64::regs::setup_fpu(&self.fd)?;
276282
crate::arch::x86_64::regs::setup_sregs(guest_mem, &self.fd)?;

0 commit comments

Comments
 (0)