diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2017-03-01 13:20:02 +0000 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2017-03-09 10:41:38 +0000 |
commit | 5ee5993001cf32addb86a92e2ae8cb090fbc1462 (patch) | |
tree | 5c54fe7fef9dddfcc18ec6c56ae2e17903e2b726 /target | |
parent | c34c762015fec023c3ea5cf3629cbac462a80973 (diff) |
sparc/sparc64: grab BQL before calling cpu_check_irqs
IRQ modification is part of device emulation and should be done while
the BQL is held to prevent races when MTTCG is enabled. This adds
assertions in the hw emulation layer and wraps the calls from helpers
in the BQL.
Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/sparc/int64_helper.c | 3 | ||||
-rw-r--r-- | target/sparc/win_helper.c | 13 |
2 files changed, 16 insertions, 0 deletions
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c index 605747c93c..f942973c22 100644 --- a/target/sparc/int64_helper.c +++ b/target/sparc/int64_helper.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "exec/helper-proto.h" #include "exec/log.h" @@ -208,7 +209,9 @@ static bool do_modify_softint(CPUSPARCState *env, uint32_t value) env->softint = value; #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif return true; diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c index 71b3dd37e8..154279ecda 100644 --- a/target/sparc/win_helper.c +++ b/target/sparc/win_helper.c @@ -18,6 +18,7 @@ */ #include "qemu/osdep.h" +#include "qemu/main-loop.h" #include "cpu.h" #include "exec/exec-all.h" #include "exec/helper-proto.h" @@ -82,6 +83,7 @@ void cpu_put_psr_raw(CPUSPARCState *env, target_ulong val) #endif } +/* Called with BQL held */ void cpu_put_psr(CPUSPARCState *env, target_ulong val) { cpu_put_psr_raw(env, val); @@ -153,7 +155,10 @@ void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr) if ((new_psr & PSR_CWP) >= env->nwindows) { cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC()); } else { + /* cpu_put_psr may trigger interrupts, hence BQL */ + qemu_mutex_lock_iothread(); cpu_put_psr(env, new_psr); + qemu_mutex_unlock_iothread(); } } @@ -368,7 +373,9 @@ void helper_wrpstate(CPUSPARCState *env, target_ulong new_state) #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } @@ -381,7 +388,9 @@ void helper_wrpil(CPUSPARCState *env, target_ulong new_pil) env->psrpil = new_pil; if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } @@ -408,7 +417,9 @@ void helper_done(CPUSPARCState *env) #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } @@ -435,7 +446,9 @@ void helper_retry(CPUSPARCState *env) #if !defined(CONFIG_USER_ONLY) if (cpu_interrupts_enabled(env)) { + qemu_mutex_lock_iothread(); cpu_check_irqs(env); + qemu_mutex_unlock_iothread(); } #endif } |