From d2254e034e76dc23320ea1b300177a79e4818b61 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Fri, 17 Mar 2017 11:57:23 +0000 Subject: dev, arm: Fix multi-core KVM race in the generic timer The generic timer sometimes needs to access global state. This can lead to race conditions when simulating a multi-core KVM system where each core lives in its own thread. In that case, the setMiscReg and readMiscReg methods are called from the thread owning the CPU and not the global device thread. Change-Id: Ie3e982258648c8562cce0b30a0c122dfbfaf42cd Signed-off-by: Andreas Sandberg Reviewed-by: Gabor Dozsa Reviewed-by: Curtis Dunham Reviewed-by: Sascha Bischoff Reviewed-on: https://gem5-review.googlesource.com/2460 Reviewed-by: Weiping Liao --- src/dev/arm/generic_timer.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/dev/arm/generic_timer.cc b/src/dev/arm/generic_timer.cc index 1b8d917e9..d33090d74 100644 --- a/src/dev/arm/generic_timer.cc +++ b/src/dev/arm/generic_timer.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015 ARM Limited + * Copyright (c) 2013, 2015, 2017 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -307,6 +307,11 @@ 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) { @@ -399,6 +404,11 @@ 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) { -- cgit v1.2.3