소스 검색

cpu-exec: tighten barrier on TCG_EXIT_REQUESTED

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>
Paolo Bonzini 8 년 전
부모
커밋
a70fe14b7d
1개의 변경된 파일2개의 추가작업 그리고 2개의 파일을 삭제
  1. 2 2
      cpu-exec.c

+ 2 - 2
cpu-exec.c

@@ -552,11 +552,11 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
          * have set something else (eg exit_request or
          * have set something else (eg exit_request or
          * interrupt_request) which we will handle
          * interrupt_request) which we will handle
          * next time around the loop.  But we need to
          * 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
          * comes before the next read of cpu->exit_request
          * or cpu->interrupt_request.
          * or cpu->interrupt_request.
          */
          */
-        smp_rmb();
+        smp_mb();
         *last_tb = NULL;
         *last_tb = NULL;
         break;
         break;
     case TB_EXIT_ICOUNT_EXPIRED:
     case TB_EXIT_ICOUNT_EXPIRED: