diff options
author | Richard Henderson <rth@twiddle.net> | 2016-06-29 22:12:55 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-10-26 08:29:00 -0700 |
commit | fdbc2b5722f6092e47181a947c90fd4bdcc1c121 (patch) | |
tree | e28acccae721a37200503f6983edf56b42b9d4a4 /cpu-exec.c | |
parent | 1edaeee0955fba7d834b7c8f4e372e7eae030745 (diff) |
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.c | 30 |
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; |