diff options
author | Alexander Graf <agraf@suse.de> | 2012-07-11 16:47:42 +0200 |
---|---|---|
committer | hyokeun <hyokeun.jeon@samsung.com> | 2016-09-06 15:55:32 +0900 |
commit | 8b88a1089ad30f285527b82eccc72e856e359a33 (patch) | |
tree | e83163abd9680904b5a875f3d1cbbc4b80f874a8 | |
parent | 8f8f750a131b71d567bb5be15b2329b634408675 (diff) | |
download | qemu-8b88a1089ad30f285527b82eccc72e856e359a33.tar.gz qemu-8b88a1089ad30f285527b82eccc72e856e359a33.tar.bz2 qemu-8b88a1089ad30f285527b82eccc72e856e359a33.zip |
linux-user: lock tb flushing too
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto exec.c/translate-all.c split for 1.4]
[AF: Rebased onto tb_alloc() changes for v2.5.0-rc0]
Signed-off-by: Andreas Färber <afaerber@suse.de>
-rw-r--r-- | translate-all.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/translate-all.c b/translate-all.c index 0dd6466e0..1e7c61b38 100644 --- a/translate-all.c +++ b/translate-all.c @@ -767,17 +767,21 @@ static TranslationBlock *tb_alloc(target_ulong pc) { TranslationBlock *tb; + tcg_lock(); if (tcg_ctx.tb_ctx.nb_tbs >= tcg_ctx.code_gen_max_blocks) { + tcg_unlock(); return NULL; } tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++]; tb->pc = pc; tb->cflags = 0; + tcg_unlock(); return tb; } void tb_free(TranslationBlock *tb) { + tcg_lock(); /* In practice this is mostly used for single use temporary TB Ignore the hard cases and just back up if this TB happens to be the last one generated. */ @@ -786,6 +790,7 @@ void tb_free(TranslationBlock *tb) tcg_ctx.code_gen_ptr = tb->tc_ptr; tcg_ctx.tb_ctx.nb_tbs--; } + tcg_unlock(); } static inline void invalidate_page_bitmap(PageDesc *p) @@ -844,6 +849,7 @@ void tb_flush(CPUState *cpu) ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)) / tcg_ctx.tb_ctx.nb_tbs : 0); #endif + tcg_lock(); if ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) > tcg_ctx.code_gen_buffer_size) { cpu_abort(cpu, "Internal error: code buffer overflow\n"); @@ -862,6 +868,7 @@ void tb_flush(CPUState *cpu) /* XXX: flush processor icache at this point if cache flush is expensive */ tcg_ctx.tb_ctx.tb_flush_count++; + tcg_unlock(); } #ifdef DEBUG_TB_CHECK @@ -1320,8 +1327,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, uint32_t current_flags = 0; #endif /* TARGET_HAS_PRECISE_SMC */ + tcg_lock(); p = page_find(start >> TARGET_PAGE_BITS); if (!p) { + tcg_unlock(); return; } #if defined(TARGET_HAS_PRECISE_SMC) @@ -1392,6 +1401,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end, cpu_loop_exit_noexc(cpu); } #endif + tcg_unlock(); } #ifdef CONFIG_SOFTMMU @@ -1509,13 +1519,16 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr) { int m_min, m_max, m; uintptr_t v; - TranslationBlock *tb; + TranslationBlock *tb, *r; + tcg_lock(); if (tcg_ctx.tb_ctx.nb_tbs <= 0) { + tcg_unlock(); return NULL; } if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer || tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) { + tcg_unlock(); return NULL; } /* binary search (cf Knuth) */ @@ -1526,6 +1539,7 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr) tb = &tcg_ctx.tb_ctx.tbs[m]; v = (uintptr_t)tb->tc_ptr; if (v == tc_ptr) { + tcg_unlock(); return tb; } else if (tc_ptr < v) { m_max = m - 1; @@ -1533,7 +1547,9 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr) m_min = m + 1; } } - return &tcg_ctx.tb_ctx.tbs[m_max]; + r = &tcg_ctx.tb_ctx.tbs[m_max]; + tcg_unlock(); + return r; } #if !defined(CONFIG_USER_ONLY) |