cpu: Move mem_io_{pc,vaddr} fields from CPU_COMMON to CPUState
Reset them. Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
parent
7510454e3e
commit
93afeade09
9
exec.c
9
exec.c
@ -1553,7 +1553,7 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
|
|||||||
flushed */
|
flushed */
|
||||||
if (!cpu_physical_memory_is_clean(ram_addr)) {
|
if (!cpu_physical_memory_is_clean(ram_addr)) {
|
||||||
CPUArchState *env = current_cpu->env_ptr;
|
CPUArchState *env = current_cpu->env_ptr;
|
||||||
tlb_set_dirty(env, env->mem_io_vaddr);
|
tlb_set_dirty(env, current_cpu->mem_io_vaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1572,7 +1572,8 @@ static const MemoryRegionOps notdirty_mem_ops = {
|
|||||||
/* Generate a debug exception if a watchpoint has been hit. */
|
/* Generate a debug exception if a watchpoint has been hit. */
|
||||||
static void check_watchpoint(int offset, int len_mask, int flags)
|
static void check_watchpoint(int offset, int len_mask, int flags)
|
||||||
{
|
{
|
||||||
CPUArchState *env = current_cpu->env_ptr;
|
CPUState *cpu = current_cpu;
|
||||||
|
CPUArchState *env = cpu->env_ptr;
|
||||||
target_ulong pc, cs_base;
|
target_ulong pc, cs_base;
|
||||||
target_ulong vaddr;
|
target_ulong vaddr;
|
||||||
CPUWatchpoint *wp;
|
CPUWatchpoint *wp;
|
||||||
@ -1582,10 +1583,10 @@ static void check_watchpoint(int offset, int len_mask, int flags)
|
|||||||
/* We re-entered the check after replacing the TB. Now raise
|
/* We re-entered the check after replacing the TB. Now raise
|
||||||
* the debug interrupt so that is will trigger after the
|
* the debug interrupt so that is will trigger after the
|
||||||
* current instruction. */
|
* current instruction. */
|
||||||
cpu_interrupt(ENV_GET_CPU(env), CPU_INTERRUPT_DEBUG);
|
cpu_interrupt(cpu, CPU_INTERRUPT_DEBUG);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
|
vaddr = (cpu->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
|
||||||
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
|
QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
|
||||||
if ((vaddr == (wp->vaddr & len_mask) ||
|
if ((vaddr == (wp->vaddr & len_mask) ||
|
||||||
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
|
(vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
|
||||||
|
@ -406,7 +406,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!kvm_enabled()) {
|
if (!kvm_enabled()) {
|
||||||
cpu_restore_state(env, env->mem_io_pc);
|
cpu_restore_state(env, cs->mem_io_pc);
|
||||||
cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
|
cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
|
||||||
¤t_flags);
|
¤t_flags);
|
||||||
}
|
}
|
||||||
|
@ -146,13 +146,6 @@ typedef struct CPUWatchpoint {
|
|||||||
#define CPU_TEMP_BUF_NLONGS 128
|
#define CPU_TEMP_BUF_NLONGS 128
|
||||||
#define CPU_COMMON \
|
#define CPU_COMMON \
|
||||||
/* soft mmu support */ \
|
/* soft mmu support */ \
|
||||||
/* in order to avoid passing too many arguments to the MMIO \
|
|
||||||
helpers, we store some rarely used information in the CPU \
|
|
||||||
context) */ \
|
|
||||||
uintptr_t mem_io_pc; /* host pc at which the memory was \
|
|
||||||
accessed */ \
|
|
||||||
target_ulong mem_io_vaddr; /* target virtual addr at which the \
|
|
||||||
memory was accessed */ \
|
|
||||||
CPU_COMMON_TLB \
|
CPU_COMMON_TLB \
|
||||||
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
|
struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
|
||||||
\
|
\
|
||||||
|
@ -126,12 +126,12 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
|
|||||||
MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr);
|
MemoryRegion *mr = iotlb_to_region(cpu->as, physaddr);
|
||||||
|
|
||||||
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
|
||||||
env->mem_io_pc = retaddr;
|
cpu->mem_io_pc = retaddr;
|
||||||
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !can_do_io(env)) {
|
if (mr != &io_mem_rom && mr != &io_mem_notdirty && !can_do_io(env)) {
|
||||||
cpu_io_recompile(env, retaddr);
|
cpu_io_recompile(env, retaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
env->mem_io_vaddr = addr;
|
cpu->mem_io_vaddr = addr;
|
||||||
io_mem_read(mr, physaddr, &val, 1 << SHIFT);
|
io_mem_read(mr, physaddr, &val, 1 << SHIFT);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -337,8 +337,8 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
|
|||||||
cpu_io_recompile(env, retaddr);
|
cpu_io_recompile(env, retaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
env->mem_io_vaddr = addr;
|
cpu->mem_io_vaddr = addr;
|
||||||
env->mem_io_pc = retaddr;
|
cpu->mem_io_pc = retaddr;
|
||||||
io_mem_write(mr, physaddr, val, 1 << SHIFT);
|
io_mem_write(mr, physaddr, val, 1 << SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +163,8 @@ struct kvm_run;
|
|||||||
* @gdb_num_regs: Number of total registers accessible to GDB.
|
* @gdb_num_regs: Number of total registers accessible to GDB.
|
||||||
* @gdb_num_g_regs: Number of registers in GDB 'g' packets.
|
* @gdb_num_g_regs: Number of registers in GDB 'g' packets.
|
||||||
* @next_cpu: Next CPU sharing TB cache.
|
* @next_cpu: Next CPU sharing TB cache.
|
||||||
|
* @mem_io_pc: Host Program Counter at which the memory was accessed.
|
||||||
|
* @mem_io_vaddr: Target virtual address at which the memory was accessed.
|
||||||
* @kvm_fd: vCPU file descriptor for KVM.
|
* @kvm_fd: vCPU file descriptor for KVM.
|
||||||
*
|
*
|
||||||
* State of one CPU core or thread.
|
* State of one CPU core or thread.
|
||||||
@ -204,6 +206,12 @@ struct CPUState {
|
|||||||
int gdb_num_g_regs;
|
int gdb_num_g_regs;
|
||||||
QTAILQ_ENTRY(CPUState) node;
|
QTAILQ_ENTRY(CPUState) node;
|
||||||
|
|
||||||
|
/* In order to avoid passing too many arguments to the MMIO helpers,
|
||||||
|
* we store some rarely used information in the CPU context.
|
||||||
|
*/
|
||||||
|
uintptr_t mem_io_pc;
|
||||||
|
vaddr mem_io_vaddr;
|
||||||
|
|
||||||
int kvm_fd;
|
int kvm_fd;
|
||||||
bool kvm_vcpu_dirty;
|
bool kvm_vcpu_dirty;
|
||||||
struct KVMState *kvm_state;
|
struct KVMState *kvm_state;
|
||||||
|
@ -239,6 +239,8 @@ static void cpu_common_reset(CPUState *cpu)
|
|||||||
cpu->interrupt_request = 0;
|
cpu->interrupt_request = 0;
|
||||||
cpu->current_tb = NULL;
|
cpu->current_tb = NULL;
|
||||||
cpu->halted = 0;
|
cpu->halted = 0;
|
||||||
|
cpu->mem_io_pc = 0;
|
||||||
|
cpu->mem_io_vaddr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cpu_common_has_work(CPUState *cs)
|
static bool cpu_common_has_work(CPUState *cs)
|
||||||
|
@ -1254,13 +1254,14 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
|
|||||||
void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
|
void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
|
||||||
{
|
{
|
||||||
X86CPU *cpu = x86_env_get_cpu(env);
|
X86CPU *cpu = x86_env_get_cpu(env);
|
||||||
|
CPUState *cs = CPU(cpu);
|
||||||
|
|
||||||
if (kvm_enabled()) {
|
if (kvm_enabled()) {
|
||||||
env->tpr_access_type = access;
|
env->tpr_access_type = access;
|
||||||
|
|
||||||
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_TPR);
|
cpu_interrupt(cs, CPU_INTERRUPT_TPR);
|
||||||
} else {
|
} else {
|
||||||
cpu_restore_state(env, env->mem_io_pc);
|
cpu_restore_state(env, cs->mem_io_pc);
|
||||||
|
|
||||||
apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
|
apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
|
||||||
}
|
}
|
||||||
|
@ -1063,9 +1063,9 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
|||||||
if (current_tb_not_found) {
|
if (current_tb_not_found) {
|
||||||
current_tb_not_found = 0;
|
current_tb_not_found = 0;
|
||||||
current_tb = NULL;
|
current_tb = NULL;
|
||||||
if (env->mem_io_pc) {
|
if (cpu->mem_io_pc) {
|
||||||
/* now we have a real cpu fault */
|
/* now we have a real cpu fault */
|
||||||
current_tb = tb_find_pc(env->mem_io_pc);
|
current_tb = tb_find_pc(cpu->mem_io_pc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (current_tb == tb &&
|
if (current_tb == tb &&
|
||||||
@ -1077,7 +1077,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
|||||||
restore the CPU state */
|
restore the CPU state */
|
||||||
|
|
||||||
current_tb_modified = 1;
|
current_tb_modified = 1;
|
||||||
cpu_restore_state_from_tb(current_tb, env, env->mem_io_pc);
|
cpu_restore_state_from_tb(current_tb, env, cpu->mem_io_pc);
|
||||||
cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
|
cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base,
|
||||||
¤t_flags);
|
¤t_flags);
|
||||||
}
|
}
|
||||||
@ -1104,7 +1104,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
|||||||
if (!p->first_tb) {
|
if (!p->first_tb) {
|
||||||
invalidate_page_bitmap(p);
|
invalidate_page_bitmap(p);
|
||||||
if (is_cpu_write_access) {
|
if (is_cpu_write_access) {
|
||||||
tlb_unprotect_code_phys(env, start, env->mem_io_vaddr);
|
tlb_unprotect_code_phys(env, start, cpu->mem_io_vaddr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1376,14 +1376,15 @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
|
|||||||
|
|
||||||
void tb_check_watchpoint(CPUArchState *env)
|
void tb_check_watchpoint(CPUArchState *env)
|
||||||
{
|
{
|
||||||
|
CPUState *cpu = ENV_GET_CPU(env);
|
||||||
TranslationBlock *tb;
|
TranslationBlock *tb;
|
||||||
|
|
||||||
tb = tb_find_pc(env->mem_io_pc);
|
tb = tb_find_pc(cpu->mem_io_pc);
|
||||||
if (!tb) {
|
if (!tb) {
|
||||||
cpu_abort(env, "check_watchpoint: could not find TB for pc=%p",
|
cpu_abort(env, "check_watchpoint: could not find TB for pc=%p",
|
||||||
(void *)env->mem_io_pc);
|
(void *)cpu->mem_io_pc);
|
||||||
}
|
}
|
||||||
cpu_restore_state_from_tb(tb, env, env->mem_io_pc);
|
cpu_restore_state_from_tb(tb, env, cpu->mem_io_pc);
|
||||||
tb_phys_invalidate(tb, -1);
|
tb_phys_invalidate(tb, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user