diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-03-24 05:56:09 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-03-24 05:56:09 +0000 |
commit | 15bcc00b79decbc781d2d1badd5c654ed2609ea8 (patch) | |
tree | 286f4740681344a2b406354cf14899b95595aa0d | |
parent | 6d6d1361a87d19477c9f035405065fc9b714ef73 (diff) | |
parent | 8ee4a3f6d0e75e51e088a431376d2976b0dac866 (diff) |
Merge release-20210315.0-20-g8ee4a3f6d (automated)
-rw-r--r-- | pkg/sentry/platform/kvm/machine_amd64.go | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go index 8f2c82e73..3af96c7e5 100644 --- a/pkg/sentry/platform/kvm/machine_amd64.go +++ b/pkg/sentry/platform/kvm/machine_amd64.go @@ -294,6 +294,28 @@ func (c *vCPU) fault(signal int32, info *arch.SignalInfo) (usermem.AccessType, e return accessType, platform.ErrContextSignal } +//go:nosplit +//go:noinline +func loadByte(ptr *byte) byte { + return *ptr +} + +// prefaultFloatingPointState touches each page of the floating point state to +// be sure that its physical pages are mapped. +// +// Otherwise the kernel can trigger KVM_EXIT_MMIO and an instruction that +// triggered a fault will be emulated by the kvm kernel code, but it can't +// emulate instructions like xsave and xrstor. +// +//go:nosplit +func prefaultFloatingPointState(data *fpu.State) { + size := len(*data) + for i := 0; i < size; i += usermem.PageSize { + loadByte(&(*data)[i]) + } + loadByte(&(*data)[size-1]) +} + // SwitchToUser unpacks architectural-details. func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts, info *arch.SignalInfo) (usermem.AccessType, error) { // Check for canonical addresses. @@ -324,6 +346,7 @@ func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts, info *arch.SignalInfo) // allocations occur. entersyscall() bluepill(c) + prefaultFloatingPointState(switchOpts.FloatingPointState) vector = c.CPU.SwitchToUser(switchOpts) exitsyscall() |