diff options
author | Andrei Vagin <avagin@google.com> | 2021-06-11 18:41:13 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-06-11 18:43:26 -0700 |
commit | ec6a7ebc75f714e9ac8ae1dc785304661f6e63b4 (patch) | |
tree | 56182edee0961038848a611cfa10efc145807bbe /pkg/ring0 | |
parent | 3c63fce628ccee1f41c9c3a1ff693042ce094503 (diff) |
Rework the workaround of the XCR0 issue
XCR0 has to be synchronized with the host. We can call xsave from the host
context and then call xrstor from the guest context and vise versa. This means
we need to support the same set of FPU features in both contexts.
PiperOrigin-RevId: 378988281
Diffstat (limited to 'pkg/ring0')
-rw-r--r-- | pkg/ring0/kernel_amd64.go | 22 |
1 files changed, 5 insertions, 17 deletions
diff --git a/pkg/ring0/kernel_amd64.go b/pkg/ring0/kernel_amd64.go index 41dfd0bf9..f63af8b76 100644 --- a/pkg/ring0/kernel_amd64.go +++ b/pkg/ring0/kernel_amd64.go @@ -254,6 +254,8 @@ func (c *CPU) SwitchToUser(switchOpts SwitchOpts) (vector Vector) { return } +var sentryXCR0 = xgetbv(0) + // start is the CPU entrypoint. // // This is called from the Start asm stub (see entry_amd64.go); on return the @@ -265,24 +267,10 @@ func start(c *CPU) { WriteGS(kernelAddr(c.kernelEntry)) WriteFS(uintptr(c.registers.Fs_base)) - // Initialize floating point. - // - // Note that on skylake, the valid XCR0 mask reported seems to be 0xff. - // This breaks down as: - // - // bit0 - x87 - // bit1 - SSE - // bit2 - AVX - // bit3-4 - MPX - // bit5-7 - AVX512 - // - // For some reason, enabled MPX & AVX512 on platforms that report them - // seems to be cause a general protection fault. (Maybe there are some - // virtualization issues and these aren't exported to the guest cpuid.) - // This needs further investigation, but we can limit the floating - // point operations to x87, SSE & AVX for now. fninit() - xsetbv(0, validXCR0Mask&0x7) + // Need to sync XCR0 with the host, because xsave and xrstor can be + // called from different contexts. + xsetbv(0, sentryXCR0) // Set the syscall target. wrmsr(_MSR_LSTAR, kernelFunc(sysenter)) |