cpu-exec: tighten barrier on TCG_EXIT_REQUESTED
authorPaolo Bonzini <pbonzini@redhat.com>
Sun, 29 Jan 2017 11:15:15 +0000 (12:15 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Thu, 16 Feb 2017 13:06:56 +0000 (14:06 +0100)
This seems to have worked just fine so far on weakly-ordered
architectures, but I don't see anything that prevents the
reordering from:

    store 1 to exit_request
    store 1 to tcg_exit_req
                                 load tcg_exit_req
                                 store 0 to tcg_exit_req
                                 load exit_request
                                 store 0 to exit_request
    store 1 to exit_request
    store 1 to tcg_exit_req

to this:

    store 1 to exit_request
    store 1 to tcg_exit_req
                                 load tcg_exit_req
                                 load exit_request
    store 1 to exit_request
    store 1 to tcg_exit_req
                                 store 0 to tcg_exit_req
                                 store 0 to exit_request

therefore losing a request.  It's possible that other memory barriers
(e.g. in rcu_read_unlock) are hiding it, but better safe than
sorry.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
cpu-exec.c

index 1f7d217f30e75ad53d14b947a6b7806ebd3a6d6d..d50625bf97f86fad858fb9ae6c2af50e0919e680 100644 (file)
@@ -552,11 +552,11 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
          * have set something else (eg exit_request or
          * interrupt_request) which we will handle
          * next time around the loop.  But we need to
-         * ensure the tcg_exit_req read in generated code
+         * ensure the zeroing of tcg_exit_req (see cpu_tb_exec)
          * comes before the next read of cpu->exit_request
          * or cpu->interrupt_request.
          */
-        smp_rmb();
+        smp_mb();
         *last_tb = NULL;
         break;
     case TB_EXIT_ICOUNT_EXPIRED: