diff options
-rw-r--r-- | exec-i386.c | 11 | ||||
-rw-r--r-- | exec.h | 21 |
2 files changed, 18 insertions, 14 deletions
diff --git a/exec-i386.c b/exec-i386.c index 978b1da9d8..68e0371cc7 100644 --- a/exec-i386.c +++ b/exec-i386.c @@ -206,14 +206,13 @@ int cpu_x86_exec(CPUX86State *env1) flags |= (1 << GEN_FLAG_VM_SHIFT); flags |= (3 << GEN_FLAG_CPL_SHIFT); } - flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT); - flags |= (env->eflags & TF_MASK) << (GEN_FLAG_TF_SHIFT - 8); + flags |= (env->eflags & (IOPL_MASK | TF_MASK)); cs_base = env->seg_cache[R_CS].base; pc = cs_base + env->eip; - spin_lock(&tb_lock); tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, flags); if (!tb) { + spin_lock(&tb_lock); /* if no translated code available, then translate it now */ tb = tb_alloc((unsigned long)pc); if (!tb) { @@ -244,6 +243,7 @@ int cpu_x86_exec(CPUX86State *env1) tb->hash_next = NULL; tb_link(tb); code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); + spin_unlock(&tb_lock); } #ifdef DEBUG_EXEC if (loglevel) { @@ -252,13 +252,14 @@ int cpu_x86_exec(CPUX86State *env1) lookup_symbol((void *)tb->pc)); } #endif - /* see if we can patch the calling TB */ if (T0 != 0 && !(env->eflags & TF_MASK)) { + spin_lock(&tb_lock); tb_add_jump((TranslationBlock *)(T0 & ~3), T0 & 3, tb); + spin_unlock(&tb_lock); } + tc_ptr = tb->tc_ptr; - spin_unlock(&tb_lock); /* execute the generated code */ gen_func = (void *)tc_ptr; @@ -23,9 +23,9 @@ #define GEN_FLAG_SS32_SHIFT 2 #define GEN_FLAG_VM_SHIFT 3 #define GEN_FLAG_ST_SHIFT 4 -#define GEN_FLAG_CPL_SHIFT 7 -#define GEN_FLAG_IOPL_SHIFT 9 -#define GEN_FLAG_TF_SHIFT 11 +#define GEN_FLAG_TF_SHIFT 8 /* same position as eflags */ +#define GEN_FLAG_CPL_SHIFT 9 +#define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */ struct TranslationBlock; int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -150,12 +150,15 @@ static inline void tb_set_jmp_target(TranslationBlock *tb, static inline void tb_add_jump(TranslationBlock *tb, int n, TranslationBlock *tb_next) { - /* patch the native jump address */ - tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr); - - /* add in TB jmp circular list */ - tb->jmp_next[n] = tb_next->jmp_first; - tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n)); + /* NOTE: this test is only needed for thread safety */ + if (!tb->jmp_next[n]) { + /* patch the native jump address */ + tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr); + + /* add in TB jmp circular list */ + tb->jmp_next[n] = tb_next->jmp_first; + tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n)); + } } #ifndef offsetof |