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