summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-07-11 16:47:42 +0200
committerJunfeng Dong <junfeng.dong@intel.com>2013-11-19 18:57:37 +0800
commitf2f0b2d804db9bfdab8ea7afe482ee57fa086f6b (patch)
tree7d42b9a36fab2189642cf66d069b87e26ca3a7d9
parent8c0bfdd62ef3cdf3f0b810659932c55c80da9537 (diff)
downloadqemu-f2f0b2d804db9bfdab8ea7afe482ee57fa086f6b.tar.gz
qemu-f2f0b2d804db9bfdab8ea7afe482ee57fa086f6b.tar.bz2
qemu-f2f0b2d804db9bfdab8ea7afe482ee57fa086f6b.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] Signed-off-by: Andreas Färber <afaerber@suse.de>
-rw-r--r--translate-all.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/translate-all.c b/translate-all.c
index 3b5fc7c90..165a63e29 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -612,19 +612,23 @@ 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_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer) >=
tcg_ctx.code_gen_buffer_max_size) {
+ 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. */
@@ -633,6 +637,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)
@@ -690,6 +695,7 @@ void tb_flush(CPUArchState *env1)
((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(env1, "Internal error: code buffer overflow\n");
@@ -710,6 +716,7 @@ void tb_flush(CPUArchState *env1)
/* 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
@@ -1019,8 +1026,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int current_flags = 0;
#endif /* TARGET_HAS_PRECISE_SMC */
+ tcg_lock();
p = page_find(start >> TARGET_PAGE_BITS);
if (!p) {
+ tcg_unlock();
return;
}
if (!p->code_bitmap &&
@@ -1113,6 +1122,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
cpu_resume_from_signal(env, NULL);
}
#endif
+ tcg_unlock();
}
/* len must be <= 8 and start must be a multiple of len */
@@ -1336,13 +1346,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) */
@@ -1353,6 +1366,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;
@@ -1360,7 +1374,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(TARGET_HAS_ICE) && !defined(CONFIG_USER_ONLY)