features_amd64.go raw
1 // Copyright 2019 The gVisor Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //go:build amd64
16 // +build amd64
17
18 package cpuid
19
20 // block is a collection of 32 Feature bits.
21 type block int
22
23 // blockSize is the number of bits in a single block.
24 const blockSize = 32
25
26 // featureID returns the feature identified by the given block and bit.
27 //
28 // Feature bits are numbered according to "blocks". Each block is 32 bits, and
29 // feature bits from the same source (cpuid leaf/level) are in the same block.
30 func featureID(b block, bit int) Feature {
31 return Feature(blockSize*int(b) + bit)
32 }
33
34 // block returns the block associated with the feature.
35 func (f Feature) block() block {
36 return block(f / blockSize)
37 }
38
39 // Bit returns the bit associated with the feature.
40 func (f Feature) bit() uint32 {
41 return uint32(1 << (f % blockSize))
42 }
43
44 // ChangeableSet is a feature set that can allows changes.
45 type ChangeableSet interface {
46 Query(in In) Out
47 Set(in In, out Out)
48 }
49
50 // Set sets the given feature.
51 func (f Feature) Set(s ChangeableSet) {
52 f.set(s, true)
53 }
54
55 // Unset unsets the given feature.
56 func (f Feature) Unset(s ChangeableSet) {
57 f.set(s, false)
58 }
59
60 // set sets the given feature.
61 func (f Feature) set(s ChangeableSet, on bool) {
62 switch f.block() {
63 case 0:
64 out := s.Query(In{Eax: uint32(featureInfo)})
65 if on {
66 out.Ecx |= f.bit()
67 } else {
68 out.Ecx &^= f.bit()
69 }
70 s.Set(In{Eax: uint32(featureInfo)}, out)
71 case 1:
72 out := s.Query(In{Eax: uint32(featureInfo)})
73 if on {
74 out.Edx |= f.bit()
75 } else {
76 out.Edx &^= f.bit()
77 }
78 s.Set(In{Eax: uint32(featureInfo)}, out)
79 case 2:
80 out := s.Query(In{Eax: uint32(extendedFeatureInfo)})
81 if on {
82 out.Ebx |= f.bit()
83 } else {
84 out.Ebx &^= f.bit()
85 }
86 s.Set(In{Eax: uint32(extendedFeatureInfo)}, out)
87 case 3:
88 out := s.Query(In{Eax: uint32(extendedFeatureInfo)})
89 if on {
90 out.Ecx |= f.bit()
91 } else {
92 out.Ecx &^= f.bit()
93 }
94 s.Set(In{Eax: uint32(extendedFeatureInfo)}, out)
95 case 4:
96 // Need to turn on the bit in block 0.
97 out := s.Query(In{Eax: uint32(featureInfo)})
98 out.Ecx |= (1 << 26)
99 s.Set(In{Eax: uint32(featureInfo)}, out)
100
101 out = s.Query(In{Eax: xSaveInfoSub.eax(), Ecx: xSaveInfoSub.ecx()})
102 if on {
103 out.Eax |= f.bit()
104 } else {
105 out.Eax &^= f.bit()
106 }
107 s.Set(In{Eax: xSaveInfoSub.eax(), Ecx: xSaveInfoSub.ecx()}, out)
108 case 5, 6:
109 // Need to enable extended features.
110 out := s.Query(In{Eax: uint32(extendedFunctionInfo)})
111 if out.Eax < uint32(extendedFeatures) {
112 out.Eax = uint32(extendedFeatures)
113 }
114 s.Set(In{Eax: uint32(extendedFunctionInfo)}, out)
115 out = s.Query(In{Eax: uint32(extendedFeatures)})
116 if f.block() == 5 {
117 if on {
118 out.Ecx |= f.bit()
119 } else {
120 out.Ecx &^= f.bit()
121 }
122 } else {
123 if on {
124 out.Edx |= f.bit()
125 } else {
126 out.Edx &^= f.bit()
127 }
128 }
129 s.Set(In{Eax: uint32(extendedFeatures)}, out)
130 case 7:
131 out := s.Query(In{Eax: uint32(extendedFeatureInfo)})
132 if on {
133 out.Edx |= f.bit()
134 } else {
135 out.Edx &^= f.bit()
136 }
137 s.Set(In{Eax: uint32(extendedFeatureInfo)}, out)
138 }
139 }
140
141 // check checks for the given feature.
142 //
143 //go:nosplit
144 func (f Feature) check(fs FeatureSet) bool {
145 switch f.block() {
146 case 0:
147 _, _, cx, _ := fs.query(featureInfo)
148 return (cx & f.bit()) != 0
149 case 1:
150 _, _, _, dx := fs.query(featureInfo)
151 return (dx & f.bit()) != 0
152 case 2:
153 _, bx, _, _ := fs.query(extendedFeatureInfo)
154 return (bx & f.bit()) != 0
155 case 3:
156 _, _, cx, _ := fs.query(extendedFeatureInfo)
157 return (cx & f.bit()) != 0
158 case 4:
159 // Need to check appropriate bit in block 0.
160 _, _, cx, _ := fs.query(featureInfo)
161 if (cx & (1 << 26)) == 0 {
162 return false
163 }
164 ax, _, _, _ := fs.query(xSaveInfoSub)
165 return (ax & f.bit()) != 0
166 case 5, 6:
167 // eax=0x80000000 gets supported extended levels. We use this
168 // to determine if there are any non-zero block 4 or block 6
169 // bits to find.
170 ax, _, _, _ := fs.query(extendedFunctionInfo)
171 if ax >= uint32(extendedFeatures) {
172 _, _, cx, dx := fs.query(extendedFeatures)
173 if f.block() == 5 {
174 return (cx & f.bit()) != 0
175 }
176 // Ignore features duplicated from block 1 on AMD.
177 // These bits are reserved on Intel.
178 return ((dx &^ block6DuplicateMask) & f.bit()) != 0
179 }
180 return false
181 case 7:
182 _, _, _, dx := fs.query(extendedFeatureInfo)
183 return (dx & f.bit()) != 0
184 default:
185 return false
186 }
187 }
188
189 // Block 0 constants are all of the "basic" feature bits returned by a cpuid in
190 // ecx with eax=1.
191 const (
192 X86FeatureSSE3 Feature = iota
193 X86FeaturePCLMULDQ
194 X86FeatureDTES64
195 X86FeatureMONITOR
196 X86FeatureDSCPL
197 X86FeatureVMX
198 X86FeatureSMX
199 X86FeatureEST
200 X86FeatureTM2
201 X86FeatureSSSE3 // Not a typo, "supplemental" SSE3.
202 X86FeatureCNXTID
203 X86FeatureSDBG
204 X86FeatureFMA
205 X86FeatureCX16
206 X86FeatureXTPR
207 X86FeaturePDCM
208 _ // ecx bit 16 is reserved.
209 X86FeaturePCID
210 X86FeatureDCA
211 X86FeatureSSE4_1
212 X86FeatureSSE4_2
213 X86FeatureX2APIC
214 X86FeatureMOVBE
215 X86FeaturePOPCNT
216 X86FeatureTSCD
217 X86FeatureAES
218 X86FeatureXSAVE
219 X86FeatureOSXSAVE
220 X86FeatureAVX
221 X86FeatureF16C
222 X86FeatureRDRAND
223 X86FeatureHypervisor
224 )
225
226 // Block 1 constants are all of the "basic" feature bits returned by a cpuid in
227 // edx with eax=1.
228 const (
229 X86FeatureFPU Feature = 32 + iota
230 X86FeatureVME
231 X86FeatureDE
232 X86FeaturePSE
233 X86FeatureTSC
234 X86FeatureMSR
235 X86FeaturePAE
236 X86FeatureMCE
237 X86FeatureCX8
238 X86FeatureAPIC
239 _ // edx bit 10 is reserved.
240 X86FeatureSEP
241 X86FeatureMTRR
242 X86FeaturePGE
243 X86FeatureMCA
244 X86FeatureCMOV
245 X86FeaturePAT
246 X86FeaturePSE36
247 X86FeaturePSN
248 X86FeatureCLFSH
249 _ // edx bit 20 is reserved.
250 X86FeatureDS
251 X86FeatureACPI
252 X86FeatureMMX
253 X86FeatureFXSR
254 X86FeatureSSE
255 X86FeatureSSE2
256 X86FeatureSS
257 X86FeatureHTT
258 X86FeatureTM
259 X86FeatureIA64
260 X86FeaturePBE
261 )
262
263 // Block 2 bits are the "structured extended" features returned in ebx for
264 // eax=7, ecx=0.
265 const (
266 X86FeatureFSGSBase Feature = 2*32 + iota
267 X86FeatureTSC_ADJUST
268 _ // ebx bit 2 is reserved.
269 X86FeatureBMI1
270 X86FeatureHLE
271 X86FeatureAVX2
272 X86FeatureFDP_EXCPTN_ONLY
273 X86FeatureSMEP
274 X86FeatureBMI2
275 X86FeatureERMS
276 X86FeatureINVPCID
277 X86FeatureRTM
278 X86FeatureCQM
279 X86FeatureFPCSDS
280 X86FeatureMPX
281 X86FeatureRDT
282 X86FeatureAVX512F
283 X86FeatureAVX512DQ
284 X86FeatureRDSEED
285 X86FeatureADX
286 X86FeatureSMAP
287 X86FeatureAVX512IFMA
288 X86FeaturePCOMMIT
289 X86FeatureCLFLUSHOPT
290 X86FeatureCLWB
291 X86FeatureIPT // Intel processor trace.
292 X86FeatureAVX512PF
293 X86FeatureAVX512ER
294 X86FeatureAVX512CD
295 X86FeatureSHA
296 X86FeatureAVX512BW
297 X86FeatureAVX512VL
298 )
299
300 // Block 3 bits are the "extended" features returned in ecx for eax=7, ecx=0.
301 const (
302 X86FeaturePREFETCHWT1 Feature = 3*32 + iota
303 X86FeatureAVX512VBMI
304 X86FeatureUMIP
305 X86FeaturePKU
306 X86FeatureOSPKE
307 X86FeatureWAITPKG
308 X86FeatureAVX512_VBMI2
309 X86FeatureCET_SS
310 X86FeatureGFNI
311 X86FeatureVAES
312 X86FeatureVPCLMULQDQ
313 X86FeatureAVX512_VNNI
314 X86FeatureAVX512_BITALG
315 X86FeatureTME
316 X86FeatureAVX512_VPOPCNTDQ
317 _ // ecx bit 15 is reserved
318 X86FeatureLA57
319 // ecx bits 17-21 are reserved
320 _
321 _
322 _
323 _
324 _
325 X86FeatureRDPID
326 // ecx bits 23-24 are reserved
327 _
328 _
329 X86FeatureCLDEMOTE
330 _ // ecx bit 26 is reserved
331 X86FeatureMOVDIRI
332 X86FeatureMOVDIR64B
333 )
334
335 // Block 4 constants are for xsave capabilities in CPUID.(EAX=0DH,ECX=01H):EAX.
336 // The CPUID leaf is available only if 'X86FeatureXSAVE' is present.
337 const (
338 X86FeatureXSAVEOPT Feature = 4*32 + iota
339 X86FeatureXSAVEC
340 X86FeatureXGETBV1
341 X86FeatureXSAVES
342 // EAX[31:4] are reserved.
343 )
344
345 // Block 5 constants are the extended feature bits in
346 // CPUID.(EAX=0x80000001):ECX.
347 const (
348 X86FeatureLAHF64 Feature = 5*32 + iota
349 X86FeatureCMP_LEGACY
350 X86FeatureSVM
351 X86FeatureEXTAPIC
352 X86FeatureCR8_LEGACY
353 X86FeatureLZCNT
354 X86FeatureSSE4A
355 X86FeatureMISALIGNSSE
356 X86FeaturePREFETCHW
357 X86FeatureOSVW
358 X86FeatureIBS
359 X86FeatureXOP
360 X86FeatureSKINIT
361 X86FeatureWDT
362 _ // ecx bit 14 is reserved.
363 X86FeatureLWP
364 X86FeatureFMA4
365 X86FeatureTCE
366 _ // ecx bit 18 is reserved.
367 _ // ecx bit 19 is reserved.
368 _ // ecx bit 20 is reserved.
369 X86FeatureTBM
370 X86FeatureTOPOLOGY
371 X86FeaturePERFCTR_CORE
372 X86FeaturePERFCTR_NB
373 _ // ecx bit 25 is reserved.
374 X86FeatureBPEXT
375 X86FeaturePERFCTR_TSC
376 X86FeaturePERFCTR_LLC
377 X86FeatureMWAITX
378 X86FeatureADMSKEXTN
379 _ // ecx bit 31 is reserved.
380 )
381
382 // Block 6 constants are the extended feature bits in
383 // CPUID.(EAX=0x80000001):EDX.
384 //
385 // These are sparse, and so the bit positions are assigned manually.
386 const (
387 // On AMD, EDX[24:23] | EDX[17:12] | EDX[9:0] are duplicate features
388 // also defined in block 1 (in identical bit positions). Those features
389 // are not listed here.
390 block6DuplicateMask = 0x183f3ff
391
392 X86FeatureSYSCALL Feature = 6*32 + 11
393 X86FeatureNX Feature = 6*32 + 20
394 X86FeatureMMXEXT Feature = 6*32 + 22
395 X86FeatureFXSR_OPT Feature = 6*32 + 25
396 X86FeatureGBPAGES Feature = 6*32 + 26
397 X86FeatureRDTSCP Feature = 6*32 + 27
398 X86FeatureLM Feature = 6*32 + 29
399 X86Feature3DNOWEXT Feature = 6*32 + 30
400 X86Feature3DNOW Feature = 6*32 + 31
401 )
402
403 // Block 7 constants are the extended features bits in
404 // CPUID.(EAX=07H,ECX=0):EDX.
405 const (
406 _ Feature = 7*32 + iota // edx bit 0 is reserved.
407 _ // edx bit 1 is reserved.
408 X86FeatureAVX512_4VNNIW
409 X86FeatureAVX512_4FMAPS
410 X86FeatureFSRM
411 _ // edx bit 5 is not used in Linux.
412 _ // edx bit 6 is reserved.
413 _ // edx bit 7 is reserved.
414 X86FeatureAVX512_VP2INTERSECT
415 X86FeatureSRBDS_CTRL
416 X86FeatureMD_CLEAR
417 X86FeatureRTM_ALWAYS_ABORT
418 _ // edx bit 12 is reserved.
419 X86FeatureTSX_FORCE_ABORT
420 X86FeatureSERIALIZE
421 X86FeatureHYBRID_CPU
422 X86FeatureTSXLDTRK
423 _ // edx bit 17 is reserved.
424 X86FeaturePCONFIG
425 X86FeatureARCH_LBR
426 X86FeatureIBT
427 _ // edx bit 21 is reserved.
428 X86FeatureAMX_BF16
429 X86FeatureAVX512_FP16
430 X86FeatureAMX_TILE
431 X86FeatureAMX_INT8
432 X86FeatureSPEC_CTRL
433 X86FeatureINTEL_STIBP
434 X86FeatureFLUSH_L1D
435 X86FeatureARCH_CAPABILITIES
436 X86FeatureCORE_CAPABILITIES
437 X86FeatureSPEC_CTRL_SSBD
438 )
439
440 // These are the extended floating point state features. They are used to
441 // enumerate floating point features in XCR0, XSTATE_BV, etc.
442 const (
443 XSAVEFeatureX87 = 1 << 0
444 XSAVEFeatureSSE = 1 << 1
445 XSAVEFeatureAVX = 1 << 2
446 XSAVEFeatureBNDREGS = 1 << 3
447 XSAVEFeatureBNDCSR = 1 << 4
448 XSAVEFeatureAVX512op = 1 << 5
449 XSAVEFeatureAVX512zmm0 = 1 << 6
450 XSAVEFeatureAVX512zmm16 = 1 << 7
451 XSAVEFeaturePKRU = 1 << 9
452 )
453
454 // allFeatures is the set of allFeatures.
455 //
456 // These match names used in arch/x86/kernel/cpu/capflags.c.
457 var allFeatures = map[Feature]allFeatureInfo{
458 // Block 0.
459 X86FeatureSSE3: {"pni", true},
460 X86FeaturePCLMULDQ: {"pclmulqdq", true},
461 X86FeatureDTES64: {"dtes64", true},
462 X86FeatureMONITOR: {"monitor", true},
463 X86FeatureDSCPL: {"ds_cpl", true},
464 X86FeatureVMX: {"vmx", true},
465 X86FeatureSMX: {"smx", true},
466 X86FeatureEST: {"est", true},
467 X86FeatureTM2: {"tm2", true},
468 X86FeatureSSSE3: {"ssse3", true},
469 X86FeatureCNXTID: {"cid", true},
470 X86FeatureSDBG: {"sdbg", true},
471 X86FeatureFMA: {"fma", true},
472 X86FeatureCX16: {"cx16", true},
473 X86FeatureXTPR: {"xtpr", true},
474 X86FeaturePDCM: {"pdcm", true},
475 X86FeaturePCID: {"pcid", true},
476 X86FeatureDCA: {"dca", true},
477 X86FeatureSSE4_1: {"sse4_1", true},
478 X86FeatureSSE4_2: {"sse4_2", true},
479 X86FeatureX2APIC: {"x2apic", true},
480 X86FeatureMOVBE: {"movbe", true},
481 X86FeaturePOPCNT: {"popcnt", true},
482 X86FeatureTSCD: {"tsc_deadline_timer", true},
483 X86FeatureAES: {"aes", true},
484 X86FeatureXSAVE: {"xsave", true},
485 X86FeatureAVX: {"avx", true},
486 X86FeatureF16C: {"f16c", true},
487 X86FeatureRDRAND: {"rdrand", true},
488 X86FeatureHypervisor: {"hypervisor", true},
489 X86FeatureOSXSAVE: {"osxsave", false},
490
491 // Block 1.
492 X86FeatureFPU: {"fpu", true},
493 X86FeatureVME: {"vme", true},
494 X86FeatureDE: {"de", true},
495 X86FeaturePSE: {"pse", true},
496 X86FeatureTSC: {"tsc", true},
497 X86FeatureMSR: {"msr", true},
498 X86FeaturePAE: {"pae", true},
499 X86FeatureMCE: {"mce", true},
500 X86FeatureCX8: {"cx8", true},
501 X86FeatureAPIC: {"apic", true},
502 X86FeatureSEP: {"sep", true},
503 X86FeatureMTRR: {"mtrr", true},
504 X86FeaturePGE: {"pge", true},
505 X86FeatureMCA: {"mca", true},
506 X86FeatureCMOV: {"cmov", true},
507 X86FeaturePAT: {"pat", true},
508 X86FeaturePSE36: {"pse36", true},
509 X86FeaturePSN: {"pn", true},
510 X86FeatureCLFSH: {"clflush", true},
511 X86FeatureDS: {"dts", true},
512 X86FeatureACPI: {"acpi", true},
513 X86FeatureMMX: {"mmx", true},
514 X86FeatureFXSR: {"fxsr", true},
515 X86FeatureSSE: {"sse", true},
516 X86FeatureSSE2: {"sse2", true},
517 X86FeatureSS: {"ss", true},
518 X86FeatureHTT: {"ht", true},
519 X86FeatureTM: {"tm", true},
520 X86FeatureIA64: {"ia64", true},
521 X86FeaturePBE: {"pbe", true},
522
523 // Block 2.
524 X86FeatureFSGSBase: {"fsgsbase", true},
525 X86FeatureTSC_ADJUST: {"tsc_adjust", true},
526 X86FeatureBMI1: {"bmi1", true},
527 X86FeatureHLE: {"hle", true},
528 X86FeatureAVX2: {"avx2", true},
529 X86FeatureSMEP: {"smep", true},
530 X86FeatureBMI2: {"bmi2", true},
531 X86FeatureERMS: {"erms", true},
532 X86FeatureINVPCID: {"invpcid", true},
533 X86FeatureRTM: {"rtm", true},
534 X86FeatureCQM: {"cqm", true},
535 X86FeatureMPX: {"mpx", true},
536 X86FeatureRDT: {"rdt_a", true},
537 X86FeatureAVX512F: {"avx512f", true},
538 X86FeatureAVX512DQ: {"avx512dq", true},
539 X86FeatureRDSEED: {"rdseed", true},
540 X86FeatureADX: {"adx", true},
541 X86FeatureSMAP: {"smap", true},
542 X86FeatureCLWB: {"clwb", true},
543 X86FeatureAVX512PF: {"avx512pf", true},
544 X86FeatureAVX512ER: {"avx512er", true},
545 X86FeatureAVX512CD: {"avx512cd", true},
546 X86FeatureSHA: {"sha_ni", true},
547 X86FeatureAVX512BW: {"avx512bw", true},
548 X86FeatureAVX512VL: {"avx512vl", true},
549 X86FeatureFDP_EXCPTN_ONLY: {"fdp_excptn_only", false},
550 X86FeatureFPCSDS: {"fpcsds", false},
551 X86FeatureIPT: {"ipt", false},
552 X86FeatureCLFLUSHOPT: {"clfushopt", false},
553
554 // Block 3.
555 X86FeatureAVX512VBMI: {"avx512vbmi", true},
556 X86FeatureUMIP: {"umip", true},
557 X86FeaturePKU: {"pku", true},
558 X86FeatureOSPKE: {"ospke", true},
559 X86FeatureWAITPKG: {"waitpkg", true},
560 X86FeatureAVX512_VBMI2: {"avx512_vbmi2", true},
561 X86FeatureGFNI: {"gfni", true},
562 X86FeatureCET_SS: {"cet_ss", false},
563 X86FeatureVAES: {"vaes", true},
564 X86FeatureVPCLMULQDQ: {"vpclmulqdq", true},
565 X86FeatureAVX512_VNNI: {"avx512_vnni", true},
566 X86FeatureAVX512_BITALG: {"avx512_bitalg", true},
567 X86FeatureTME: {"tme", true},
568 X86FeatureAVX512_VPOPCNTDQ: {"avx512_vpopcntdq", true},
569 X86FeatureLA57: {"la57", true},
570 X86FeatureRDPID: {"rdpid", true},
571 X86FeatureCLDEMOTE: {"cldemote", true},
572 X86FeatureMOVDIRI: {"movdiri", true},
573 X86FeatureMOVDIR64B: {"movdir64b", true},
574 X86FeaturePREFETCHWT1: {"prefetchwt1", false},
575
576 // Block 4.
577 X86FeatureXSAVEOPT: {"xsaveopt", true},
578 X86FeatureXSAVEC: {"xsavec", true},
579 X86FeatureXGETBV1: {"xgetbv1", true},
580 X86FeatureXSAVES: {"xsaves", true},
581
582 // Block 5.
583 X86FeatureLAHF64: {"lahf_lm", true}, // LAHF/SAHF in long mode.
584 X86FeatureCMP_LEGACY: {"cmp_legacy", true},
585 X86FeatureSVM: {"svm", true},
586 X86FeatureEXTAPIC: {"extapic", true},
587 X86FeatureCR8_LEGACY: {"cr8_legacy", true},
588 X86FeatureLZCNT: {"abm", true}, // Advanced bit manipulation.
589 X86FeatureSSE4A: {"sse4a", true},
590 X86FeatureMISALIGNSSE: {"misalignsse", true},
591 X86FeaturePREFETCHW: {"3dnowprefetch", true},
592 X86FeatureOSVW: {"osvw", true},
593 X86FeatureIBS: {"ibs", true},
594 X86FeatureXOP: {"xop", true},
595 X86FeatureSKINIT: {"skinit", true},
596 X86FeatureWDT: {"wdt", true},
597 X86FeatureLWP: {"lwp", true},
598 X86FeatureFMA4: {"fma4", true},
599 X86FeatureTCE: {"tce", true},
600 X86FeatureTBM: {"tbm", true},
601 X86FeatureTOPOLOGY: {"topoext", true},
602 X86FeaturePERFCTR_CORE: {"perfctr_core", true},
603 X86FeaturePERFCTR_NB: {"perfctr_nb", true},
604 X86FeatureBPEXT: {"bpext", true},
605 X86FeaturePERFCTR_TSC: {"ptsc", true},
606 X86FeaturePERFCTR_LLC: {"perfctr_llc", true},
607 X86FeatureMWAITX: {"mwaitx", true},
608 X86FeatureADMSKEXTN: {"ad_mask_extn", false},
609
610 // Block 6.
611 X86FeatureSYSCALL: {"syscall", true},
612 X86FeatureNX: {"nx", true},
613 X86FeatureMMXEXT: {"mmxext", true},
614 X86FeatureFXSR_OPT: {"fxsr_opt", true},
615 X86FeatureGBPAGES: {"pdpe1gb", true},
616 X86FeatureRDTSCP: {"rdtscp", true},
617 X86FeatureLM: {"lm", true},
618 X86Feature3DNOWEXT: {"3dnowext", true},
619 X86Feature3DNOW: {"3dnow", true},
620
621 // Block 7.
622 X86FeatureAVX512_4VNNIW: {"avx512_4vnniw", true},
623 X86FeatureAVX512_4FMAPS: {"avx512_4fmaps", true},
624 X86FeatureFSRM: {"fsrm", true},
625 X86FeatureAVX512_VP2INTERSECT: {"avx512_vp2intersect", true},
626 X86FeatureSRBDS_CTRL: {"srbds_ctrl", false},
627 X86FeatureMD_CLEAR: {"md_clear", true},
628 X86FeatureRTM_ALWAYS_ABORT: {"rtm_always_abort", false},
629 X86FeatureTSX_FORCE_ABORT: {"tsx_force_abort", false},
630 X86FeatureSERIALIZE: {"serialize", true},
631 X86FeatureHYBRID_CPU: {"hybrid_cpu", false},
632 X86FeatureTSXLDTRK: {"tsxldtrk", true},
633 X86FeaturePCONFIG: {"pconfig", true},
634 X86FeatureARCH_LBR: {"arch_lbr", true},
635 X86FeatureIBT: {"ibt", true},
636 X86FeatureAMX_BF16: {"amx_bf16", true},
637 X86FeatureAVX512_FP16: {"avx512_fp16", true},
638 X86FeatureAMX_TILE: {"amx_tile", true},
639 X86FeatureAMX_INT8: {"amx_int8", true},
640 X86FeatureSPEC_CTRL: {"spec_ctrl", false},
641 X86FeatureINTEL_STIBP: {"intel_stibp", false},
642 X86FeatureFLUSH_L1D: {"flush_l1d", true},
643 X86FeatureARCH_CAPABILITIES: {"arch_capabilities", true},
644 X86FeatureCORE_CAPABILITIES: {"core_capabilities", false},
645 X86FeatureSPEC_CTRL_SSBD: {"spec_ctrl_ssbd", false},
646 }
647
648 // linuxBlockOrder defines the order in which linux organizes the feature
649 // blocks. Linux also tracks feature bits in 32-bit blocks, but in an order
650 // which doesn't match well here, so for the /proc/cpuinfo generation we simply
651 // re-map the blocks to Linux's ordering and then go through the bits in each
652 // block.
653 var linuxBlockOrder = []block{1, 6, 0, 5, 2, 4, 3, 7}
654
655 func archFlagOrder(fn func(Feature)) {
656 for _, b := range linuxBlockOrder {
657 for i := 0; i < blockSize; i++ {
658 f := featureID(b, i)
659 if _, ok := allFeatures[f]; ok {
660 fn(f)
661 }
662 }
663 }
664 }
665