tcg: synchronize cpu->exit_request and cpu->tcg_exit_req accesses
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 18 Aug 2015 13:34:19 +0000 (06:34 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 9 Sep 2015 13:34:53 +0000 (15:34 +0200)
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
cpu-exec.c
qom/cpu.c

index 567ae8bda152817dbe488e5c0f563aaf0cfacc11..e24c6400133b84f9457da31e28e6c077db62beee 100644 (file)
@@ -507,8 +507,12 @@ int cpu_exec(CPUState *cpu)
                          * loop. Whatever requested the exit will also
                          * have set something else (eg exit_request or
                          * interrupt_request) which we will handle
-                         * next time around the loop.
+                         * next time around the loop.  But we need to
+                         * ensure the tcg_exit_req read in generated code
+                         * comes before the next read of cpu->exit_request
+                         * or cpu->interrupt_request.
                          */
+                        smp_rmb();
                         next_tb = 0;
                         break;
                     case TB_EXIT_ICOUNT_EXPIRED:
index 62f4b5de44837e684aae0dc746e490ccc50a27cc..02b56f7076d344b63130e0f31a66c68591658d51 100644 (file)
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -114,6 +114,8 @@ void cpu_reset_interrupt(CPUState *cpu, int mask)
 void cpu_exit(CPUState *cpu)
 {
     cpu->exit_request = 1;
+    /* Ensure cpu_exec will see the exit request after TCG has exited.  */
+    smp_wmb();
     cpu->tcg_exit_req = 1;
 }