diff options
author | Andreas Sandberg <andreas.sandberg@arm.com> | 2015-06-01 19:43:41 +0100 |
---|---|---|
committer | Andreas Sandberg <andreas.sandberg@arm.com> | 2015-06-01 19:43:41 +0100 |
commit | 8e7c0575dc000fdc5b09114f012942b9e52eb303 (patch) | |
tree | 266d635942b9ae5e693be3e56f8c8b295929937c | |
parent | 06cf5cc60bcfa9080c51b5e413df5a04ae9b95a6 (diff) | |
download | gem5-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.cc | 18 |
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) { |