diff options
author | Emilio G. Cota <cota@braap.org> | 2018-07-05 12:07:17 -0400 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-07-09 16:14:36 +0100 |
commit | ec7eb2ae77cc207064e17ace048f7ec0c4b85d6f (patch) | |
tree | ad3b328853c61619b35bdabf21721156ac41377b /accel/tcg | |
parent | 6d1d4276aea9773af97fed651cb205aab4f1b163 (diff) |
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>
Diffstat (limited to 'accel/tcg')
-rw-r--r-- | accel/tcg/translate-all.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 170b95793f..49d77fad44 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -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); h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb_cflags(tb) & CF_HASH_MASK, 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; } @@ -1604,8 +1605,6 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, { PageDesc *p; PageDesc *p2 = NULL; - void *existing_tb = NULL; - uint32_t h; assert_memory_lock(); @@ -1625,20 +1624,25 @@ tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb->page_addr[1] = -1; } - /* add in the hash table */ - h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK, - tb->trace_vcpu_dstate); - qht_insert(&tb_ctx.htable, tb, h, &existing_tb); + if (!(tb->cflags & CF_NOCACHE)) { + void *existing_tb = NULL; + uint32_t h; - /* remove TB from the page(s) if we couldn't insert it */ - if (unlikely(existing_tb)) { - tb_page_remove(p, tb); - invalidate_page_bitmap(p); - if (p2) { - tb_page_remove(p2, tb); - invalidate_page_bitmap(p2); + /* add in the hash table */ + h = tb_hash_func(phys_pc, tb->pc, tb->flags, tb->cflags & CF_HASH_MASK, + tb->trace_vcpu_dstate); + qht_insert(&tb_ctx.htable, tb, h, &existing_tb); + + /* remove TB from the page(s) if we couldn't insert it */ + if (unlikely(existing_tb)) { + tb_page_remove(p, tb); + invalidate_page_bitmap(p); + if (p2) { + tb_page_remove(p2, tb); + invalidate_page_bitmap(p2); + } + tb = existing_tb; } - tb = existing_tb; } if (p2 && p2 != p) { |