summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2015-06-01 19:43:41 +0100
committerAndreas Sandberg <andreas.sandberg@arm.com>2015-06-01 19:43:41 +0100
commit8e7c0575dc000fdc5b09114f012942b9e52eb303 (patch)
tree266d635942b9ae5e693be3e56f8c8b295929937c
parent06cf5cc60bcfa9080c51b5e413df5a04ae9b95a6 (diff)
downloadgem5-8e7c0575dc000fdc5b09114f012942b9e52eb303.tar.xz
kvm: Handle inst events at the current instruction count
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).
-rw-r--r--src/cpu/kvm/base.cc18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/cpu/kvm/base.cc b/src/cpu/kvm/base.cc
index abb3451f6..827cd5581 100644
--- a/src/cpu/kvm/base.cc
+++ b/src/cpu/kvm/base.cc
@@ -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) {