• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisão426eeecdf5d9cf1695a53c08f46394f8e5351750 (tree)
Hora2017-11-03 17:34:21
AutorPeter Maydell <peter.maydell@lina...>
CommiterRichard Henderson

Mensagem de Log

cpu-exec: Exit exclusive region on longjmp from step_atomic

Commit ac03ee5331612e44be narrowed the scope of the exclusive
region so it only covers when we're executing the TB, not when
we're generating it. However it missed that there is more than
one execution path out of cpu_tb_exec -- if the atomic insn
causes an exception then the code will longjmp out, skipping
the code to end the exclusive region. This causes QEMU to hang
the next time the CPU calls start_exclusive(), waiting for
itself to exit the region.

Move the "end the region" code out to the end of the
function so that it is run for both normal exit and also
for exit-via-longjmp. We have to use a volatile bool flag
to decide whether we need to end the region, because we
can longjump out of the codegen as well as the execution.

(For some reason this only reproduces for me with a clang
optimized build, not a gcc debug build.)

Reviewed-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Fixes: ac03ee5331612e44beb393df2b578c951d27dc0d
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <1509640536-32160-1-git-send-email-peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Mudança Sumário

Diff

--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -233,6 +233,8 @@ void cpu_exec_step_atomic(CPUState *cpu)
233233 uint32_t flags;
234234 uint32_t cflags = 1;
235235 uint32_t cf_mask = cflags & CF_HASH_MASK;
236+ /* volatile because we modify it between setjmp and longjmp */
237+ volatile bool in_exclusive_region = false;
236238
237239 if (sigsetjmp(cpu->jmp_env, 0) == 0) {
238240 tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask);
@@ -251,14 +253,12 @@ void cpu_exec_step_atomic(CPUState *cpu)
251253
252254 /* Since we got here, we know that parallel_cpus must be true. */
253255 parallel_cpus = false;
256+ in_exclusive_region = true;
254257 cc->cpu_exec_enter(cpu);
255258 /* execute the generated code */
256259 trace_exec_tb(tb, pc);
257260 cpu_tb_exec(cpu, tb);
258261 cc->cpu_exec_exit(cpu);
259- parallel_cpus = true;
260-
261- end_exclusive();
262262 } else {
263263 /* We may have exited due to another problem here, so we need
264264 * to reset any tb_locks we may have taken but didn't release.
@@ -270,6 +270,15 @@ void cpu_exec_step_atomic(CPUState *cpu)
270270 #endif
271271 tb_lock_reset();
272272 }
273+
274+ if (in_exclusive_region) {
275+ /* We might longjump out of either the codegen or the
276+ * execution, so must make sure we only end the exclusive
277+ * region if we started it.
278+ */
279+ parallel_cpus = true;
280+ end_exclusive();
281+ }
273282 }
274283
275284 struct tb_desc {