aboutsummaryrefslogtreecommitdiff
path: root/cpu-exec.c
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@adacore.com>2013-04-09 18:06:54 +0200
committerStefan Weil <sw@weilnetz.de>2013-04-12 18:27:16 +0200
commitec9bd89fa48147e1d16e078217513c1235f9132a (patch)
treec67dfa73eba87a51b8dbef752e3881dfd4c05d8f /cpu-exec.c
parented9164a3549f93204d6b096136cda2ce54e9f03a (diff)
Ensure good ordering of memory instruction in cpu_exec
The IO thread, when it senses cpu_single_env == 0, expects exit_request to be checked later on. A compiler scheduling constraint is not strong enough to ensure this on modern architecture. A memory fence is needed as well. Signed-off-by: Olivier Hainque <hainque@adacore.com> Signed-off-by: Fabien Chouteau <chouteau@adacore.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Stefan Weil <sw@weilnetz.de>
Diffstat (limited to 'cpu-exec.c')
-rw-r--r--cpu-exec.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index e74e55656a..aa8fa893d9 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -217,6 +217,14 @@ int cpu_exec(CPUArchState *env)
cpu_single_env = env;
+ /* As long as cpu_single_env is null, up to the assignment just above,
+ * requests by other threads to exit the execution loop are expected to
+ * be issued using the exit_request global. We must make sure that our
+ * evaluation of the global value is performed past the cpu_single_env
+ * value transition point, which requires a memory barrier as well as
+ * an instruction scheduling constraint on modern architectures. */
+ smp_mb();
+
if (unlikely(exit_request)) {
cpu->exit_request = 1;
}