summaryrefslogtreecommitdiff
path: root/vendor/github.com/klauspost/cpuid/v2/cpuid.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/klauspost/cpuid/v2/cpuid.go')
-rw-r--r--vendor/github.com/klauspost/cpuid/v2/cpuid.go104
1 files changed, 103 insertions, 1 deletions
diff --git a/vendor/github.com/klauspost/cpuid/v2/cpuid.go b/vendor/github.com/klauspost/cpuid/v2/cpuid.go
index 248439a9a..9cf7738a9 100644
--- a/vendor/github.com/klauspost/cpuid/v2/cpuid.go
+++ b/vendor/github.com/klauspost/cpuid/v2/cpuid.go
@@ -220,6 +220,7 @@ const (
SEV_SNP // AMD SEV Secure Nested Paging supported
SGX // Software Guard Extensions
SGXLC // Software Guard Extensions Launch Control
+ SGXPQC // Software Guard Extensions 256-bit Encryption
SHA // Intel SHA Extensions
SME // AMD Secure Memory Encryption supported
SME_COHERENT // AMD Hardware cache coherency across encryption domains enforced
@@ -255,6 +256,9 @@ const (
TLB_FLUSH_NESTED // AMD: Flushing includes all the nested translations for guest translations
TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE.
TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX.
+ TSA_L1_NO // AMD only: Not vulnerable to TSA-L1
+ TSA_SQ_NO // AM onlyD: Not vulnerable to TSA-SQ
+ TSA_VERW_CLEAR // If set, the memory form of the VERW instruction may be used to help mitigate TSA
TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104
TSXLDTRK // Intel TSX Suspend Load Address Tracking
VAES // Vector AES. AVX(512) versions requires additional checks.
@@ -304,6 +308,13 @@ const (
SM3 // SM3 instructions
SM4 // SM4 instructions
SVE // Scalable Vector Extension
+
+ // PMU
+ PMU_FIXEDCOUNTER_CYCLES
+ PMU_FIXEDCOUNTER_REFCYCLES
+ PMU_FIXEDCOUNTER_INSTRUCTIONS
+ PMU_FIXEDCOUNTER_TOPDOWN_SLOTS
+
// Keep it last. It automatically defines the size of []flagSet
lastID
@@ -336,11 +347,36 @@ type CPUInfo struct {
SGX SGXSupport
AMDMemEncryption AMDMemEncryptionSupport
AVX10Level uint8
+ PMU PerformanceMonitoringInfo // holds information about the PMU
maxFunc uint32
maxExFunc uint32
}
+// PerformanceMonitoringInfo holds information about CPU performance monitoring capabilities.
+// This is primarily populated from CPUID leaf 0xAh on x86
+type PerformanceMonitoringInfo struct {
+ // VersionID (x86 only): Version ID of architectural performance monitoring.
+ // A value of 0 means architectural performance monitoring is not supported or information is unavailable.
+ VersionID uint8
+ // NumGPPMC: Number of General-Purpose Performance Monitoring Counters per logical processor.
+ // On ARM, this is derived from PMCR_EL0.N (number of event counters).
+ NumGPCounters uint8
+ // GPPMCWidth: Bit width of General-Purpose Performance Monitoring Counters.
+ // On ARM, typically 64 for PMU event counters.
+ GPPMCWidth uint8
+ // NumFixedPMC: Number of Fixed-Function Performance Counters.
+ // Valid on x86 if VersionID > 1. On ARM, this typically includes at least the cycle counter (PMCCNTR_EL0).
+ NumFixedPMC uint8
+ // FixedPMCWidth: Bit width of Fixed-Function Performance Counters.
+ // Valid on x86 if VersionID > 1. On ARM, the cycle counter (PMCCNTR_EL0) is 64-bit.
+ FixedPMCWidth uint8
+ // Raw register output from CPUID leaf 0xAh.
+ RawEBX uint32
+ RawEAX uint32
+ RawEDX uint32
+}
+
var cpuid func(op uint32) (eax, ebx, ecx, edx uint32)
var cpuidex func(op, op2 uint32) (eax, ebx, ecx, edx uint32)
var xgetbv func(index uint32) (eax, edx uint32)
@@ -1358,6 +1394,11 @@ func support() flagSet {
fs.setIf(edx&(1<<4) != 0, BHI_CTRL)
fs.setIf(edx&(1<<5) != 0, MCDT_NO)
+ if fs.inSet(SGX) {
+ eax, _, _, _ := cpuidex(0x12, 0)
+ fs.setIf(eax&(1<<12) != 0, SGXPQC)
+ }
+
// Add keylocker features.
if fs.inSet(KEYLOCKER) && mfi >= 0x19 {
_, ebx, _, _ := cpuidex(0x19, 0)
@@ -1371,6 +1412,7 @@ func support() flagSet {
fs.setIf(ebx&(1<<17) != 0, AVX10_256)
fs.setIf(ebx&(1<<18) != 0, AVX10_512)
}
+
}
// Processor Extended State Enumeration Sub-leaf (EAX = 0DH, ECX = 1)
@@ -1514,12 +1556,28 @@ func support() flagSet {
}
if maxExtendedFunction() >= 0x80000021 && vend == AMD {
- a, _, _, _ := cpuid(0x80000021)
+ a, _, c, _ := cpuid(0x80000021)
fs.setIf((a>>31)&1 == 1, SRSO_MSR_FIX)
fs.setIf((a>>30)&1 == 1, SRSO_USER_KERNEL_NO)
fs.setIf((a>>29)&1 == 1, SRSO_NO)
fs.setIf((a>>28)&1 == 1, IBPB_BRTYPE)
fs.setIf((a>>27)&1 == 1, SBPB)
+ fs.setIf((c>>1)&1 == 1, TSA_L1_NO)
+ fs.setIf((c>>2)&1 == 1, TSA_SQ_NO)
+ fs.setIf((a>>5)&1 == 1, TSA_VERW_CLEAR)
+ }
+ if vend == AMD {
+ if family < 0x19 {
+ // AMD CPUs that are older than Family 19h are not vulnerable to TSA but do not set TSA_L1_NO or TSA_SQ_NO.
+ // Source: https://www.amd.com/content/dam/amd/en/documents/resources/bulletin/technical-guidance-for-mitigating-transient-scheduler-attacks.pdf
+ fs.set(TSA_L1_NO)
+ fs.set(TSA_SQ_NO)
+ } else if family == 0x1a {
+ // AMD Family 1Ah models 00h-4Fh and 60h-7Fh are also not vulnerable to TSA but do not set TSA_L1_NO or TSA_SQ_NO.
+ // Future AMD CPUs will set these CPUID bits if appropriate. CPUs will be designed to set these CPUID bits if appropriate.
+ notVuln := model <= 0x4f || (model >= 0x60 && model <= 0x7f)
+ fs.setIf(notVuln, TSA_L1_NO, TSA_SQ_NO)
+ }
}
if mfi >= 0x20 {
@@ -1575,3 +1633,47 @@ func valAsString(values ...uint32) []byte {
}
return r
}
+
+func parseLeaf0AH(c *CPUInfo, eax, ebx, edx uint32) (info PerformanceMonitoringInfo) {
+ info.VersionID = uint8(eax & 0xFF)
+ info.NumGPCounters = uint8((eax >> 8) & 0xFF)
+ info.GPPMCWidth = uint8((eax >> 16) & 0xFF)
+
+ info.RawEBX = ebx
+ info.RawEAX = eax
+ info.RawEDX = edx
+
+ if info.VersionID > 1 { // This information is only valid if VersionID > 1
+ info.NumFixedPMC = uint8(edx & 0x1F) // Bits 4:0
+ info.FixedPMCWidth = uint8((edx >> 5) & 0xFF) // Bits 12:5
+ }
+ if info.VersionID > 0 {
+ // first 4 fixed events are always instructions retired, cycles, ref cycles and topdown slots
+ if ebx == 0x0 && info.NumFixedPMC == 3 {
+ c.featureSet.set(PMU_FIXEDCOUNTER_INSTRUCTIONS)
+ c.featureSet.set(PMU_FIXEDCOUNTER_CYCLES)
+ c.featureSet.set(PMU_FIXEDCOUNTER_REFCYCLES)
+ }
+ if ebx == 0x0 && info.NumFixedPMC == 4 {
+ c.featureSet.set(PMU_FIXEDCOUNTER_INSTRUCTIONS)
+ c.featureSet.set(PMU_FIXEDCOUNTER_CYCLES)
+ c.featureSet.set(PMU_FIXEDCOUNTER_REFCYCLES)
+ c.featureSet.set(PMU_FIXEDCOUNTER_TOPDOWN_SLOTS)
+ }
+ if ebx != 0x0 {
+ if ((ebx >> 0) & 1) == 0 {
+ c.featureSet.set(PMU_FIXEDCOUNTER_INSTRUCTIONS)
+ }
+ if ((ebx >> 1) & 1) == 0 {
+ c.featureSet.set(PMU_FIXEDCOUNTER_CYCLES)
+ }
+ if ((ebx >> 2) & 1) == 0 {
+ c.featureSet.set(PMU_FIXEDCOUNTER_REFCYCLES)
+ }
+ if ((ebx >> 3) & 1) == 0 {
+ c.featureSet.set(PMU_FIXEDCOUNTER_TOPDOWN_SLOTS)
+ }
+ }
+ }
+ return info
+}