Skip to content

Commit

Permalink
translate-all: fix watchpoints if retranslation not possible
Browse files Browse the repository at this point in the history
The tb_check_watchpoint function currently assumes that all memory
access is done either directly through the TCG code or through an
helper which knows its return address. This is obviously wrong as the
helpers use cpu_ldxx/stxx_data functions to access the memory.

Instead of aborting in that case, don't try to retranslate the code, but
assume that the CPU state (and especially the program counter) has been
saved before calling the helper. Then invalidate the TB based on this
address.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information
aurel32 authored and agraf committed Jun 17, 2015
1 parent f0e0d81 commit 8d302e7
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions translate-all.c
Expand Up @@ -1431,12 +1431,22 @@ void tb_check_watchpoint(CPUState *cpu)
TranslationBlock *tb;

tb = tb_find_pc(cpu->mem_io_pc);
if (!tb) {
cpu_abort(cpu, "check_watchpoint: could not find TB for pc=%p",
(void *)cpu->mem_io_pc);
if (tb) {
/* We can use retranslation to find the PC. */
cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc);
tb_phys_invalidate(tb, -1);
} else {
/* The exception probably happened in a helper. The CPU state should
have been saved before calling it. Fetch the PC from there. */
CPUArchState *env = cpu->env_ptr;
target_ulong pc, cs_base;
tb_page_addr_t addr;
int flags;

cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
addr = get_page_addr_code(env, pc);
tb_invalidate_phys_range(addr, addr + 1);
}
cpu_restore_state_from_tb(cpu, tb, cpu->mem_io_pc);
tb_phys_invalidate(tb, -1);
}

#ifndef CONFIG_USER_ONLY
Expand Down

0 comments on commit 8d302e7

Please sign in to comment.