To invalidate a TB on MacOS we need to enable write access to the JIT buffer. We were doing this for tb_phys_invalidate__locked but that is not the only path into do_tb_phys_invalidate. Move the manipulation into the shared function that does the work.
As a result we can drop the tb_phys_invalidate__locked function and update the calls directly. This enables watchpoints to work in MacOS TCG guests. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3444 Signed-off-by: Alex Bennée <[email protected]> --- v2 - make everyone call do_tb_phys_invalidate - tweak the if statement so we don't miss unlocking on an early return --- accel/tcg/tb-maint.c | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index cd7c32361bb..0c7ac5a72c0 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -925,6 +925,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) uint32_t orig_cflags = tb_cflags(tb); assert_memory_lock(); + qemu_thread_jit_write(); /* make sure no further incoming jumps will be chained to this TB */ qemu_spin_lock(&tb->jmp_lock); @@ -935,33 +936,27 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list) phys_pc = tb_page_addr0(tb); h = tb_hash_func(phys_pc, (orig_cflags & CF_PCREL ? 0 : tb->pc), tb->flags, tb->cs_base, orig_cflags); - if (!qht_remove(&tb_ctx.htable, tb, h)) { - return; - } + if (qht_remove(&tb_ctx.htable, tb, h)) { - /* remove the TB from the page list */ - if (rm_from_page_list) { - tb_remove(tb); - } + /* remove the TB from the page list */ + if (rm_from_page_list) { + tb_remove(tb); + } - /* remove the TB from the hash list */ - tb_jmp_cache_inval_tb(tb); + /* remove the TB from the hash list */ + tb_jmp_cache_inval_tb(tb); - /* suppress this TB from the two jump lists */ - tb_remove_from_jmp_list(tb, 0); - tb_remove_from_jmp_list(tb, 1); + /* suppress this TB from the two jump lists */ + tb_remove_from_jmp_list(tb, 0); + tb_remove_from_jmp_list(tb, 1); - /* suppress any remaining jumps to this TB */ - tb_jmp_unlink(tb); + /* suppress any remaining jumps to this TB */ + tb_jmp_unlink(tb); - qatomic_set(&tb_ctx.tb_phys_invalidate_count, - tb_ctx.tb_phys_invalidate_count + 1); -} + qatomic_set(&tb_ctx.tb_phys_invalidate_count, + tb_ctx.tb_phys_invalidate_count + 1); + } -static void tb_phys_invalidate__locked(TranslationBlock *tb) -{ - qemu_thread_jit_write(); - do_tb_phys_invalidate(tb, true); qemu_thread_jit_execute(); } @@ -1030,7 +1025,7 @@ void tb_invalidate_phys_range(CPUState *cpu, tb_page_addr_t start, assert_memory_lock(); PAGE_FOR_EACH_TB(start, last, unused, tb, n) { - tb_phys_invalidate__locked(tb); + do_tb_phys_invalidate(tb, true); } } @@ -1091,7 +1086,7 @@ bool tb_invalidate_phys_page_unwind(CPUState *cpu, tb_page_addr_t addr, current_tb_modified = true; cpu_restore_state_from_tb(cpu, current_tb, pc); } - tb_phys_invalidate__locked(tb); + do_tb_phys_invalidate(tb, true); } if (current_tb_modified) { @@ -1156,7 +1151,7 @@ tb_invalidate_phys_page_range__locked(CPUState *cpu, current_tb_modified = true; cpu_restore_state_from_tb(cpu, current_tb, retaddr); } - tb_phys_invalidate__locked(tb); + do_tb_phys_invalidate(tb, true); } } -- 2.47.3
