gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/cpuid/features_amd64.go (about) 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 }