tcg: synchronize exit_request and tcg_current_cpu accesses

Synchronize the remaining pair of accesses in cpu_signal.  These should
be necessary on Windows as well, at least in theory.  Probably
SuspendProcess and ResumeProcess introduce some implicit memory
barrier.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/cpu-exec.c b/cpu-exec.c
index e24c640..ef9d745 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -372,7 +372,7 @@
     atomic_mb_set(&tcg_current_cpu, cpu);
     rcu_read_lock();
 
-    if (unlikely(exit_request)) {
+    if (unlikely(atomic_mb_read(&exit_request))) {
         cpu->exit_request = 1;
     }
 
diff --git a/cpus.c b/cpus.c
index 6cebb7a..dd2fc29 100644
--- a/cpus.c
+++ b/cpus.c
@@ -663,11 +663,15 @@
 
 static void cpu_signal(int sig)
 {
-    CPUState *cpu = atomic_mb_read(&tcg_current_cpu);
+    CPUState *cpu;
+    /* Ensure whatever caused the exit has reached the CPU threads before
+     * writing exit_request.
+     */
+    atomic_mb_set(&exit_request, 1);
+    cpu = atomic_mb_read(&tcg_current_cpu);
     if (cpu) {
         cpu_exit(cpu);
     }
-    exit_request = 1;
 }
 
 #ifdef CONFIG_LINUX
@@ -1063,7 +1067,7 @@
     }
 
     /* process any pending work */
-    exit_request = 1;
+    atomic_mb_set(&exit_request, 1);
 
     while (1) {
         tcg_exec_all();
@@ -1441,7 +1445,9 @@
             break;
         }
     }
-    exit_request = 0;
+
+    /* Pairs with smp_wmb in qemu_cpu_kick.  */
+    atomic_mb_set(&exit_request, 0);
 }
 
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)