summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/arch/arch_x86.go
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@gmail.com>2021-03-16 09:15:03 -0700
committerAndrei Vagin <avagin@gmail.com>2021-03-16 21:55:20 -0700
commit2f3dac78ca9aa1abb9d27570bc9ece0f486ddb60 (patch)
tree195f9161e491c3f31ac6a1191e651f25f9743976 /pkg/sentry/arch/arch_x86.go
parentf7e841c2cede357c4cbd6117605e3f3d54f1961c (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/arch_x86.go')
-rw-r--r--pkg/sentry/arch/arch_x86.go14
1 files changed, 7 insertions, 7 deletions
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