mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
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>
This commit is contained in:
parent
c34c762015
commit
5ee5993001
4 changed files with 22 additions and 0 deletions
|
@ -142,6 +142,9 @@ void cpu_check_irqs(CPUSPARCState *env)
|
|||
{
|
||||
CPUState *cs;
|
||||
|
||||
/* We should be holding the BQL before we mess with IRQs */
|
||||
g_assert(qemu_mutex_iothread_locked());
|
||||
|
||||
if (env->pil_in && (env->interrupt_index == 0 ||
|
||||
(env->interrupt_index & ~15) == TT_EXTINT)) {
|
||||
unsigned int i;
|
||||
|
|
|
@ -55,6 +55,9 @@ void cpu_check_irqs(CPUSPARCState *env)
|
|||
uint32_t pil = env->pil_in |
|
||||
(env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
|
||||
|
||||
/* We should be holding the BQL before we mess with IRQs */
|
||||
g_assert(qemu_mutex_iothread_locked());
|
||||
|
||||
/* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
|
||||
if (env->ivec_status & 0x20) {
|
||||
return;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue