summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/platform/kvm/bluepill_unsafe.go
diff options
context:
space:
mode:
authorAdin Scannell <ascannell@google.com>2018-05-15 18:33:19 -0700
committerShentubot <shentubot@google.com>2018-05-15 18:34:09 -0700
commit310a99228b9254ad3c09ecdaa66e5747be4f46c5 (patch)
tree9dd3470493abe335db0bfe178735bd6f279812f2 /pkg/sentry/platform/kvm/bluepill_unsafe.go
parent96c28a43682e8a665142da5b8b0734198fff3a00 (diff)
Simplify KVM state handling.
This also removes the dependency on tmutex. PiperOrigin-RevId: 196764317 Change-Id: I523fb67454318e1a2ca9da3a08e63bfa3c1eeed3
Diffstat (limited to 'pkg/sentry/platform/kvm/bluepill_unsafe.go')
-rw-r--r--pkg/sentry/platform/kvm/bluepill_unsafe.go27
1 files changed, 13 insertions, 14 deletions
diff --git a/pkg/sentry/platform/kvm/bluepill_unsafe.go b/pkg/sentry/platform/kvm/bluepill_unsafe.go
index 9e252af64..2c1e098d7 100644
--- a/pkg/sentry/platform/kvm/bluepill_unsafe.go
+++ b/pkg/sentry/platform/kvm/bluepill_unsafe.go
@@ -51,15 +51,13 @@ func bluepillHandler(context unsafe.Pointer) {
// Increment the number of switches.
atomic.AddUint32(&c.switches, 1)
- // Store vCPUGuest.
- //
- // This is fine even if we're not in guest mode yet. In this signal
- // handler, we'll already have all the relevant signals blocked, so an
- // interrupt is only deliverable when we actually execute the KVM_RUN.
- //
- // The state will be returned to vCPUReady by Phase2.
- if state := atomic.SwapUintptr(&c.state, vCPUGuest); state != vCPUReady {
- throw("vCPU not in ready state")
+ // Mark this as guest mode.
+ switch atomic.SwapUint32(&c.state, vCPUGuest|vCPUUser) {
+ case vCPUUser: // Expected case.
+ case vCPUUser | vCPUWaiter:
+ c.notify()
+ default:
+ throw("invalid state")
}
for {
@@ -118,11 +116,12 @@ func bluepillHandler(context unsafe.Pointer) {
// Copy out registers.
bluepillArchExit(c, bluepillArchContext(context))
- // Notify any waiters.
- switch state := atomic.SwapUintptr(&c.state, vCPUReady); state {
- case vCPUGuest:
- case vCPUWaiter:
- c.notify() // Safe from handler.
+ // Return to the vCPUReady state; notify any waiters.
+ user := atomic.LoadUint32(&c.state) & vCPUUser
+ switch atomic.SwapUint32(&c.state, user) {
+ case user | vCPUGuest: // Expected case.
+ case user | vCPUGuest | vCPUWaiter:
+ c.notify()
default:
throw("invalid state")
}