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
					
				| @ -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
 | ||||
|  * access (ie the address range covered by the watchpoint overlaps | ||||
|  * 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; | ||||
| } | ||||
| 
 | ||||
| /* 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 */ | ||||
| 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; | ||||
| } | ||||
| 
 | ||||
| /* 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, | ||||
|                                  MemTxAttrs attrs, void *buf, hwaddr len); | ||||
| static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Claudio Fontana
						Claudio Fontana