summary refs log tree commit diff stats
path: root/cpu-exec.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2016-06-29 22:12:55 -0700
committerRichard Henderson <rth@twiddle.net>2016-10-26 08:29:00 -0700
commitfdbc2b5722f6092e47181a947c90fd4bdcc1c121 (patch)
treee28acccae721a37200503f6983edf56b42b9d4a4 /cpu-exec.c
parent1edaeee0955fba7d834b7c8f4e372e7eae030745 (diff)
downloadfocaccia-qemu-fdbc2b5722f6092e47181a947c90fd4bdcc1c121.tar.gz
focaccia-qemu-fdbc2b5722f6092e47181a947c90fd4bdcc1c121.zip
tcg: Add EXCP_ATOMIC
When we cannot emulate an atomic operation within a parallel
context, this exception allows us to stop the world and try
again in a serial context.

Reviewed-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'cpu-exec.c')
-rw-r--r--cpu-exec.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index e114fcdf29..c9997935dd 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -222,6 +222,36 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
 }
 #endif
 
+static void cpu_exec_step(CPUState *cpu)
+{
+    CPUArchState *env = (CPUArchState *)cpu->env_ptr;
+    TranslationBlock *tb;
+    target_ulong cs_base, pc;
+    uint32_t flags;
+
+    cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
+    tb = tb_gen_code(cpu, pc, cs_base, flags,
+                     1 | CF_NOCACHE | CF_IGNORE_ICOUNT);
+    tb->orig_tb = NULL;
+    /* execute the generated code */
+    trace_exec_tb_nocache(tb, pc);
+    cpu_tb_exec(cpu, tb);
+    tb_phys_invalidate(tb, -1);
+    tb_free(tb);
+}
+
+void cpu_exec_step_atomic(CPUState *cpu)
+{
+    start_exclusive();
+
+    /* Since we got here, we know that parallel_cpus must be true.  */
+    parallel_cpus = false;
+    cpu_exec_step(cpu);
+    parallel_cpus = true;
+
+    end_exclusive();
+}
+
 struct tb_desc {
     target_ulong pc;
     target_ulong cs_base;