summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2021-03-23 22:50:14 -0700
committergVisor bot <gvisor-bot@google.com>2021-03-23 22:50:14 -0700
commit8ee4a3f6d0e75e51e088a431376d2976b0dac866 (patch)
treefe85fee268fd2f7c4012d566a048dac107f742a1 /pkg
parent56a9a13976ad800a8a34b194d35f0169d0a0bb23 (diff)
parent2f3dac78ca9aa1abb9d27570bc9ece0f486ddb60 (diff)
Merge pull request #5677 from avagin:kvm-mmio
PiperOrigin-RevId: 364728696
Diffstat (limited to 'pkg')
-rw-r--r--pkg/sentry/platform/kvm/machine_amd64.go23
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()