translate-all: honour CF_NOCACHE in tb_gen_code
This fixes a record-replay regression introduced by 95590e2
("translate-all: discard TB when tb_link_page returns an existing
matching TB", 2018-06-15). The problem is that code using CF_NOCACHE
assumes that the TB returned from tb_gen_code is always a
newly-generated one. This assumption, however, was broken in
the aforementioned commit.
Fix it by honouring CF_NOCACHE, so that tb_gen_code always
returns a newly-generated TB when CF_NOCACHE is passed to it.
Do this by avoiding the TB hash table if CF_NOCACHE is set.
Reported-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Tested-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Signed-off-by: Emilio G. Cota <cota@braap.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Alistair Francis <alistair.francis@wdc.com>
Message-id: 1530806837-5416-1-git-send-email-cota@braap.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
6d1d4276ae
commit
ec7eb2ae77
|
@ -1446,7 +1446,8 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
|
||||||
phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
|
phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
|
||||||
h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb_cflags(tb) & CF_HASH_MASK,
|
h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb_cflags(tb) & CF_HASH_MASK,
|
||||||
tb->trace_vcpu_dstate);
|
tb->trace_vcpu_dstate);
|
||||||
if (!qht_remove(&tb_ctx.htable, tb, h)) {
|
if (!(tb->cflags & CF_NOCACHE) &&
|
||||||
|
!qht_remove(&tb_ctx.htable, tb, h)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1604,8 +1605,6 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
|
||||||
{
|
{
|
||||||
PageDesc *p;
|
PageDesc *p;
|
||||||
PageDesc *p2 = NULL;
|
PageDesc *p2 = NULL;
|
||||||
void *existing_tb = NULL;
|
|
||||||
uint32_t h;
|
|
||||||
|
|
||||||
assert_memory_lock();
|
assert_memory_lock();
|
||||||
|
|
||||||
|
@ -1625,6 +1624,10 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
|
||||||
tb->page_addr[1] = -1;
|
tb->page_addr[1] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(tb->cflags & CF_NOCACHE)) {
|
||||||
|
void *existing_tb = NULL;
|
||||||
|
uint32_t h;
|
||||||
|
|
||||||
/* add in the hash table */
|
/* add in the hash table */
|
||||||
h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK,
|
h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK,
|
||||||
tb->trace_vcpu_dstate);
|
tb->trace_vcpu_dstate);
|
||||||
|
@ -1640,6 +1643,7 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
|
||||||
}
|
}
|
||||||
tb = existing_tb;
|
tb = existing_tb;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (p2 && p2 != p) {
|
if (p2 && p2 != p) {
|
||||||
page_unlock(p2);
|
page_unlock(p2);
|
||||||
|
|
Loading…
Reference in a new issue