github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/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  }