Check for support for xgetbv

Fixes #5738

PiperOrigin-RevId: 413054140
This commit is contained in:
Ian Lewis
2021-11-29 21:26:45 -08:00
committed by gVisor bot
parent 91d4826f5b
commit afd549d79c
+13 -4
View File
@@ -22,6 +22,7 @@ import (
"reflect"
"sync"
"gvisor.dev/gvisor/pkg/cpuid"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/sentry/arch"
)
@@ -267,14 +268,20 @@ func doSwitchToUser(
needIRET uint64) Vector // +32(FP), +40(FP)
var (
sentryXCR0 uintptr
sentryXCR0Once sync.Once
sentryXCR0 uintptr
xgetbvIsSupported bool
sentryXCR0Once sync.Once
)
// initSentryXCR0 saves a value of XCR0 in the host mode. It is used to
// initialize XCR0 of guest vCPU-s.
func initSentryXCR0() {
sentryXCR0Once.Do(func() { sentryXCR0 = xgetbv(0) })
sentryXCR0Once.Do(func() {
if cpuid.HostFeatureSet().HasFeature(cpuid.X86FeatureXSAVE) {
sentryXCR0 = xgetbv(0)
xgetbvIsSupported = true
}
})
}
// startGo is the CPU entrypoint.
@@ -303,7 +310,9 @@ func startGo(c *CPU) {
fninit()
// Need to sync XCR0 with the host, because xsave and xrstor can be
// called from different contexts.
xsetbv(0, sentryXCR0)
if xgetbvIsSupported {
xsetbv(0, sentryXCR0)
}
// Set the syscall target.
wrmsr(_MSR_LSTAR, kernelFunc(addrOfSysenter()))