提交 b0052d15 编写于 作者: J Jan Kiszka 提交者: Aurelien Jarno

Fix cpu_unlink_tb race

If a signal hit after the env->exit_request check but before cpu_exec
updated env->current_tb, cpu_unlink_tb called from the signal hander
will not unlink the current TB. This may leave us stuck in a guest loop
if no further unlink is invoked.

Fix this by reordering current_tb update and exit_request check,
additionally enforcing the correct order via a compiler barrier.
Signed-off-by: NJan Kiszka <jan.kiszka@siemens.com>
Acked-by: NPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: NMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
上级 1d93f0f0
......@@ -600,8 +600,9 @@ int cpu_exec(CPUState *env1)
TB, but before it is linked into a potentially
infinite loop and becomes env->current_tb. Avoid
starting execution if there is a pending interrupt. */
if (!unlikely (env->exit_request)) {
env->current_tb = tb;
env->current_tb = tb;
barrier();
if (likely(!env->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
......@@ -610,7 +611,6 @@ int cpu_exec(CPUState *env1)
#define env cpu_single_env
#endif
next_tb = tcg_qemu_tb_exec(tc_ptr);
env->current_tb = NULL;
if ((next_tb & 3) == 2) {
/* Instruction counter expired. */
int insns_left;
......@@ -639,6 +639,7 @@ int cpu_exec(CPUState *env1)
}
}
}
env->current_tb = NULL;
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
} /* for(;;) */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册