diff --git a/pkg/ring0/kernel_amd64.go b/pkg/ring0/kernel_amd64.go index 7e55011b5f..9a9a4a6e25 100644 --- a/pkg/ring0/kernel_amd64.go +++ b/pkg/ring0/kernel_amd64.go @@ -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()))