diff --git a/qemu-lock.h b/qemu-lock.h index a72edda1d2..e460e129a5 100644 --- a/qemu-lock.h +++ b/qemu-lock.h @@ -24,6 +24,12 @@ #include #define spin_lock pthread_mutex_lock #define spin_unlock pthread_mutex_unlock +static inline void spin_unlock_safe(pthread_mutex_t *lock) +{ + /* unlocking an unlocked mutex results in undefined behavior */ + pthread_mutex_trylock(lock); + pthread_mutex_unlock(lock); +} #define spinlock_t pthread_mutex_t #define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER @@ -46,4 +52,8 @@ static inline void spin_unlock(spinlock_t *lock) { } +static inline void spin_unlock_safe(spinlock_t *lock) +{ +} + #endif diff --git a/user-exec.c b/user-exec.c index ef9b1727b3..1ec5d9af9a 100644 --- a/user-exec.c +++ b/user-exec.c @@ -88,6 +88,10 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address, qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", pc, address, is_write, *(unsigned long *)old_set); #endif + + /* Maybe we're still holding the TB fiddling lock? */ + spin_unlock_safe(&tb_lock); + /* XXX: locking issue */ if (is_write && h2g_valid(address) && page_unprotect(h2g(address), pc, puc)) {