Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AMD cache hang on buggy Xen hypervisor #104

Merged
merged 1 commit into from Jun 21, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 26 additions & 1 deletion cpuid.go
Expand Up @@ -14,6 +14,7 @@ import (
"flag"
"fmt"
"math"
"math/bits"
"os"
"runtime"
"strings"
Expand Down Expand Up @@ -389,8 +390,9 @@ func (c CPUInfo) IsVendor(v Vendor) bool {
return c.VendorID == v
}

// FeatureSet returns all available features as strings.
func (c CPUInfo) FeatureSet() []string {
s := make([]string, 0)
s := make([]string, 0, c.featureSet.nEnabled())
s = append(s, c.featureSet.Strings()...)
return s
}
Expand Down Expand Up @@ -563,6 +565,14 @@ func (s flagSet) hasSet(other flagSet) bool {
return true
}

// nEnabled will return the number of enabled flags.
func (s flagSet) nEnabled() (n int) {
for _, v := range s[:] {
n += bits.OnesCount64(uint64(v))
}
return n
}

func flagSetWith(feat ...FeatureID) flagSet {
var res flagSet
for _, f := range feat {
Expand Down Expand Up @@ -834,6 +844,11 @@ func (c *CPUInfo) cacheSize() {
if maxExtendedFunction() < 0x8000001D {
return
}

// Xen Hypervisor is buggy and returns the same entry no matter ECX value.
// Hack: When we encounter the same entry 100 times we break.
nSame := 0
var last uint32
for i := uint32(0); i < math.MaxUint32; i++ {
eax, ebx, ecx, _ := cpuidex(0x8000001D, i)

Expand All @@ -849,6 +864,16 @@ func (c *CPUInfo) cacheSize() {
return
}

// Check for the same value repeated.
comb := eax ^ ebx ^ ecx
if comb == last {
nSame++
if nSame == 100 {
return
}
}
last = comb

switch level {
case 1:
switch typ {
Expand Down