summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2021-09-01 10:27:30 -0700
committergVisor bot <gvisor-bot@google.com>2021-09-01 10:29:51 -0700
commit810ea0957517bcfc459627aeb10a3594340c895b (patch)
treef82824f83afb1241fd66b8271b262a4eb5dc2a91
parentc5cc6a65664fed83932596abf2a446a93e357bbe (diff)
Cache cpuid.HostFeatureSet().
PiperOrigin-RevId: 394261815
-rw-r--r--pkg/cpuid/cpuid.go8
-rw-r--r--pkg/cpuid/cpuid_arm64.go14
-rw-r--r--pkg/cpuid/cpuid_x86.go15
3 files changed, 33 insertions, 4 deletions
diff --git a/pkg/cpuid/cpuid.go b/pkg/cpuid/cpuid.go
index 69eeb7528..4d5e062a8 100644
--- a/pkg/cpuid/cpuid.go
+++ b/pkg/cpuid/cpuid.go
@@ -37,6 +37,14 @@ package cpuid
// arch/arm64/include/uapi/asm/hwcap.h
type Feature int
+// HostFeatureSet returns a FeatureSet that matches that of the host machine.
+// Callers must not mutate the returned FeatureSet.
+func HostFeatureSet() *FeatureSet {
+ return hostFeatureSet
+}
+
+var hostFeatureSet = getHostFeatureSet()
+
// ErrIncompatible is returned by FeatureSet.HostCompatible if fs is not a
// subset of the host feature set.
type ErrIncompatible struct {
diff --git a/pkg/cpuid/cpuid_arm64.go b/pkg/cpuid/cpuid_arm64.go
index 6e61d562f..04645aed5 100644
--- a/pkg/cpuid/cpuid_arm64.go
+++ b/pkg/cpuid/cpuid_arm64.go
@@ -230,6 +230,16 @@ type FeatureSet struct {
CPURevision uint8
}
+// Clone returns a copy of fs.
+func (fs *FeatureSet) Clone() *FeatureSet {
+ fs2 := *fs
+ fs2.Set = make(map[Feature]bool)
+ for f, b := range fs.Set {
+ fs2.Set[f] = b
+ }
+ return &fs2
+}
+
// CheckHostCompatible returns nil if fs is a subset of the host feature set.
// Noop on arm64.
func (fs *FeatureSet) CheckHostCompatible() error {
@@ -292,9 +302,9 @@ func (fs FeatureSet) WriteCPUInfoTo(cpu uint, b *bytes.Buffer) {
fmt.Fprintln(b, "") // The /proc/cpuinfo file ends with an extra newline.
}
-// HostFeatureSet uses hwCap to get host values and construct a feature set
+// getHostFeatureSet uses hwCap to get host values and construct a feature set
// that matches that of the host machine.
-func HostFeatureSet() *FeatureSet {
+func getHostFeatureSet() *FeatureSet {
s := make(map[Feature]bool)
for f := range arm64FeatureStrings {
diff --git a/pkg/cpuid/cpuid_x86.go b/pkg/cpuid/cpuid_x86.go
index dc17cade8..a92d32d74 100644
--- a/pkg/cpuid/cpuid_x86.go
+++ b/pkg/cpuid/cpuid_x86.go
@@ -627,6 +627,17 @@ type FeatureSet struct {
CacheLine uint32
}
+// Clone returns a copy of fs.
+func (fs *FeatureSet) Clone() *FeatureSet {
+ fs2 := *fs
+ fs2.Set = make(map[Feature]bool)
+ for f, b := range fs.Set {
+ fs2.Set[f] = b
+ }
+ fs2.Caches = append([]Cache(nil), fs.Caches...)
+ return &fs2
+}
+
// FlagsString prints out supported CPU flags. If cpuinfoOnly is true, it is
// equivalent to the "flags" field in /proc/cpuinfo.
func (fs *FeatureSet) FlagsString(cpuinfoOnly bool) string {
@@ -961,13 +972,13 @@ func (fs *FeatureSet) UseXsaveopt() bool {
// HostID executes a native CPUID instruction.
func HostID(axArg, cxArg uint32) (ax, bx, cx, dx uint32)
-// HostFeatureSet uses cpuid to get host values and construct a feature set
+// getHostFeatureSet uses cpuid to get host values and construct a feature set
// that matches that of the host machine. Note that there are several places
// where there appear to be some unnecessary assignments between register names
// (ax, bx, cx, or dx) and featureBlockN variables. This is to explicitly show
// where the different feature blocks come from, to make the code easier to
// inspect and read.
-func HostFeatureSet() *FeatureSet {
+func getHostFeatureSet() *FeatureSet {
// eax=0 gets max supported feature and vendor ID.
_, bx, cx, dx := HostID(0, 0)
vendorID := vendorIDFromRegs(bx, cx, dx)