diff options
author | Adin Scannell <ascannell@google.com> | 2018-05-15 18:33:19 -0700 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-05-15 18:34:09 -0700 |
commit | 310a99228b9254ad3c09ecdaa66e5747be4f46c5 (patch) | |
tree | 9dd3470493abe335db0bfe178735bd6f279812f2 /pkg/sentry/platform/kvm/bluepill_unsafe.go | |
parent | 96c28a43682e8a665142da5b8b0734198fff3a00 (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.go | 27 |
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") } |