Skip to content

Commit c835e07

Browse files
committed
vmm: More specific CPU model check for CPU templates
Do CPU model check for static CPU templates in accordance with the doc change in the prev commit. Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent 8ce1360 commit c835e07

File tree

11 files changed

+258
-193
lines changed

11 files changed

+258
-193
lines changed

.buildkite/pipeline_cpu_template.py

-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ class BkStep(str, Enum):
7070
"m5n.metal",
7171
"m6i.metal",
7272
"m6a.metal",
73-
"m7a.metal-48xl",
7473
],
7574
},
7675
}

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ and this project adheres to
2626
WAITPKG CPUID bit in CPUID normalization. The feature enables a guest to put a
2727
physical processor into an idle state, which is undesirable in a FaaS
2828
environment since that is what the host wants to decide.
29+
- [#5142](https://github.com/firecracker-microvm/firecracker/pull/5142):
30+
Clarified what CPU models are supported by each existing CPU template.
31+
Firecracker exits with an error if a CPU template is used on an unsupported
32+
CPU model.
2933

3034
### Deprecated
3135

docs/cpu_templates/cpu-templates.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ Firecracker supports two types of CPU templates:
4848

4949
At the moment the following set of static CPU templates are supported:
5050

51-
| CPU template | CPU vendor | CPU model |
52-
| ------------ | ---------- | --------------------- |
53-
| C3 | Intel | any |
54-
| T2 | Intel | any |
55-
| T2A | AMD | Milan |
56-
| T2CL | Intel | Cascade Lake or newer |
57-
| T2S | Intel | any |
58-
| V1N1 | ARM | Neoverse V1 |
51+
| CPU template | CPU vendor | CPU model |
52+
| ------------ | ---------- | ------------------------------- |
53+
| C3 | Intel | Skylake, Cascade Lake, Ice Lake |
54+
| T2 | Intel | Skylake, Cascade Lake, Ice Lake |
55+
| T2A | AMD | Milan |
56+
| T2CL | Intel | Cascade Lake, Ice Lake |
57+
| T2S | Intel | Skylake, Cascade Lake |
58+
| V1N1 | ARM | Neoverse V1 |
5959

6060
T2 and C3 templates are mapped as close as possible to AWS T2 and C3 instances
6161
in terms of CPU features. Note that on a microVM that is lauched with the C3
@@ -71,8 +71,8 @@ a performance assessment if they wish to use the T2S template. Note that
7171
Firecracker expects the host to always be running the latest version of the
7272
microcode.
7373

74-
The T2CL template is mapped to be close to Intel Cascade Lake. It is not safe to
75-
use it on Intel CPUs older than Cascade Lake (such as Skylake).
74+
The T2CL template is mapped to be close to Intel Cascade Lake. It is only safe
75+
to use it on Intel Cascade Lake and Ice Lake.
7676

7777
The only AMD template is T2A. It is considered safe to be used with AMD Milan.
7878

src/vmm/src/arch/x86_64/cpu_model.rs

+46-60
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use std::arch::x86_64::__cpuid as host_cpuid;
5-
use std::cmp::{Eq, Ordering, PartialEq, PartialOrd};
5+
use std::cmp::{Eq, PartialEq};
66

77
/// Structure representing x86_64 CPU model.
88
#[derive(Debug, Eq, PartialEq)]
@@ -19,6 +19,42 @@ pub struct CpuModel {
1919
pub stepping: u8,
2020
}
2121

22+
/// Family / Model / Stepping for Intel Skylake
23+
pub const SKYLAKE_FMS: CpuModel = CpuModel {
24+
extended_family: 0x0,
25+
extended_model: 0x5,
26+
family: 0x6,
27+
model: 0x5,
28+
stepping: 0x4,
29+
};
30+
31+
/// Family / Model / Stepping for Intel Cascade Lake
32+
pub const CASCADE_LAKE_FMS: CpuModel = CpuModel {
33+
extended_family: 0x0,
34+
extended_model: 0x5,
35+
family: 0x6,
36+
model: 0x5,
37+
stepping: 0x7,
38+
};
39+
40+
/// Family / Model / Stepping for Intel Ice Lake
41+
pub const ICE_LAKE_FMS: CpuModel = CpuModel {
42+
extended_family: 0x0,
43+
extended_model: 0x6,
44+
family: 0x6,
45+
model: 0xa,
46+
stepping: 0x6,
47+
};
48+
49+
/// Family / Model / Stepping for AMD Milan
50+
pub const MILAN_FMS: CpuModel = CpuModel {
51+
extended_family: 0xa,
52+
extended_model: 0x0,
53+
family: 0xf,
54+
model: 0x1,
55+
stepping: 0x1,
56+
};
57+
2258
impl CpuModel {
2359
/// Get CPU model from current machine.
2460
pub fn get_cpu_model() -> Self {
@@ -27,19 +63,6 @@ impl CpuModel {
2763
let eax = unsafe { host_cpuid(0x1) }.eax;
2864
CpuModel::from(&eax)
2965
}
30-
31-
/// Check if the current CPU model is Intel Cascade Lake or later.
32-
pub fn is_at_least_cascade_lake(&self) -> bool {
33-
let cascade_lake = CpuModel {
34-
extended_family: 0,
35-
extended_model: 5,
36-
family: 6,
37-
model: 5,
38-
stepping: 7,
39-
};
40-
41-
self >= &cascade_lake
42-
}
4366
}
4467

4568
impl From<&u32> for CpuModel {
@@ -54,59 +77,22 @@ impl From<&u32> for CpuModel {
5477
}
5578
}
5679

57-
impl From<&CpuModel> for u32 {
58-
fn from(cpu_model: &CpuModel) -> Self {
59-
(u32::from(cpu_model.extended_family) << 20)
60-
| (u32::from(cpu_model.extended_model) << 16)
61-
| (u32::from(cpu_model.family) << 8)
62-
| (u32::from(cpu_model.model) << 4)
63-
| u32::from(cpu_model.stepping)
64-
}
65-
}
66-
67-
impl PartialOrd for CpuModel {
68-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
69-
Some(u32::from(self).cmp(&u32::from(other)))
70-
}
71-
}
72-
73-
impl Ord for CpuModel {
74-
fn cmp(&self, other: &Self) -> Ordering {
75-
u32::from(self).cmp(&u32::from(other))
76-
}
77-
}
78-
7980
#[cfg(test)]
8081
mod tests {
8182
use super::*;
8283

83-
const SKYLAKE: CpuModel = CpuModel {
84-
extended_family: 0,
85-
extended_model: 5,
86-
family: 6,
87-
model: 5,
88-
stepping: 4,
89-
};
90-
91-
const CASCADE_LAKE: CpuModel = CpuModel {
92-
extended_family: 0,
93-
extended_model: 5,
94-
family: 6,
95-
model: 5,
96-
stepping: 7,
97-
};
98-
9984
#[test]
10085
fn cpu_model_from() {
10186
let skylake_eax = 0x00050654;
102-
assert_eq!(u32::from(&SKYLAKE), skylake_eax);
103-
assert_eq!(CpuModel::from(&skylake_eax), SKYLAKE);
104-
}
87+
assert_eq!(CpuModel::from(&skylake_eax), SKYLAKE_FMS);
10588

106-
#[test]
107-
fn cpu_model_ord() {
108-
assert_eq!(SKYLAKE, SKYLAKE);
109-
assert!(SKYLAKE < CASCADE_LAKE);
110-
assert!(CASCADE_LAKE > SKYLAKE);
89+
let cascade_lake_eax = 0x00050657;
90+
assert_eq!(CpuModel::from(&cascade_lake_eax), CASCADE_LAKE_FMS);
91+
92+
let ice_lake_eax = 0x000606a6;
93+
assert_eq!(CpuModel::from(&ice_lake_eax), ICE_LAKE_FMS);
94+
95+
let milan_eax = 0x00a00f11;
96+
assert_eq!(CpuModel::from(&milan_eax), MILAN_FMS);
11197
}
11298
}

src/vmm/src/arch/x86_64/vcpu.rs

+31-20
Original file line numberDiff line numberDiff line change
@@ -832,17 +832,6 @@ mod tests {
832832
(kvm, vm, vcpu)
833833
}
834834

835-
fn is_at_least_cascade_lake() -> bool {
836-
CpuModel::get_cpu_model()
837-
>= (CpuModel {
838-
extended_family: 0,
839-
extended_model: 5,
840-
family: 6,
841-
model: 5,
842-
stepping: 7,
843-
})
844-
}
845-
846835
fn create_vcpu_config(
847836
kvm: &Kvm,
848837
vcpu: &KvmVcpu,
@@ -915,24 +904,46 @@ mod tests {
915904
// Test configure while using the T2S template.
916905
let t2a_res = try_configure(&kvm, &mut vcpu, StaticCpuTemplate::T2A);
917906

907+
let cpu_model = CpuModel::get_cpu_model();
918908
match &cpuid::common::get_vendor_id_from_host().unwrap() {
919909
cpuid::VENDOR_ID_INTEL => {
920-
assert!(t2_res);
921-
assert!(c3_res);
922-
assert!(t2s_res);
923-
if is_at_least_cascade_lake() {
924-
assert!(t2cl_res);
925-
} else {
926-
assert!(!t2cl_res);
927-
}
910+
assert_eq!(
911+
t2_res,
912+
StaticCpuTemplate::T2
913+
.get_supported_cpu_models()
914+
.contains(&cpu_model)
915+
);
916+
assert_eq!(
917+
c3_res,
918+
StaticCpuTemplate::C3
919+
.get_supported_cpu_models()
920+
.contains(&cpu_model)
921+
);
922+
assert_eq!(
923+
t2s_res,
924+
StaticCpuTemplate::T2S
925+
.get_supported_cpu_models()
926+
.contains(&cpu_model)
927+
);
928+
assert_eq!(
929+
t2cl_res,
930+
StaticCpuTemplate::T2CL
931+
.get_supported_cpu_models()
932+
.contains(&cpu_model)
933+
);
928934
assert!(!t2a_res);
929935
}
930936
cpuid::VENDOR_ID_AMD => {
931937
assert!(!t2_res);
932938
assert!(!c3_res);
933939
assert!(!t2s_res);
934940
assert!(!t2cl_res);
935-
assert!(t2a_res);
941+
assert_eq!(
942+
t2a_res,
943+
StaticCpuTemplate::T2A
944+
.get_supported_cpu_models()
945+
.contains(&cpu_model)
946+
);
936947
}
937948
_ => {
938949
assert!(!t2_res);

0 commit comments

Comments
 (0)