summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2017-07-27 09:26:07 +0000
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-08-01 16:20:24 +0000
commitdb85b8ff32c46796aa91fecb04ea1ae3411c077e (patch)
tree601211fa2486b21504883cc85f379edb1d9016b0
parent1935cec529ac2ae7d9b31f1e55f333a0769184b5 (diff)
downloadgem5-db85b8ff32c46796aa91fecb04ea1ae3411c077e.tar.xz
kvm, arm: Switch to the device EQ when accessing ISA devices
ISA devices typically run in the device event queue. Previously, we assumed that devices would perform their own EQ migrations as needed. This isn't ideal since it means we have different conventions for IO devices and ISA devices. Switch to doing migrations in the KVM CPU instead to make the behavior consistent. Change-Id: I33b74480fb2126b0786dbdbfdcfa86083384250c Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com> Reviewed-on: https://gem5-review.googlesource.com/4288 Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
-rw-r--r--src/arch/arm/kvm/armv8_cpu.cc21
-rw-r--r--src/dev/arm/generic_timer.cc10
2 files changed, 18 insertions, 13 deletions
diff --git a/src/arch/arm/kvm/armv8_cpu.cc b/src/arch/arm/kvm/armv8_cpu.cc
index db2b9c07a..209f49efa 100644
--- a/src/arch/arm/kvm/armv8_cpu.cc
+++ b/src/arch/arm/kvm/armv8_cpu.cc
@@ -260,7 +260,17 @@ ArmV8KvmCPU::updateKvmState()
}
for (const auto &ri : getSysRegMap()) {
- const uint64_t value(tc->readMiscReg(ri.idx));
+ uint64_t value;
+ if (ri.is_device) {
+ // This system register is backed by a device. This means
+ // we need to lock the device event queue.
+ EventQueue::ScopedMigration migrate(deviceEventQueue());
+
+ value = tc->readMiscReg(ri.idx);
+ } else {
+ value = tc->readMiscReg(ri.idx);
+ }
+
DPRINTF(KvmContext, " %s := 0x%x\n", ri.name, value);
setOneReg(ri.kvm, value);
}
@@ -323,10 +333,15 @@ ArmV8KvmCPU::updateThreadContext()
for (const auto &ri : getSysRegMap()) {
const auto value(getOneRegU64(ri.kvm));
DPRINTF(KvmContext, " %s := 0x%x\n", ri.name, value);
- if (ri.is_device)
+ if (ri.is_device) {
+ // This system register is backed by a device. This means
+ // we need to lock the device event queue.
+ EventQueue::ScopedMigration migrate(deviceEventQueue());
+
tc->setMiscReg(ri.idx, value);
- else
+ } else {
tc->setMiscRegNoEffect(ri.idx, value);
+ }
}
PCState pc(getOneRegU64(INT_REG(regs.pc)));
diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc
index 6332b8f4d..350867488 100644
--- a/src/dev/arm/generic_timer.cc
+++ b/src/dev/arm/generic_timer.cc
@@ -318,11 +318,6 @@ GenericTimer::createTimers(unsigned cpus)
void
GenericTimer::setMiscReg(int reg, unsigned cpu, MiscReg val)
{
- // This method might have been called from another context if we
- // are running in multi-core KVM. Migrate to the SimObject's event
- // queue to prevent surprising race conditions.
- EventQueue::ScopedMigration migrate(eventQueue());
-
CoreTimers &core(getTimers(cpu));
switch (reg) {
@@ -415,11 +410,6 @@ GenericTimer::setMiscReg(int reg, unsigned cpu, MiscReg val)
MiscReg
GenericTimer::readMiscReg(int reg, unsigned cpu)
{
- // This method might have been called from another context if we
- // are running in multi-core KVM. Migrate to the SimObject's event
- // queue to prevent surprising race conditions.
- EventQueue::ScopedMigration migrate(eventQueue());
-
CoreTimers &core(getTimers(cpu));
switch (reg) {