diff --git a/qemu/accel/tcg/cpu-exec.c b/qemu/accel/tcg/cpu-exec.c index 1236da69..b6ff4b0a 100644 --- a/qemu/accel/tcg/cpu-exec.c +++ b/qemu/accel/tcg/cpu-exec.c @@ -60,17 +60,19 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb) * or timer mode is in effect, since these already fix the PC. */ if (!HOOK_EXISTS(env->uc, UC_HOOK_CODE) && !env->uc->timeout) { - if (cc->synchronize_from_tb) { + if (cc->tcg_ops.synchronize_from_tb) { // avoid sync twice when helper_uc_tracecode() already did this. if (env->uc->emu_counter <= env->uc->emu_count && - !env->uc->stop_request && !env->uc->quit_request) - cc->synchronize_from_tb(cpu, last_tb); + !env->uc->stop_request && !env->uc->quit_request) { + cc->tcg_ops.synchronize_from_tb(cpu, last_tb); + } } else { assert(cc->set_pc); // avoid sync twice when helper_uc_tracecode() already did this. if (env->uc->emu_counter <= env->uc->emu_count && - !env->uc->stop_request && !env->uc->quit_request) + !env->uc->stop_request && !env->uc->quit_request) { cc->set_pc(cpu, last_tb->pc); + } } } } diff --git a/qemu/include/qom/cpu.h b/qemu/include/qom/cpu.h index 7998ff37..42ec521e 100644 --- a/qemu/include/qom/cpu.h +++ b/qemu/include/qom/cpu.h @@ -85,6 +85,20 @@ typedef struct TcgCpuOperations { */ void (*initialize)(struct uc_struct *uc); + /** + * @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock + * + * This is called when we abandon execution of a TB before starting it, + * and must set all parts of the CPU state which the previous TB in the + * chain may not have updated. + * By default, when this is NULL, a call is made to @set_pc(tb->pc). + * + * If more state needs to be restored, the target must implement a + * function to restore all the state, and register it here. + */ + void (*synchronize_from_tb)(CPUState *cpu, + const struct TranslationBlock *tb); + } TcgCpuOperations; /** @@ -116,13 +130,6 @@ typedef struct TcgCpuOperations { * If the target behaviour here is anything other than "set * the PC register to the value passed in" then the target must * also implement the synchronize_from_tb hook. - * @synchronize_from_tb: Callback for synchronizing state from a TCG - * #TranslationBlock. This is called when we abandon execution - * of a TB before starting it, and must set all parts of the CPU - * state which the previous TB in the chain may not have updated. - * This always includes at least the program counter; some targets - * will need to do more. If this hook is not implemented then the - * default is to call @set_pc(tb->pc). * @tlb_fill: Callback for handling a softmmu tlb miss or user-only * address fault. For system mode, if the access is valid, call * tlb_set_page and return true; if the access is invalid, and @@ -179,7 +186,6 @@ typedef struct CPUClass { void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list, Error **errp); void (*set_pc)(CPUState *cpu, vaddr value); - void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb); bool (*tlb_fill)(CPUState *cpu, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index fcb6862d..7341dbe6 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -45,7 +45,8 @@ static void arm_cpu_set_pc(CPUState *cs, vaddr value) } } -static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +#ifdef CONFIG_TCG +static void arm_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { ARMCPU *cpu = ARM_CPU(NULL, cs); CPUARMState *env = &cpu->env; @@ -60,6 +61,7 @@ static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) env->regs[15] = tb->pc; } } +#endif /* CONFIG_TCG */ static bool arm_cpu_has_work(CPUState *cs) { @@ -2098,7 +2100,6 @@ static void arm_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *data cc->cpu_exec_interrupt = arm_cpu_exec_interrupt; //cc->dump_state = arm_cpu_dump_state; cc->set_pc = arm_cpu_set_pc; - cc->synchronize_from_tb = arm_cpu_synchronize_from_tb; #ifndef CONFIG_USER_ONLY cc->do_interrupt = arm_cpu_do_interrupt; cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug; @@ -2109,6 +2110,7 @@ static void arm_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *data #endif #ifdef CONFIG_TCG cc->tcg_ops.initialize = arm_translate_init; + cc->tcg_ops.synchronize_from_tb = arm_cpu_synchronize_from_tb; cc->tlb_fill = arm_cpu_tlb_fill; cc->debug_excp_handler = arm_debug_excp_handler; cc->debug_check_watchpoint = arm_debug_check_watchpoint; diff --git a/qemu/target/i386/cpu.c b/qemu/target/i386/cpu.c index dbbb04e0..77de4221 100644 --- a/qemu/target/i386/cpu.c +++ b/qemu/target/i386/cpu.c @@ -5800,7 +5800,7 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.eip = value; } -static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +static void x86_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { X86CPU *cpu = X86_CPU(cs->uc, cs); @@ -5879,7 +5879,7 @@ static void x86_cpu_common_class_init(struct uc_struct *uc, ObjectClass *oc, voi #endif cc->dump_state = x86_cpu_dump_state; cc->set_pc = x86_cpu_set_pc; - cc->synchronize_from_tb = x86_cpu_synchronize_from_tb; + cc->tcg_ops.synchronize_from_tb = x86_cpu_synchronize_from_tb; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifndef CONFIG_USER_ONLY diff --git a/qemu/target/mips/cpu.c b/qemu/target/mips/cpu.c index 6dcb5e2a..05cd6160 100644 --- a/qemu/target/mips/cpu.c +++ b/qemu/target/mips/cpu.c @@ -40,7 +40,8 @@ static void mips_cpu_set_pc(CPUState *cs, vaddr value) } } -static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +#ifdef CONFIG_TCG +static void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { MIPSCPU *cpu = MIPS_CPU(cs->uc, cs); CPUMIPSState *env = &cpu->env; @@ -49,6 +50,7 @@ static void mips_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) env->hflags &= ~MIPS_HFLAG_BMASK; env->hflags |= tb->flags & MIPS_HFLAG_BMASK; } +#endif /* CONFIG_TCG */ static bool mips_cpu_has_work(CPUState *cs) { @@ -174,7 +176,6 @@ static void mips_cpu_class_init(struct uc_struct *uc, ObjectClass *c, void *data cc->do_interrupt = mips_cpu_do_interrupt; cc->cpu_exec_interrupt = mips_cpu_exec_interrupt; cc->set_pc = mips_cpu_set_pc; - cc->synchronize_from_tb = mips_cpu_synchronize_from_tb; #ifndef CONFIG_USER_ONLY cc->do_transaction_failed = mips_cpu_do_transaction_failed; cc->do_unaligned_access = mips_cpu_do_unaligned_access; @@ -182,6 +183,7 @@ static void mips_cpu_class_init(struct uc_struct *uc, ObjectClass *c, void *data #endif #ifdef CONFIG_TCG cc->tcg_ops.initialize = mips_tcg_init; + cc->tcg_ops.synchronize_from_tb = mips_cpu_synchronize_from_tb; cc->tlb_fill = mips_cpu_tlb_fill; #endif } diff --git a/qemu/target/riscv/cpu.c b/qemu/target/riscv/cpu.c index 9ecc7cbe..e474893f 100644 --- a/qemu/target/riscv/cpu.c +++ b/qemu/target/riscv/cpu.c @@ -264,7 +264,7 @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value) env->pc = value; } -static void riscv_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +static void riscv_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { RISCVCPU *cpu = RISCV_CPU(cs->uc, cs); CPURISCVState *env = &cpu->env; @@ -361,7 +361,7 @@ static void riscv_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *da cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt; //cc->dump_state = riscv_cpu_dump_state; cc->set_pc = riscv_cpu_set_pc; - cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb; + cc->tcg_ops.synchronize_from_tb = riscv_cpu_synchronize_from_tb; //cc->gdb_read_register = riscv_cpu_gdb_read_register; //cc->gdb_write_register = riscv_cpu_gdb_write_register; //cc->gdb_num_core_regs = 65; diff --git a/qemu/target/sparc/cpu.c b/qemu/target/sparc/cpu.c index 63f608d9..7f93e9f2 100644 --- a/qemu/target/sparc/cpu.c +++ b/qemu/target/sparc/cpu.c @@ -730,7 +730,7 @@ static void sparc_cpu_set_pc(CPUState *cs, vaddr value) cpu->env.npc = value + 4; } -static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb) +static void sparc_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb) { SPARCCPU *cpu = SPARC_CPU(cs->uc, cs); @@ -847,7 +847,7 @@ static void sparc_cpu_class_init(struct uc_struct *uc, ObjectClass *oc, void *da cc->memory_rw_debug = sparc_cpu_memory_rw_debug; #endif cc->set_pc = sparc_cpu_set_pc; - cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb; + cc->tcg_ops.synchronize_from_tb = sparc_cpu_synchronize_from_tb; cc->tlb_fill = sparc_cpu_tlb_fill; #ifndef CONFIG_USER_ONLY cc->do_transaction_failed = sparc_cpu_do_transaction_failed;