sim-card
/
qemu
Archived
10
0
Fork 0

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:
Jan Kiszka 2010-06-25 16:56:50 +02:00 committed by Aurelien Jarno
parent 1d93f0f03d
commit b0052d1531
1 changed files with 4 additions and 3 deletions

View File

@ -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(;;) */