kvm: Handle inst events at the current instruction count
authorAndreas Sandberg <andreas.sandberg@arm.com>
Mon, 1 Jun 2015 18:43:41 +0000 (19:43 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Mon, 1 Jun 2015 18:43:41 +0000 (19:43 +0100)
There are cases (particularly when attaching GDB) when instruction
events are scheduled at the current instruction tick. This used to
trigger an assertion error in kvm. This changeset adds a check for
this condition and forces KVM to do a quick entry that completes any
pending IO operations, but does not execute any new instructions,
before servicing the event. We could check if we need to enter KVM at
all, but forcing a quick entry is makes the code slightly cleaner and
does not hurt correctness (performance is hardly an issue in these
cases).

src/cpu/kvm/base.cc

index abb3451f64bfc33305c59d65d26b849a2d454a77..827cd55814cc6bcad913437bd58de66cbe00953a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2015 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -533,15 +533,23 @@ BaseKvmCPU::tick()
 
       case RunningServiceCompletion:
       case Running: {
-          EventQueue *q = curEventQueue();
-          Tick ticksToExecute(q->nextTick() - curTick());
+          const uint64_t nextInstEvent(
+              !comInstEventQueue[0]->empty() ?
+              comInstEventQueue[0]->nextTick() : UINT64_MAX);
+          // Enter into KVM and complete pending IO instructions if we
+          // have an instruction event pending.
+          const Tick ticksToExecute(
+              nextInstEvent > ctrInsts ?
+              curEventQueue()->nextTick() - curTick() : 0);
 
           // We might need to update the KVM state.
           syncKvmState();
 
           // Setup any pending instruction count breakpoints using
-          // PerfEvent.
-          setupInstStop();
+          // PerfEvent if we are going to execute more than just an IO
+          // completion.
+          if (ticksToExecute > 0)
+              setupInstStop();
 
           DPRINTF(KvmRun, "Entering KVM...\n");
           if (drainManager) {