From 84d6bd737ce0dd9471aa9d589d918406f2c3c6e8 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 5 Jul 2012 17:31:39 +0200 Subject: [PATCH] linux-user: lock tcg The tcg code generator is not thread safe. Lock its generation between different threads. Signed-off-by: Alexander Graf --- linux-user/mmap.c | 3 +++ tcg/tcg.c | 29 +++++++++++++++++++++++++++-- tcg/tcg.h | 6 ++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 3f5e1d7..a669b3a 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -30,6 +30,7 @@ #include "qemu.h" #include "qemu-common.h" +#include "tcg.h" //#define DEBUG_MMAP @@ -42,6 +43,7 @@ void mmap_lock(void) if (mmap_lock_count++ == 0) { pthread_mutex_lock(&mmap_mutex); } + tcg_lock(); } void mmap_unlock(void) @@ -49,6 +51,7 @@ void mmap_unlock(void) if (--mmap_lock_count == 0) { pthread_mutex_unlock(&mmap_mutex); } + tcg_unlock(); } /* Grab lock to make sure things are in a consistent state after fork(). */ diff --git a/tcg/tcg.c b/tcg/tcg.c index ab589c7..c315e2a 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -40,6 +40,8 @@ #include "cache-utils.h" #include "host-utils.h" #include "qemu-timer.h" +#include "config-host.h" +#include "qemu-thread.h" /* Note: the long term plan is to reduce the dependancies on the QEMU CPU definitions. Currently they are used for qemu_ld/st @@ -105,6 +107,22 @@ static TCGRegSet tcg_target_call_clobber_regs; uint16_t *gen_opc_ptr; TCGArg *gen_opparam_ptr; +void tcg_lock(void) +{ +#ifdef CONFIG_USER_ONLY + TCGContext *s = &tcg_ctx; + qemu_mutex_lock(&s->lock); +#endif +} + +void tcg_unlock(void) +{ +#ifdef CONFIG_USER_ONLY + TCGContext *s = &tcg_ctx; + qemu_mutex_unlock(&s->lock); +#endif +} + static inline void tcg_out8(TCGContext *s, uint8_t v) { *s->code_ptr++ = v; @@ -245,7 +263,8 @@ void tcg_context_init(TCGContext *s) memset(s, 0, sizeof(*s)); s->temps = s->static_temps; s->nb_globals = 0; - + qemu_mutex_init(&s->lock); + /* Count total number of arguments and allocate the corresponding space */ total_args = 0; @@ -2182,11 +2201,13 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf) } #endif + tcg_lock(); tcg_gen_code_common(s, gen_code_buf, -1); /* flush instruction cache */ flush_icache_range((tcg_target_ulong)gen_code_buf, (tcg_target_ulong)s->code_ptr); + tcg_unlock(); return s->code_ptr - gen_code_buf; } @@ -2197,7 +2218,11 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf) Return -1 if not found. */ int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset) { - return tcg_gen_code_common(s, gen_code_buf, offset); + int r; + tcg_lock(); + r = tcg_gen_code_common(s, gen_code_buf, offset); + tcg_unlock(); + return r; } #ifdef CONFIG_PROFILER diff --git a/tcg/tcg.h b/tcg/tcg.h index a83bddd..e20fc82 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -46,6 +46,8 @@ typedef uint64_t tcg_target_ulong; #error unsupported #endif +#include "config-host.h" +#include "qemu-thread.h" #include "tcg-target.h" #include "tcg-runtime.h" @@ -389,6 +391,7 @@ struct TCGContext { #ifdef CONFIG_DEBUG_TCG int temps_in_use; #endif + QemuMutex lock; }; extern TCGContext tcg_ctx; @@ -568,6 +571,9 @@ void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args, TCGOpDef *tcg_op_def); +extern void tcg_lock(void); +extern void tcg_unlock(void); + /* only used for debugging purposes */ void tcg_register_helper(void *func, const char *name); const char *tcg_helper_get_name(TCGContext *s, void *func);