@@ -15,14 +15,12 @@ import (
1515// ref: https://gitlab.com/x86-psABIs/x86-64-ABI
1616// ref: https://developers.redhat.com/blog/2021/01/05/building-red-hat-enterprise-linux-9-for-the-x86-64-v2-microarchitecture-level
1717var microarchs = map [string ][]string {
18+ "x86-64" : {"cmov" , "cx8" , "fpu" , "fxsr" , "mmx" , "syscall" , "sse" , "sse2" },
1819 "x86-64-v2" : {"cx16" , "lahf_lm" , "popcnt" , "ssse3" , "sse4_1" , "sse4_2" , "ssse3" },
1920 "x86-64-v3" : {"avx" , "avx2" , "bmi1" , "bmi2" , "f16c" , "fma" , "lzcnt" , "movbe" , "xsave" },
2021 "x86-64-v4" : {"avx512f" , "avx512bw" , "avx512cd" , "avx512dq" , "avx512vl" },
2122}
2223
23- // x8664BaseFeatures are the features that are present in all x86-64 microarchitectures.
24- var x8664BaseFeatures = []string {"cmov" , "cx8" , "fpu" , "fxsr" , "mmx" , "syscall" , "sse" , "sse2" }
25-
2624type AnalyzeHostCPU struct {
2725 hostAnalyzer * troubleshootv1beta2.CPUAnalyze
2826}
@@ -126,13 +124,36 @@ func (a *AnalyzeHostCPU) Analyze(
126124}
127125
128126func doCompareHostCPUMicroArchitecture (microarch string , flags []string ) (res bool , err error ) {
129- specifics , ok := microarchs [microarch ]
130- if ! ok && microarch != "x86-64" {
127+ specifics := make ([]string , 0 )
128+ switch microarch {
129+ case "x86-64-v4" :
130+ specifics = append (specifics , microarchs ["x86-64-v4" ]... )
131+ fallthrough
132+ case "x86-64-v3" :
133+ specifics = append (specifics , microarchs ["x86-64-v3" ]... )
134+ fallthrough
135+ case "x86-64-v2" :
136+ specifics = append (specifics , microarchs ["x86-64-v2" ]... )
137+ fallthrough
138+ case "x86-64" :
139+ specifics = append (specifics , microarchs ["x86-64" ]... )
140+ default :
131141 return false , errors .Errorf ("troubleshoot does not yet support microarchitecture %q" , microarch )
132142 }
133- expectedFlags := x8664BaseFeatures
134- if len (specifics ) > 0 {
135- expectedFlags = append (expectedFlags , specifics ... )
143+
144+ for _ , flag := range specifics {
145+ if slices .Contains (flags , flag ) {
146+ continue
147+ }
148+ return false , nil
149+ }
150+ return true , nil
151+ }
152+
153+ func doCompareHostCPUFlags (expected string , flags []string ) (res bool , err error ) {
154+ expectedFlags := strings .Split (expected , "," )
155+ if len (expectedFlags ) == 0 {
156+ return false , errors .New ("expected flags cannot be empty" )
136157 }
137158 for _ , flag := range expectedFlags {
138159 if slices .Contains (flags , flag ) {
@@ -173,6 +194,11 @@ func compareHostCPUConditionalToActual(conditional string, logicalCount int, phy
173194 return doCompareHostCPUMicroArchitecture (desired , flags )
174195 }
175196
197+ // hasFlags allows users to query for specific flags on the CPU.
198+ if strings .ToLower (comparator ) == "hasflags" {
199+ return doCompareHostCPUFlags (desired , flags )
200+ }
201+
176202 if ! compareLogical && ! comparePhysical && ! compareUnspecified {
177203 return false , errors .New ("unable to parse conditional" )
178204 }
0 commit comments