aboutsummaryrefslogtreecommitdiff
path: root/cpus.c
diff options
context:
space:
mode:
authorPranith Kumar <bobby.prani@gmail.com>2017-02-23 18:29:15 +0000
committerAlex Bennée <alex.bennee@linaro.org>2017-02-24 10:32:45 +0000
commit08e73c48b053566bfe0c994f154f73991cd0ff0e (patch)
tree5a2a033b6acfc8d41d65424a695943c6f9480337 /cpus.c
parent372579427a5040a26dfee78464b50e2bdf27ef26 (diff)
tcg: handle EXCP_ATOMIC exception for system emulation
The patch enables handling atomic code in the guest. This should be preferably done in cpu_handle_exception(), but the current assumptions regarding when we can execute atomic sections cause a deadlock. The current mechanism discards the flags which were set in atomic execution. We ensure they are properly saved by calling the cc->cpu_exec_enter/leave() functions around the loop. As we are running cpu_exec_step_atomic() from the outermost loop we need to avoid an abort() when single stepping over atomic code since debug exception longjmp will point to the the setlongjmp in cpu_exec(). We do this by setting a new jmp_env so that it jumps back here on an exception. Signed-off-by: Pranith Kumar <bobby.prani@gmail.com> [AJB: tweak title, merge with new patches, add mmap_lock] Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <rth@twiddle.net> CC: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'cpus.c')
-rw-r--r--cpus.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/cpus.c b/cpus.c
index bfee326d30..8200ac6b75 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1348,6 +1348,11 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
if (r == EXCP_DEBUG) {
cpu_handle_guest_debug(cpu);
break;
+ } else if (r == EXCP_ATOMIC) {
+ qemu_mutex_unlock_iothread();
+ cpu_exec_step_atomic(cpu);
+ qemu_mutex_lock_iothread();
+ break;
}
} else if (cpu->stop) {
if (cpu->unplug) {
@@ -1458,6 +1463,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
*/
g_assert(cpu->halted);
break;
+ case EXCP_ATOMIC:
+ qemu_mutex_unlock_iothread();
+ cpu_exec_step_atomic(cpu);
+ qemu_mutex_lock_iothread();
default:
/* Ignore everything else? */
break;