diff options
-rw-r--r-- | pkg/cpuid/cpuid.go | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go index 0571b7cde..64e2e68f1 100644 --- a/pkg/cpuid/cpuid.go +++ b/pkg/cpuid/cpuid.go @@ -551,6 +551,16 @@ func (fs FeatureSet) CPUInfo(cpu uint) string { return b.String() } +// AMD returns true if fs describes an AMD CPU. +func (fs *FeatureSet) AMD() bool { + return fs.VendorID == "AuthenticAMD" +} + +// Intel returns true if fs describes an Intel CPU. +func (fs *FeatureSet) Intel() bool { + return fs.VendorID == "GenuineIntel" +} + // Helper to convert 3 regs into 12-byte vendor ID. func vendorIDFromRegs(bx, cx, dx uint32) string { bytes := make([]byte, 0, 12) @@ -735,6 +745,20 @@ func (fs *FeatureSet) EmulateID(origAx, origCx uint32) (ax, bx, cx, dx uint32) { cx = fs.blockMask(block(0)) dx = fs.blockMask(block(1)) ax = fs.signature() + case intelCacheDescriptors: + if !fs.Intel() { + // Reserved on non-Intel. + return 0, 0, 0, 0 + } + + // "The least-significant byte in register EAX (register AL) + // will always return 01H. Software should ignore this value + // and not interpret it as an informational descriptor." - SDM + // + // We do not support exposing cache information, but we do set + // this fixed field because some language runtimes (dlang) get + // confused by ax = 0 and will loop infinitely. + ax = 1 case xSaveInfo: if !fs.UseXsave() { return 0, 0, 0, 0 @@ -753,7 +777,7 @@ func (fs *FeatureSet) EmulateID(origAx, origCx uint32) (ax, bx, cx, dx uint32) { case extendedFeatures: cx = fs.blockMask(block(5)) dx = fs.blockMask(block(6)) - if fs.VendorID == "AuthenticAMD" { + if fs.AMD() { // AMD duplicates some block 1 features in block 6. dx |= fs.blockMask(block(1)) & block6DuplicateMask } |