mirror of https://github.com/xemu-project/xemu.git
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: Jan Kiszka <jan.kiszka@siemens.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
1d93f0f03d
commit
b0052d1531
|
@ -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(;;) */
|
||||
|
|
Loading…
Reference in New Issue