Skip to content

Commit 180b12a

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 c664078 commit 180b12a

File tree

8 files changed

+177
-118
lines changed

8 files changed

+177
-118
lines changed

.buildkite/pipeline_cpu_template.py

Lines changed: 0 additions & 1 deletion
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 9 additions & 9 deletions
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
@@ -72,7 +72,7 @@ Firecracker expects the host to always be running the latest version of the
7272
microcode.
7373

7474
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).
75+
use it on Intel CPUs other than 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

Lines changed: 39 additions & 51 deletions
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 {
@@ -64,49 +87,14 @@ impl From<&CpuModel> for u32 {
6487
}
6588
}
6689

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-
7990
#[cfg(test)]
8091
mod tests {
8192
use super::*;
8293

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-
9994
#[test]
10095
fn cpu_model_from() {
10196
let skylake_eax = 0x00050654;
102-
assert_eq!(u32::from(&SKYLAKE), skylake_eax);
103-
assert_eq!(CpuModel::from(&skylake_eax), SKYLAKE);
104-
}
105-
106-
#[test]
107-
fn cpu_model_ord() {
108-
assert_eq!(SKYLAKE, SKYLAKE);
109-
assert!(SKYLAKE < CASCADE_LAKE);
110-
assert!(CASCADE_LAKE > SKYLAKE);
97+
assert_eq!(u32::from(&SKYLAKE_FMS), skylake_eax);
98+
assert_eq!(CpuModel::from(&skylake_eax), SKYLAKE_FMS);
11199
}
112100
}

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

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,9 @@ mod tests {
797797

798798
use super::*;
799799
use crate::arch::BootProtocol;
800-
use crate::arch::x86_64::cpu_model::CpuModel;
800+
use crate::arch::x86_64::cpu_model::{
801+
CASCADE_LAKE_FMS, CpuModel, ICE_LAKE_FMS, MILAN_FMS, SKYLAKE_FMS,
802+
};
801803
use crate::cpu_config::templates::{
802804
CpuConfiguration, CpuTemplateType, CustomCpuTemplate, GetCpuTemplate, GuestConfigError,
803805
StaticCpuTemplate,
@@ -832,17 +834,6 @@ mod tests {
832834
(kvm, vm, vcpu)
833835
}
834836

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-
846837
fn create_vcpu_config(
847838
kvm: &Kvm,
848839
vcpu: &KvmVcpu,
@@ -915,24 +906,37 @@ mod tests {
915906
// Test configure while using the T2S template.
916907
let t2a_res = try_configure(&kvm, &mut vcpu, StaticCpuTemplate::T2A);
917908

909+
let cpu_model = CpuModel::get_cpu_model();
918910
match &cpuid::common::get_vendor_id_from_host().unwrap() {
919911
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-
}
912+
assert_eq!(
913+
t2_res,
914+
cpu_model == SKYLAKE_FMS
915+
|| cpu_model == CASCADE_LAKE_FMS
916+
|| cpu_model == ICE_LAKE_FMS
917+
);
918+
assert_eq!(
919+
c3_res,
920+
cpu_model == SKYLAKE_FMS
921+
|| cpu_model == CASCADE_LAKE_FMS
922+
|| cpu_model == ICE_LAKE_FMS
923+
);
924+
assert_eq!(
925+
t2s_res,
926+
cpu_model == SKYLAKE_FMS || cpu_model == CASCADE_LAKE_FMS
927+
);
928+
assert_eq!(
929+
t2cl_res,
930+
cpu_model == CASCADE_LAKE_FMS || cpu_model == ICE_LAKE_FMS
931+
);
928932
assert!(!t2a_res);
929933
}
930934
cpuid::VENDOR_ID_AMD => {
931935
assert!(!t2_res);
932936
assert!(!c3_res);
933937
assert!(!t2s_res);
934938
assert!(!t2cl_res);
935-
assert!(t2a_res);
939+
assert_eq!(t2a_res, cpu_model == MILAN_FMS);
936940
}
937941
_ => {
938942
assert!(!t2_res);

0 commit comments

Comments
 (0)