github.com/ttpreport/gvisor-ligolo@v0.0.0-20240123134145-a858404967ba/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  	}
   131  }
   132  
   133  // check checks for the given feature.
   134  //
   135  //go:nosplit
   136  func (f Feature) check(fs FeatureSet) bool {
   137  	switch f.block() {
   138  	case 0:
   139  		_, _, cx, _ := fs.query(featureInfo)
   140  		return (cx & f.bit()) != 0
   141  	case 1:
   142  		_, _, _, dx := fs.query(featureInfo)
   143  		return (dx & f.bit()) != 0
   144  	case 2:
   145  		_, bx, _, _ := fs.query(extendedFeatureInfo)
   146  		return (bx & f.bit()) != 0
   147  	case 3:
   148  		_, _, cx, _ := fs.query(extendedFeatureInfo)
   149  		return (cx & f.bit()) != 0
   150  	case 4:
   151  		// Need to check appropriate bit in block 0.
   152  		_, _, cx, _ := fs.query(featureInfo)
   153  		if (cx & (1 << 26)) == 0 {
   154  			return false
   155  		}
   156  		ax, _, _, _ := fs.query(xSaveInfoSub)
   157  		return (ax & f.bit()) != 0
   158  	case 5, 6:
   159  		// eax=0x80000000 gets supported extended levels. We use this
   160  		// to determine if there are any non-zero block 4 or block 6
   161  		// bits to find.
   162  		ax, _, _, _ := fs.query(extendedFunctionInfo)
   163  		if ax >= uint32(extendedFeatures) {
   164  			_, _, cx, dx := fs.query(extendedFeatures)
   165  			if f.block() == 5 {
   166  				return (cx & f.bit()) != 0
   167  			}
   168  			// Ignore features duplicated from block 1 on AMD.
   169  			// These bits are reserved on Intel.
   170  			return ((dx &^ block6DuplicateMask) & f.bit()) != 0
   171  		}
   172  		return false
   173  	default:
   174  		return false
   175  	}
   176  }
   177  
   178  // Block 0 constants are all of the "basic" feature bits returned by a cpuid in
   179  // ecx with eax=1.
   180  const (
   181  	X86FeatureSSE3 Feature = iota
   182  	X86FeaturePCLMULDQ
   183  	X86FeatureDTES64
   184  	X86FeatureMONITOR
   185  	X86FeatureDSCPL
   186  	X86FeatureVMX
   187  	X86FeatureSMX
   188  	X86FeatureEST
   189  	X86FeatureTM2
   190  	X86FeatureSSSE3 // Not a typo, "supplemental" SSE3.
   191  	X86FeatureCNXTID
   192  	X86FeatureSDBG
   193  	X86FeatureFMA
   194  	X86FeatureCX16
   195  	X86FeatureXTPR
   196  	X86FeaturePDCM
   197  	_ // ecx bit 16 is reserved.
   198  	X86FeaturePCID
   199  	X86FeatureDCA
   200  	X86FeatureSSE4_1
   201  	X86FeatureSSE4_2
   202  	X86FeatureX2APIC
   203  	X86FeatureMOVBE
   204  	X86FeaturePOPCNT
   205  	X86FeatureTSCD
   206  	X86FeatureAES
   207  	X86FeatureXSAVE
   208  	X86FeatureOSXSAVE
   209  	X86FeatureAVX
   210  	X86FeatureF16C
   211  	X86FeatureRDRAND
   212  	X86FeatureHypervisor
   213  )
   214  
   215  // Block 1 constants are all of the "basic" feature bits returned by a cpuid in
   216  // edx with eax=1.
   217  const (
   218  	X86FeatureFPU Feature = 32 + iota
   219  	X86FeatureVME
   220  	X86FeatureDE
   221  	X86FeaturePSE
   222  	X86FeatureTSC
   223  	X86FeatureMSR
   224  	X86FeaturePAE
   225  	X86FeatureMCE
   226  	X86FeatureCX8
   227  	X86FeatureAPIC
   228  	_ // edx bit 10 is reserved.
   229  	X86FeatureSEP
   230  	X86FeatureMTRR
   231  	X86FeaturePGE
   232  	X86FeatureMCA
   233  	X86FeatureCMOV
   234  	X86FeaturePAT
   235  	X86FeaturePSE36
   236  	X86FeaturePSN
   237  	X86FeatureCLFSH
   238  	_ // edx bit 20 is reserved.
   239  	X86FeatureDS
   240  	X86FeatureACPI
   241  	X86FeatureMMX
   242  	X86FeatureFXSR
   243  	X86FeatureSSE
   244  	X86FeatureSSE2
   245  	X86FeatureSS
   246  	X86FeatureHTT
   247  	X86FeatureTM
   248  	X86FeatureIA64
   249  	X86FeaturePBE
   250  )
   251  
   252  // Block 2 bits are the "structured extended" features returned in ebx for
   253  // eax=7, ecx=0.
   254  const (
   255  	X86FeatureFSGSBase Feature = 2*32 + iota
   256  	X86FeatureTSC_ADJUST
   257  	_ // ebx bit 2 is reserved.
   258  	X86FeatureBMI1
   259  	X86FeatureHLE
   260  	X86FeatureAVX2
   261  	X86FeatureFDP_EXCPTN_ONLY
   262  	X86FeatureSMEP
   263  	X86FeatureBMI2
   264  	X86FeatureERMS
   265  	X86FeatureINVPCID
   266  	X86FeatureRTM
   267  	X86FeatureCQM
   268  	X86FeatureFPCSDS
   269  	X86FeatureMPX
   270  	X86FeatureRDT
   271  	X86FeatureAVX512F
   272  	X86FeatureAVX512DQ
   273  	X86FeatureRDSEED
   274  	X86FeatureADX
   275  	X86FeatureSMAP
   276  	X86FeatureAVX512IFMA
   277  	X86FeaturePCOMMIT
   278  	X86FeatureCLFLUSHOPT
   279  	X86FeatureCLWB
   280  	X86FeatureIPT // Intel processor trace.
   281  	X86FeatureAVX512PF
   282  	X86FeatureAVX512ER
   283  	X86FeatureAVX512CD
   284  	X86FeatureSHA
   285  	X86FeatureAVX512BW
   286  	X86FeatureAVX512VL
   287  )
   288  
   289  // Block 3 bits are the "extended" features returned in ecx for eax=7, ecx=0.
   290  const (
   291  	X86FeaturePREFETCHWT1 Feature = 3*32 + iota
   292  	X86FeatureAVX512VBMI
   293  	X86FeatureUMIP
   294  	X86FeaturePKU
   295  	X86FeatureOSPKE
   296  	X86FeatureWAITPKG
   297  	X86FeatureAVX512_VBMI2
   298  	X86FeatureCET_SS
   299  	X86FeatureGFNI
   300  	X86FeatureVAES
   301  	X86FeatureVPCLMULQDQ
   302  	X86FeatureAVX512_VNNI
   303  	X86FeatureAVX512_BITALG
   304  	X86FeatureTME
   305  	X86FeatureAVX512_VPOPCNTDQ
   306  	_ // ecx bit 15 is reserved
   307  	X86FeatureLA57
   308  	// ecx bits 17-21 are reserved
   309  	_
   310  	_
   311  	_
   312  	_
   313  	_
   314  	X86FeatureRDPID
   315  	// ecx bits 23-24 are reserved
   316  	_
   317  	_
   318  	X86FeatureCLDEMOTE
   319  	_ // ecx bit 26 is reserved
   320  	X86FeatureMOVDIRI
   321  	X86FeatureMOVDIR64B
   322  )
   323  
   324  // Block 4 constants are for xsave capabilities in CPUID.(EAX=0DH,ECX=01H):EAX.
   325  // The CPUID leaf is available only if 'X86FeatureXSAVE' is present.
   326  const (
   327  	X86FeatureXSAVEOPT Feature = 4*32 + iota
   328  	X86FeatureXSAVEC
   329  	X86FeatureXGETBV1
   330  	X86FeatureXSAVES
   331  	// EAX[31:4] are reserved.
   332  )
   333  
   334  // Block 5 constants are the extended feature bits in
   335  // CPUID.(EAX=0x80000001):ECX.
   336  const (
   337  	X86FeatureLAHF64 Feature = 5*32 + iota
   338  	X86FeatureCMP_LEGACY
   339  	X86FeatureSVM
   340  	X86FeatureEXTAPIC
   341  	X86FeatureCR8_LEGACY
   342  	X86FeatureLZCNT
   343  	X86FeatureSSE4A
   344  	X86FeatureMISALIGNSSE
   345  	X86FeaturePREFETCHW
   346  	X86FeatureOSVW
   347  	X86FeatureIBS
   348  	X86FeatureXOP
   349  	X86FeatureSKINIT
   350  	X86FeatureWDT
   351  	_ // ecx bit 14 is reserved.
   352  	X86FeatureLWP
   353  	X86FeatureFMA4
   354  	X86FeatureTCE
   355  	_ // ecx bit 18 is reserved.
   356  	_ // ecx bit 19 is reserved.
   357  	_ // ecx bit 20 is reserved.
   358  	X86FeatureTBM
   359  	X86FeatureTOPOLOGY
   360  	X86FeaturePERFCTR_CORE
   361  	X86FeaturePERFCTR_NB
   362  	_ // ecx bit 25 is reserved.
   363  	X86FeatureBPEXT
   364  	X86FeaturePERFCTR_TSC
   365  	X86FeaturePERFCTR_LLC
   366  	X86FeatureMWAITX
   367  	X86FeatureADMSKEXTN
   368  	_ // ecx bit 31 is reserved.
   369  )
   370  
   371  // Block 6 constants are the extended feature bits in
   372  // CPUID.(EAX=0x80000001):EDX.
   373  //
   374  // These are sparse, and so the bit positions are assigned manually.
   375  const (
   376  	// On AMD, EDX[24:23] | EDX[17:12] | EDX[9:0] are duplicate features
   377  	// also defined in block 1 (in identical bit positions). Those features
   378  	// are not listed here.
   379  	block6DuplicateMask = 0x183f3ff
   380  
   381  	X86FeatureSYSCALL  Feature = 6*32 + 11
   382  	X86FeatureNX       Feature = 6*32 + 20
   383  	X86FeatureMMXEXT   Feature = 6*32 + 22
   384  	X86FeatureFXSR_OPT Feature = 6*32 + 25
   385  	X86FeatureGBPAGES  Feature = 6*32 + 26
   386  	X86FeatureRDTSCP   Feature = 6*32 + 27
   387  	X86FeatureLM       Feature = 6*32 + 29
   388  	X86Feature3DNOWEXT Feature = 6*32 + 30
   389  	X86Feature3DNOW    Feature = 6*32 + 31
   390  )
   391  
   392  // These are the extended floating point state features. They are used to
   393  // enumerate floating point features in XCR0, XSTATE_BV, etc.
   394  const (
   395  	XSAVEFeatureX87         = 1 << 0
   396  	XSAVEFeatureSSE         = 1 << 1
   397  	XSAVEFeatureAVX         = 1 << 2
   398  	XSAVEFeatureBNDREGS     = 1 << 3
   399  	XSAVEFeatureBNDCSR      = 1 << 4
   400  	XSAVEFeatureAVX512op    = 1 << 5
   401  	XSAVEFeatureAVX512zmm0  = 1 << 6
   402  	XSAVEFeatureAVX512zmm16 = 1 << 7
   403  	XSAVEFeaturePKRU        = 1 << 9
   404  )
   405  
   406  // allFeatures is the set of allFeatures.
   407  //
   408  // These match names used in arch/x86/kernel/cpu/capflags.c.
   409  var allFeatures = map[Feature]allFeatureInfo{
   410  	// Block 0.
   411  	X86FeatureSSE3:       {"pni", true},
   412  	X86FeaturePCLMULDQ:   {"pclmulqdq", true},
   413  	X86FeatureDTES64:     {"dtes64", true},
   414  	X86FeatureMONITOR:    {"monitor", true},
   415  	X86FeatureDSCPL:      {"ds_cpl", true},
   416  	X86FeatureVMX:        {"vmx", true},
   417  	X86FeatureSMX:        {"smx", true},
   418  	X86FeatureEST:        {"est", true},
   419  	X86FeatureTM2:        {"tm2", true},
   420  	X86FeatureSSSE3:      {"ssse3", true},
   421  	X86FeatureCNXTID:     {"cid", true},
   422  	X86FeatureSDBG:       {"sdbg", true},
   423  	X86FeatureFMA:        {"fma", true},
   424  	X86FeatureCX16:       {"cx16", true},
   425  	X86FeatureXTPR:       {"xtpr", true},
   426  	X86FeaturePDCM:       {"pdcm", true},
   427  	X86FeaturePCID:       {"pcid", true},
   428  	X86FeatureDCA:        {"dca", true},
   429  	X86FeatureSSE4_1:     {"sse4_1", true},
   430  	X86FeatureSSE4_2:     {"sse4_2", true},
   431  	X86FeatureX2APIC:     {"x2apic", true},
   432  	X86FeatureMOVBE:      {"movbe", true},
   433  	X86FeaturePOPCNT:     {"popcnt", true},
   434  	X86FeatureTSCD:       {"tsc_deadline_timer", true},
   435  	X86FeatureAES:        {"aes", true},
   436  	X86FeatureXSAVE:      {"xsave", true},
   437  	X86FeatureAVX:        {"avx", true},
   438  	X86FeatureF16C:       {"f16c", true},
   439  	X86FeatureRDRAND:     {"rdrand", true},
   440  	X86FeatureHypervisor: {"hypervisor", true},
   441  	X86FeatureOSXSAVE:    {"osxsave", false},
   442  
   443  	// Block 1.
   444  	X86FeatureFPU:   {"fpu", true},
   445  	X86FeatureVME:   {"vme", true},
   446  	X86FeatureDE:    {"de", true},
   447  	X86FeaturePSE:   {"pse", true},
   448  	X86FeatureTSC:   {"tsc", true},
   449  	X86FeatureMSR:   {"msr", true},
   450  	X86FeaturePAE:   {"pae", true},
   451  	X86FeatureMCE:   {"mce", true},
   452  	X86FeatureCX8:   {"cx8", true},
   453  	X86FeatureAPIC:  {"apic", true},
   454  	X86FeatureSEP:   {"sep", true},
   455  	X86FeatureMTRR:  {"mtrr", true},
   456  	X86FeaturePGE:   {"pge", true},
   457  	X86FeatureMCA:   {"mca", true},
   458  	X86FeatureCMOV:  {"cmov", true},
   459  	X86FeaturePAT:   {"pat", true},
   460  	X86FeaturePSE36: {"pse36", true},
   461  	X86FeaturePSN:   {"pn", true},
   462  	X86FeatureCLFSH: {"clflush", true},
   463  	X86FeatureDS:    {"dts", true},
   464  	X86FeatureACPI:  {"acpi", true},
   465  	X86FeatureMMX:   {"mmx", true},
   466  	X86FeatureFXSR:  {"fxsr", true},
   467  	X86FeatureSSE:   {"sse", true},
   468  	X86FeatureSSE2:  {"sse2", true},
   469  	X86FeatureSS:    {"ss", true},
   470  	X86FeatureHTT:   {"ht", true},
   471  	X86FeatureTM:    {"tm", true},
   472  	X86FeatureIA64:  {"ia64", true},
   473  	X86FeaturePBE:   {"pbe", true},
   474  
   475  	// Block 2.
   476  	X86FeatureFSGSBase:        {"fsgsbase", true},
   477  	X86FeatureTSC_ADJUST:      {"tsc_adjust", true},
   478  	X86FeatureBMI1:            {"bmi1", true},
   479  	X86FeatureHLE:             {"hle", true},
   480  	X86FeatureAVX2:            {"avx2", true},
   481  	X86FeatureSMEP:            {"smep", true},
   482  	X86FeatureBMI2:            {"bmi2", true},
   483  	X86FeatureERMS:            {"erms", true},
   484  	X86FeatureINVPCID:         {"invpcid", true},
   485  	X86FeatureRTM:             {"rtm", true},
   486  	X86FeatureCQM:             {"cqm", true},
   487  	X86FeatureMPX:             {"mpx", true},
   488  	X86FeatureRDT:             {"rdt_a", true},
   489  	X86FeatureAVX512F:         {"avx512f", true},
   490  	X86FeatureAVX512DQ:        {"avx512dq", true},
   491  	X86FeatureRDSEED:          {"rdseed", true},
   492  	X86FeatureADX:             {"adx", true},
   493  	X86FeatureSMAP:            {"smap", true},
   494  	X86FeatureCLWB:            {"clwb", true},
   495  	X86FeatureAVX512PF:        {"avx512pf", true},
   496  	X86FeatureAVX512ER:        {"avx512er", true},
   497  	X86FeatureAVX512CD:        {"avx512cd", true},
   498  	X86FeatureSHA:             {"sha_ni", true},
   499  	X86FeatureAVX512BW:        {"avx512bw", true},
   500  	X86FeatureAVX512VL:        {"avx512vl", true},
   501  	X86FeatureFDP_EXCPTN_ONLY: {"fdp_excptn_only", false},
   502  	X86FeatureFPCSDS:          {"fpcsds", false},
   503  	X86FeatureIPT:             {"ipt", false},
   504  	X86FeatureCLFLUSHOPT:      {"clfushopt", false},
   505  
   506  	// Block 3.
   507  	X86FeatureAVX512VBMI:       {"avx512vbmi", true},
   508  	X86FeatureUMIP:             {"umip", true},
   509  	X86FeaturePKU:              {"pku", true},
   510  	X86FeatureOSPKE:            {"ospke", true},
   511  	X86FeatureWAITPKG:          {"waitpkg", true},
   512  	X86FeatureAVX512_VBMI2:     {"avx512_vbmi2", true},
   513  	X86FeatureGFNI:             {"gfni", true},
   514  	X86FeatureCET_SS:           {"cet_ss", false},
   515  	X86FeatureVAES:             {"vaes", true},
   516  	X86FeatureVPCLMULQDQ:       {"vpclmulqdq", true},
   517  	X86FeatureAVX512_VNNI:      {"avx512_vnni", true},
   518  	X86FeatureAVX512_BITALG:    {"avx512_bitalg", true},
   519  	X86FeatureTME:              {"tme", true},
   520  	X86FeatureAVX512_VPOPCNTDQ: {"avx512_vpopcntdq", true},
   521  	X86FeatureLA57:             {"la57", true},
   522  	X86FeatureRDPID:            {"rdpid", true},
   523  	X86FeatureCLDEMOTE:         {"cldemote", true},
   524  	X86FeatureMOVDIRI:          {"movdiri", true},
   525  	X86FeatureMOVDIR64B:        {"movdir64b", true},
   526  	X86FeaturePREFETCHWT1:      {"prefetchwt1", false},
   527  
   528  	// Block 4.
   529  	X86FeatureXSAVEOPT: {"xsaveopt", true},
   530  	X86FeatureXSAVEC:   {"xsavec", true},
   531  	X86FeatureXGETBV1:  {"xgetbv1", true},
   532  	X86FeatureXSAVES:   {"xsaves", true},
   533  
   534  	// Block 5.
   535  	X86FeatureLAHF64:       {"lahf_lm", true}, // LAHF/SAHF in long mode.
   536  	X86FeatureCMP_LEGACY:   {"cmp_legacy", true},
   537  	X86FeatureSVM:          {"svm", true},
   538  	X86FeatureEXTAPIC:      {"extapic", true},
   539  	X86FeatureCR8_LEGACY:   {"cr8_legacy", true},
   540  	X86FeatureLZCNT:        {"abm", true}, // Advanced bit manipulation.
   541  	X86FeatureSSE4A:        {"sse4a", true},
   542  	X86FeatureMISALIGNSSE:  {"misalignsse", true},
   543  	X86FeaturePREFETCHW:    {"3dnowprefetch", true},
   544  	X86FeatureOSVW:         {"osvw", true},
   545  	X86FeatureIBS:          {"ibs", true},
   546  	X86FeatureXOP:          {"xop", true},
   547  	X86FeatureSKINIT:       {"skinit", true},
   548  	X86FeatureWDT:          {"wdt", true},
   549  	X86FeatureLWP:          {"lwp", true},
   550  	X86FeatureFMA4:         {"fma4", true},
   551  	X86FeatureTCE:          {"tce", true},
   552  	X86FeatureTBM:          {"tbm", true},
   553  	X86FeatureTOPOLOGY:     {"topoext", true},
   554  	X86FeaturePERFCTR_CORE: {"perfctr_core", true},
   555  	X86FeaturePERFCTR_NB:   {"perfctr_nb", true},
   556  	X86FeatureBPEXT:        {"bpext", true},
   557  	X86FeaturePERFCTR_TSC:  {"ptsc", true},
   558  	X86FeaturePERFCTR_LLC:  {"perfctr_llc", true},
   559  	X86FeatureMWAITX:       {"mwaitx", true},
   560  	X86FeatureADMSKEXTN:    {"ad_mask_extn", false},
   561  
   562  	// Block 6.
   563  	X86FeatureSYSCALL:  {"syscall", true},
   564  	X86FeatureNX:       {"nx", true},
   565  	X86FeatureMMXEXT:   {"mmxext", true},
   566  	X86FeatureFXSR_OPT: {"fxsr_opt", true},
   567  	X86FeatureGBPAGES:  {"pdpe1gb", true},
   568  	X86FeatureRDTSCP:   {"rdtscp", true},
   569  	X86FeatureLM:       {"lm", true},
   570  	X86Feature3DNOWEXT: {"3dnowext", true},
   571  	X86Feature3DNOW:    {"3dnow", true},
   572  }
   573  
   574  // linuxBlockOrder defines the order in which linux organizes the feature
   575  // blocks. Linux also tracks feature bits in 32-bit blocks, but in an order
   576  // which doesn't match well here, so for the /proc/cpuinfo generation we simply
   577  // re-map the blocks to Linux's ordering and then go through the bits in each
   578  // block.
   579  var linuxBlockOrder = []block{1, 6, 0, 5, 2, 4, 3}
   580  
   581  func archFlagOrder(fn func(Feature)) {
   582  	for _, b := range linuxBlockOrder {
   583  		for i := 0; i < blockSize; i++ {
   584  			f := featureID(b, i)
   585  			if _, ok := allFeatures[f]; ok {
   586  				fn(f)
   587  			}
   588  		}
   589  	}
   590  }