diff options
author | Andrei Vagin <avagin@gmail.com> | 2021-03-16 09:15:03 -0700 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2021-03-16 21:55:20 -0700 |
commit | 2f3dac78ca9aa1abb9d27570bc9ece0f486ddb60 (patch) | |
tree | 195f9161e491c3f31ac6a1191e651f25f9743976 /pkg/sentry/arch | |
parent | f7e841c2cede357c4cbd6117605e3f3d54f1961c (diff) |
kvm: prefault a floating point state before restoring it
If physical pages of a memory region are not mapped yet, the kernel will
trigger KVM_EXIT_MMIO and we will map physical pages in bluepillHandler().
An instruction that triggered a fault will not be re-executed, it
will be emulated in the kernel, but it can't emulate complex
instructions like xsave, xrstor. We can touch the memory with
simple instructions to workaround this problem.
Diffstat (limited to 'pkg/sentry/arch')
-rw-r--r-- | pkg/sentry/arch/arch.go | 4 | ||||
-rw-r--r-- | pkg/sentry/arch/arch_aarch64.go | 8 | ||||
-rw-r--r-- | pkg/sentry/arch/arch_x86.go | 14 |
3 files changed, 13 insertions, 13 deletions
diff --git a/pkg/sentry/arch/arch.go b/pkg/sentry/arch/arch.go index dd2effdf9..3443b9e1b 100644 --- a/pkg/sentry/arch/arch.go +++ b/pkg/sentry/arch/arch.go @@ -54,7 +54,7 @@ func (a Arch) String() string { // We rely on the individual arch implementations to meet all the necessary // requirements. For example, on x86 the region must be 16-byte aligned and 512 // bytes in size. -type FloatingPointData byte +type FloatingPointData []byte // Context provides architecture-dependent information for a specific thread. // @@ -187,7 +187,7 @@ type Context interface { ClearSingleStep() // FloatingPointData will be passed to underlying save routines. - FloatingPointData() *FloatingPointData + FloatingPointData() FloatingPointData // NewMmapLayout returns a layout for a new MM, where MinAddr for the // returned layout must be no lower than min, and MaxAddr for the returned diff --git a/pkg/sentry/arch/arch_aarch64.go b/pkg/sentry/arch/arch_aarch64.go index fd73751e7..6b81e9708 100644 --- a/pkg/sentry/arch/arch_aarch64.go +++ b/pkg/sentry/arch/arch_aarch64.go @@ -88,15 +88,15 @@ func (f aarch64FPState) fork() aarch64FPState { } // FloatingPointData returns the raw data pointer. -func (f aarch64FPState) FloatingPointData() *FloatingPointData { - return (*FloatingPointData)(&f[0]) +func (f aarch64FPState) FloatingPointData() FloatingPointData { + return ([]byte)(f) } // NewFloatingPointData returns a new floating point data blob. // // This is primarily for use in tests. -func NewFloatingPointData() *FloatingPointData { - return (*FloatingPointData)(&(newAarch64FPState()[0])) +func NewFloatingPointData() FloatingPointData { + return ([]byte)(newAarch64FPState()) } // State contains the common architecture bits for aarch64 (the build tag of this diff --git a/pkg/sentry/arch/arch_x86.go b/pkg/sentry/arch/arch_x86.go index 641ada92f..91edf0703 100644 --- a/pkg/sentry/arch/arch_x86.go +++ b/pkg/sentry/arch/arch_x86.go @@ -115,7 +115,7 @@ var ( type x86FPState []byte // initX86FPState (defined in asm files) sets up initial state. -func initX86FPState(data *FloatingPointData, useXsave bool) +func initX86FPState(data *byte, useXsave bool) func newX86FPStateSlice() []byte { size, align := cpuid.HostFeatureSet().ExtendedStateSize() @@ -139,7 +139,7 @@ func newX86FPStateSlice() []byte { // CPUID we must ensure it does not contain any sentry state. func newX86FPState() x86FPState { f := x86FPState(newX86FPStateSlice()) - initX86FPState(f.FloatingPointData(), cpuid.HostFeatureSet().UseXsave()) + initX86FPState(&f.FloatingPointData()[0], cpuid.HostFeatureSet().UseXsave()) return f } @@ -151,15 +151,15 @@ func (f x86FPState) fork() x86FPState { } // FloatingPointData returns the raw data pointer. -func (f x86FPState) FloatingPointData() *FloatingPointData { - return (*FloatingPointData)(&f[0]) +func (f x86FPState) FloatingPointData() FloatingPointData { + return []byte(f) } // NewFloatingPointData returns a new floating point data blob. // // This is primarily for use in tests. -func NewFloatingPointData() *FloatingPointData { - return (*FloatingPointData)(&(newX86FPState()[0])) +func NewFloatingPointData() FloatingPointData { + return (FloatingPointData)(newX86FPState()) } // Proto returns a protobuf representation of the system registers in State. @@ -442,7 +442,7 @@ func sanitizeMXCSR(f x86FPState) { mxcsr := usermem.ByteOrder.Uint32(f[mxcsrOffset:]) initMXCSRMask.Do(func() { temp := x86FPState(alignedBytes(uint(ptraceFPRegsSize), 16)) - initX86FPState(temp.FloatingPointData(), false /* useXsave */) + initX86FPState(&temp.FloatingPointData()[0], false /* useXsave */) mxcsrMask = usermem.ByteOrder.Uint32(temp[mxcsrMaskOffset:]) if mxcsrMask == 0 { // "If the value of the MXCSR_MASK field is 00000000H, then the |