mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 18:44:58 -06:00
physmem: make watchpoint checking code TCG-only
cpu_check_watchpoint, watchpoint_address_matches are TCG-only. Signed-off-by: Claudio Fontana <cfontana@suse.de> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210204163931.7358-13-cfontana@suse.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
8535dd702d
commit
79fc8d4511
1 changed files with 72 additions and 69 deletions
|
@ -840,6 +840,7 @@ void cpu_watchpoint_remove_all(CPUState *cpu, int mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_TCG
|
||||||
/* Return true if this watchpoint address matches the specified
|
/* Return true if this watchpoint address matches the specified
|
||||||
* access (ie the address range covered by the watchpoint overlaps
|
* access (ie the address range covered by the watchpoint overlaps
|
||||||
* partially or completely with the address range covered by the
|
* partially or completely with the address range covered by the
|
||||||
|
@ -873,6 +874,77 @@ int cpu_watchpoint_address_matches(CPUState *cpu, vaddr addr, vaddr len)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Generate a debug exception if a watchpoint has been hit. */
|
||||||
|
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
||||||
|
MemTxAttrs attrs, int flags, uintptr_t ra)
|
||||||
|
{
|
||||||
|
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||||
|
CPUWatchpoint *wp;
|
||||||
|
|
||||||
|
assert(tcg_enabled());
|
||||||
|
if (cpu->watchpoint_hit) {
|
||||||
|
/*
|
||||||
|
* We re-entered the check after replacing the TB.
|
||||||
|
* Now raise the debug interrupt so that it will
|
||||||
|
* trigger after the current instruction.
|
||||||
|
*/
|
||||||
|
qemu_mutex_lock_iothread();
|
||||||
|
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
|
||||||
|
qemu_mutex_unlock_iothread();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr = cc->adjust_watchpoint_address(cpu, addr, len);
|
||||||
|
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||||
|
if (watchpoint_address_matches(wp, addr, len)
|
||||||
|
&& (wp->flags & flags)) {
|
||||||
|
if (replay_running_debug()) {
|
||||||
|
/*
|
||||||
|
* Don't process the watchpoints when we are
|
||||||
|
* in a reverse debugging operation.
|
||||||
|
*/
|
||||||
|
replay_breakpoint();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (flags == BP_MEM_READ) {
|
||||||
|
wp->flags |= BP_WATCHPOINT_HIT_READ;
|
||||||
|
} else {
|
||||||
|
wp->flags |= BP_WATCHPOINT_HIT_WRITE;
|
||||||
|
}
|
||||||
|
wp->hitaddr = MAX(addr, wp->vaddr);
|
||||||
|
wp->hitattrs = attrs;
|
||||||
|
if (!cpu->watchpoint_hit) {
|
||||||
|
if (wp->flags & BP_CPU &&
|
||||||
|
!cc->debug_check_watchpoint(cpu, wp)) {
|
||||||
|
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cpu->watchpoint_hit = wp;
|
||||||
|
|
||||||
|
mmap_lock();
|
||||||
|
tb_check_watchpoint(cpu, ra);
|
||||||
|
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
|
||||||
|
cpu->exception_index = EXCP_DEBUG;
|
||||||
|
mmap_unlock();
|
||||||
|
cpu_loop_exit_restore(cpu, ra);
|
||||||
|
} else {
|
||||||
|
/* Force execution of one insn next time. */
|
||||||
|
cpu->cflags_next_tb = 1 | curr_cflags();
|
||||||
|
mmap_unlock();
|
||||||
|
if (ra) {
|
||||||
|
cpu_restore_state(cpu, ra, true);
|
||||||
|
}
|
||||||
|
cpu_loop_exit_noexc(cpu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_TCG */
|
||||||
|
|
||||||
/* Called from RCU critical section */
|
/* Called from RCU critical section */
|
||||||
static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
|
static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
|
||||||
{
|
{
|
||||||
|
@ -2359,75 +2431,6 @@ ram_addr_t qemu_ram_addr_from_host(void *ptr)
|
||||||
return block->offset + offset;
|
return block->offset + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a debug exception if a watchpoint has been hit. */
|
|
||||||
void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
|
||||||
MemTxAttrs attrs, int flags, uintptr_t ra)
|
|
||||||
{
|
|
||||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
|
||||||
CPUWatchpoint *wp;
|
|
||||||
|
|
||||||
assert(tcg_enabled());
|
|
||||||
if (cpu->watchpoint_hit) {
|
|
||||||
/*
|
|
||||||
* We re-entered the check after replacing the TB.
|
|
||||||
* Now raise the debug interrupt so that it will
|
|
||||||
* trigger after the current instruction.
|
|
||||||
*/
|
|
||||||
qemu_mutex_lock_iothread();
|
|
||||||
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
|
|
||||||
qemu_mutex_unlock_iothread();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
addr = cc->adjust_watchpoint_address(cpu, addr, len);
|
|
||||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
|
||||||
if (watchpoint_address_matches(wp, addr, len)
|
|
||||||
&& (wp->flags & flags)) {
|
|
||||||
if (replay_running_debug()) {
|
|
||||||
/*
|
|
||||||
* Don't process the watchpoints when we are
|
|
||||||
* in a reverse debugging operation.
|
|
||||||
*/
|
|
||||||
replay_breakpoint();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (flags == BP_MEM_READ) {
|
|
||||||
wp->flags |= BP_WATCHPOINT_HIT_READ;
|
|
||||||
} else {
|
|
||||||
wp->flags |= BP_WATCHPOINT_HIT_WRITE;
|
|
||||||
}
|
|
||||||
wp->hitaddr = MAX(addr, wp->vaddr);
|
|
||||||
wp->hitattrs = attrs;
|
|
||||||
if (!cpu->watchpoint_hit) {
|
|
||||||
if (wp->flags & BP_CPU &&
|
|
||||||
!cc->debug_check_watchpoint(cpu, wp)) {
|
|
||||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cpu->watchpoint_hit = wp;
|
|
||||||
|
|
||||||
mmap_lock();
|
|
||||||
tb_check_watchpoint(cpu, ra);
|
|
||||||
if (wp->flags & BP_STOP_BEFORE_ACCESS) {
|
|
||||||
cpu->exception_index = EXCP_DEBUG;
|
|
||||||
mmap_unlock();
|
|
||||||
cpu_loop_exit_restore(cpu, ra);
|
|
||||||
} else {
|
|
||||||
/* Force execution of one insn next time. */
|
|
||||||
cpu->cflags_next_tb = 1 | curr_cflags();
|
|
||||||
mmap_unlock();
|
|
||||||
if (ra) {
|
|
||||||
cpu_restore_state(cpu, ra, true);
|
|
||||||
}
|
|
||||||
cpu_loop_exit_noexc(cpu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
|
||||||
MemTxAttrs attrs, void *buf, hwaddr len);
|
MemTxAttrs attrs, void *buf, hwaddr len);
|
||||||
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue