Merge pull request #5677 from avagin:kvm-mmio

PiperOrigin-RevId: 364728696
This commit is contained in:
gVisor bot
2021-03-23 22:50:14 -07:00
+23
View File
@@ -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()