summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/platform/kvm
diff options
context:
space:
mode:
authorAdin Scannell <ascannell@google.com>2018-06-08 17:50:55 -0700
committerShentubot <shentubot@google.com>2018-06-08 17:51:50 -0700
commitc0ab059e7b904197f52ade879711d7fb02ffa8c0 (patch)
tree093689eba3e7ef08663be3d43f6c6763228ed571 /pkg/sentry/platform/kvm
parent2fbd1cf57cb06c5f0165a2d0e9225eed242a41f5 (diff)
Fix kernel flags handling and add missing vectors.
PiperOrigin-RevId: 199877174 Change-Id: I9d19ea301608c2b989df0a6123abb1e779427853
Diffstat (limited to 'pkg/sentry/platform/kvm')
-rw-r--r--pkg/sentry/platform/kvm/machine_amd64.go52
1 files changed, 42 insertions, 10 deletions
diff --git a/pkg/sentry/platform/kvm/machine_amd64.go b/pkg/sentry/platform/kvm/machine_amd64.go
index 7fcb7451f..7ac289756 100644
--- a/pkg/sentry/platform/kvm/machine_amd64.go
+++ b/pkg/sentry/platform/kvm/machine_amd64.go
@@ -150,13 +150,20 @@ func (c *vCPU) fault(signal int32) (*arch.SignalInfo, usermem.AccessType, error)
// the code provided here. We need to re-execute.
return nil, usermem.NoAccess, platform.ErrContextInterrupt
}
- info := &arch.SignalInfo{Signo: signal}
+ info := &arch.SignalInfo{
+ Signo: signal,
+ }
info.SetAddr(uint64(faultAddr))
accessType := usermem.AccessType{
Read: code&(1<<1) == 0,
Write: code&(1<<1) != 0,
Execute: code&(1<<4) != 0,
}
+ if !accessType.Write && !accessType.Execute {
+ info.Code = 1 // SEGV_MAPERR.
+ } else {
+ info.Code = 2 // SEGV_ACCERR.
+ }
return info, accessType, platform.ErrContextSignal
}
@@ -191,30 +198,55 @@ func (c *vCPU) SwitchToUser(switchOpts ring0.SwitchOpts) (*arch.SignalInfo, user
return c.fault(int32(syscall.SIGSEGV))
case ring0.Debug, ring0.Breakpoint:
- info := &arch.SignalInfo{Signo: int32(syscall.SIGTRAP)}
+ info := &arch.SignalInfo{
+ Signo: int32(syscall.SIGTRAP),
+ Code: 1, // TRAP_BRKPT (breakpoint).
+ }
+ info.SetAddr(switchOpts.Registers.Rip) // Include address.
return info, usermem.AccessType{}, platform.ErrContextSignal
case ring0.GeneralProtectionFault:
- if !ring0.IsCanonical(switchOpts.Registers.Rip) {
- // If the RIP is non-canonical, it's a SEGV.
- info := &arch.SignalInfo{Signo: int32(syscall.SIGSEGV)}
- return info, usermem.AccessType{}, platform.ErrContextSignal
+ info := &arch.SignalInfo{
+ Signo: int32(syscall.SIGSEGV),
+ Code: arch.SignalInfoKernel,
}
- // Otherwise, we deliver a SIGBUS.
- info := &arch.SignalInfo{Signo: int32(syscall.SIGBUS)}
+ info.SetAddr(switchOpts.Registers.Rip) // Include address.
return info, usermem.AccessType{}, platform.ErrContextSignal
case ring0.InvalidOpcode:
- info := &arch.SignalInfo{Signo: int32(syscall.SIGILL)}
+ info := &arch.SignalInfo{
+ Signo: int32(syscall.SIGILL),
+ Code: 1, // ILL_ILLOPC (illegal opcode).
+ }
+ info.SetAddr(switchOpts.Registers.Rip) // Include address.
+ return info, usermem.AccessType{}, platform.ErrContextSignal
+
+ case ring0.DivideByZero:
+ info := &arch.SignalInfo{
+ Signo: int32(syscall.SIGFPE),
+ Code: 1, // FPE_INTDIV (divide by zero).
+ }
+ info.SetAddr(switchOpts.Registers.Rip) // Include address.
return info, usermem.AccessType{}, platform.ErrContextSignal
case ring0.X87FloatingPointException:
- info := &arch.SignalInfo{Signo: int32(syscall.SIGFPE)}
+ info := &arch.SignalInfo{
+ Signo: int32(syscall.SIGFPE),
+ Code: 7, // FPE_FLTINV (invalid operation).
+ }
+ info.SetAddr(switchOpts.Registers.Rip) // Include address.
return info, usermem.AccessType{}, platform.ErrContextSignal
case ring0.Vector(bounce):
return nil, usermem.NoAccess, platform.ErrContextInterrupt
+ case ring0.AlignmentCheck:
+ info := &arch.SignalInfo{
+ Signo: int32(syscall.SIGBUS),
+ Code: 2, // BUS_ADRERR (physical address does not exist).
+ }
+ return info, usermem.NoAccess, platform.ErrContextSignal
+
case ring0.NMI:
// An NMI is generated only when a fault is not servicable by
// KVM itself, so we think some mapping is writeable but it's