@@ -8,7 +8,9 @@ use std::borrow::Cow;
88use serde:: de:: Error as SerdeError ;
99use serde:: { Deserialize , Deserializer , Serialize , Serializer } ;
1010
11- use crate :: arch:: x86_64:: cpu_model:: CpuModel ;
11+ use crate :: arch:: x86_64:: cpu_model:: {
12+ CASCADE_LAKE_FMS , CpuModel , ICE_LAKE_FMS , MILAN_FMS , SKYLAKE_FMS ,
13+ } ;
1214use crate :: cpu_config:: templates:: {
1315 CpuTemplateType , GetCpuTemplate , GetCpuTemplateError , KvmCapability , RegisterValueFilter ,
1416} ;
@@ -27,12 +29,18 @@ impl GetCpuTemplate for Option<CpuTemplateType> {
2729 CpuTemplateType :: Custom ( template) => Ok ( Cow :: Borrowed ( template) ) ,
2830 CpuTemplateType :: Static ( template) => {
2931 let vendor_id = get_vendor_id_from_host ( ) . map_err ( GetCpuVendor ) ?;
32+ let cpu_model = CpuModel :: get_cpu_model ( ) ;
3033 match template {
3134 StaticCpuTemplate :: C3 => {
3235 if & vendor_id != VENDOR_ID_INTEL {
3336 return Err ( CpuVendorMismatched ) ;
37+ } else if cpu_model != SKYLAKE_FMS
38+ && cpu_model != CASCADE_LAKE_FMS
39+ && cpu_model != ICE_LAKE_FMS
40+ {
41+ return Err ( InvalidCpuModel ) ;
3442 }
35- if ! CpuModel :: get_cpu_model ( ) . is_at_least_cascade_lake ( ) {
43+ if cpu_model == SKYLAKE_FMS {
3644 warn ! (
3745 "On processors that do not enumerate FBSDP_NO, PSDP_NO and \
3846 SBDR_SSDP_NO on IA32_ARCH_CAPABILITIES MSR, the guest kernel \
@@ -45,26 +53,35 @@ impl GetCpuTemplate for Option<CpuTemplateType> {
4553 StaticCpuTemplate :: T2 => {
4654 if & vendor_id != VENDOR_ID_INTEL {
4755 return Err ( CpuVendorMismatched ) ;
56+ } else if cpu_model != SKYLAKE_FMS
57+ && cpu_model != CASCADE_LAKE_FMS
58+ && cpu_model != ICE_LAKE_FMS
59+ {
60+ return Err ( InvalidCpuModel ) ;
4861 }
4962 Ok ( Cow :: Owned ( t2:: t2 ( ) ) )
5063 }
5164 StaticCpuTemplate :: T2S => {
5265 if & vendor_id != VENDOR_ID_INTEL {
5366 return Err ( CpuVendorMismatched ) ;
67+ } else if cpu_model != SKYLAKE_FMS && cpu_model != CASCADE_LAKE_FMS {
68+ return Err ( InvalidCpuModel ) ;
5469 }
5570 Ok ( Cow :: Owned ( t2s:: t2s ( ) ) )
5671 }
5772 StaticCpuTemplate :: T2CL => {
5873 if & vendor_id != VENDOR_ID_INTEL {
5974 return Err ( CpuVendorMismatched ) ;
60- } else if ! CpuModel :: get_cpu_model ( ) . is_at_least_cascade_lake ( ) {
75+ } else if cpu_model != CASCADE_LAKE_FMS && cpu_model != ICE_LAKE_FMS {
6176 return Err ( InvalidCpuModel ) ;
6277 }
6378 Ok ( Cow :: Owned ( t2cl:: t2cl ( ) ) )
6479 }
6580 StaticCpuTemplate :: T2A => {
6681 if & vendor_id != VENDOR_ID_AMD {
6782 return Err ( CpuVendorMismatched ) ;
83+ } else if cpu_model != MILAN_FMS {
84+ return Err ( InvalidCpuModel ) ;
6885 }
6986 Ok ( Cow :: Owned ( t2a:: t2a ( ) ) )
7087 }
@@ -230,13 +247,25 @@ mod tests {
230247 #[ test]
231248 fn test_get_cpu_template_with_c3_static_template ( ) {
232249 // Test `get_cpu_template()` when C3 static CPU template is specified. The owned
233- // `CustomCpuTemplate` should be returned if CPU vendor is Intel. Otherwise, it should fail.
250+ // `CustomCpuTemplate` should be returned if CPU vendor is Intel and the CPU model is
251+ // supported. Otherwise, it should fail.
234252 let cpu_template = Some ( CpuTemplateType :: Static ( StaticCpuTemplate :: C3 ) ) ;
235253 if & get_vendor_id_from_host ( ) . unwrap ( ) == VENDOR_ID_INTEL {
236- assert_eq ! (
237- cpu_template. get_cpu_template( ) . unwrap( ) ,
238- Cow :: Owned ( c3:: c3( ) )
239- ) ;
254+ let cpu_model = CpuModel :: get_cpu_model ( ) ;
255+ if cpu_model != SKYLAKE_FMS
256+ && cpu_model != CASCADE_LAKE_FMS
257+ && cpu_model != ICE_LAKE_FMS
258+ {
259+ assert_eq ! (
260+ cpu_template. get_cpu_template( ) . unwrap_err( ) ,
261+ GetCpuTemplateError :: InvalidCpuModel ,
262+ ) ;
263+ } else {
264+ assert_eq ! (
265+ cpu_template. get_cpu_template( ) . unwrap( ) ,
266+ Cow :: Owned ( c3:: c3( ) )
267+ ) ;
268+ }
240269 } else {
241270 assert_eq ! (
242271 cpu_template. get_cpu_template( ) . unwrap_err( ) ,
@@ -248,13 +277,25 @@ mod tests {
248277 #[ test]
249278 fn test_get_cpu_template_with_t2_static_template ( ) {
250279 // Test `get_cpu_template()` when T2 static CPU template is specified. The owned
251- // `CustomCpuTemplate` should be returned if CPU vendor is Intel. Otherwise, it should fail.
280+ // `CustomCpuTemplate` should be returned if CPU vendor is Intel and the CPU model is
281+ // supported. Otherwise, it should fail.
252282 let cpu_template = Some ( CpuTemplateType :: Static ( StaticCpuTemplate :: T2 ) ) ;
253283 if & get_vendor_id_from_host ( ) . unwrap ( ) == VENDOR_ID_INTEL {
254- assert_eq ! (
255- cpu_template. get_cpu_template( ) . unwrap( ) ,
256- Cow :: Owned ( t2:: t2( ) )
257- ) ;
284+ let cpu_model = CpuModel :: get_cpu_model ( ) ;
285+ if cpu_model != SKYLAKE_FMS
286+ && cpu_model != CASCADE_LAKE_FMS
287+ && cpu_model != ICE_LAKE_FMS
288+ {
289+ assert_eq ! (
290+ cpu_template. get_cpu_template( ) . unwrap_err( ) ,
291+ GetCpuTemplateError :: InvalidCpuModel ,
292+ ) ;
293+ } else {
294+ assert_eq ! (
295+ cpu_template. get_cpu_template( ) . unwrap( ) ,
296+ Cow :: Owned ( t2:: t2( ) )
297+ ) ;
298+ }
258299 } else {
259300 assert_eq ! (
260301 cpu_template. get_cpu_template( ) . unwrap_err( ) ,
@@ -266,13 +307,22 @@ mod tests {
266307 #[ test]
267308 fn test_get_cpu_template_with_t2s_static_template ( ) {
268309 // Test `get_cpu_template()` when T2S static CPU template is specified. The owned
269- // `CustomCpuTemplate` should be returned if CPU vendor is Intel. Otherwise, it should fail.
310+ // `CustomCpuTemplate` should be returned if CPU vendor is Intel and the CPU model is
311+ // supported. Otherwise, it should fail.
270312 let cpu_template = Some ( CpuTemplateType :: Static ( StaticCpuTemplate :: T2S ) ) ;
271313 if & get_vendor_id_from_host ( ) . unwrap ( ) == VENDOR_ID_INTEL {
272- assert_eq ! (
273- cpu_template. get_cpu_template( ) . unwrap( ) ,
274- Cow :: Owned ( t2s:: t2s( ) )
275- ) ;
314+ let cpu_model = CpuModel :: get_cpu_model ( ) ;
315+ if cpu_model != SKYLAKE_FMS && cpu_model != CASCADE_LAKE_FMS {
316+ assert_eq ! (
317+ cpu_template. get_cpu_template( ) . unwrap_err( ) ,
318+ GetCpuTemplateError :: InvalidCpuModel ,
319+ ) ;
320+ } else {
321+ assert_eq ! (
322+ cpu_template. get_cpu_template( ) . unwrap( ) ,
323+ Cow :: Owned ( t2s:: t2s( ) )
324+ ) ;
325+ }
276326 } else {
277327 assert_eq ! (
278328 cpu_template. get_cpu_template( ) . unwrap_err( ) ,
@@ -299,10 +349,12 @@ mod tests {
299349 #[ test]
300350 fn test_get_cpu_template_with_t2cl_static_template ( ) {
301351 // Test `get_cpu_template()` when T2CL static CPU template is specified. The owned
302- // `CustomCpuTemplate` should be returned if CPU vendor is Intel. Otherwise, it should fail.
352+ // `CustomCpuTemplate` should be returned if CPU vendor is Intel and the CPU model is
353+ // supported. Otherwise, it should fail.
303354 let cpu_template = Some ( CpuTemplateType :: Static ( StaticCpuTemplate :: T2CL ) ) ;
304355 if & get_vendor_id_from_host ( ) . unwrap ( ) == VENDOR_ID_INTEL {
305- if CpuModel :: get_cpu_model ( ) . is_at_least_cascade_lake ( ) {
356+ let cpu_model = CpuModel :: get_cpu_model ( ) ;
357+ if cpu_model != CASCADE_LAKE_FMS && cpu_model != ICE_LAKE_FMS {
306358 assert_eq ! (
307359 cpu_template. get_cpu_template( ) . unwrap( ) ,
308360 Cow :: Owned ( t2cl:: t2cl( ) )
0 commit comments