diff --git a/qemu/qom/cpu.c b/qemu/qom/cpu.c index 98c09587..56a4e933 100644 --- a/qemu/qom/cpu.c +++ b/qemu/qom/cpu.c @@ -175,6 +175,10 @@ static void cpu_common_reset(CPUState *cpu) for (i = 0; i < TB_JMP_CACHE_SIZE; ++i) { atomic_set(&cpu->tb_jmp_cache[i], NULL); } + +#ifdef CONFIG_SOFTMMU + tlb_flush(cpu, 0); +#endif } static bool cpu_common_has_work(CPUState *cs) diff --git a/qemu/target-arm/cpu.c b/qemu/target-arm/cpu.c index db26c317..c3e5fd64 100644 --- a/qemu/target-arm/cpu.c +++ b/qemu/target-arm/cpu.c @@ -118,7 +118,7 @@ static void arm_cpu_reset(CPUState *s) acc->parent_reset(s); - memset(env, 0, offsetof(CPUARMState, features)); + memset(env, 0, offsetof(CPUARMState, end_reset_fields)); g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu); g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu); env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; @@ -231,7 +231,6 @@ static void arm_cpu_reset(CPUState *s) &env->vfp.fp_status); set_float_detect_tininess(float_tininess_before_rounding, &env->vfp.standard_fp_status); - tlb_flush(s, 1); hw_breakpoint_update_all(cpu); hw_watchpoint_update_all(cpu); diff --git a/qemu/target-arm/cpu.h b/qemu/target-arm/cpu.h index 56ceee79..56efa808 100644 --- a/qemu/target-arm/cpu.h +++ b/qemu/target-arm/cpu.h @@ -498,9 +498,12 @@ typedef struct CPUARMState { struct CPUBreakpoint *cpu_breakpoint[16]; struct CPUWatchpoint *cpu_watchpoint[16]; + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON - /* These fields after the common ones so they are preserved on reset. */ + /* Fields after CPU_COMMON are preserved across CPU reset. */ /* Internal CPU feature flags. */ uint64_t features; diff --git a/qemu/target-i386/cpu.c b/qemu/target-i386/cpu.c index 153efaec..d911e945 100644 --- a/qemu/target-i386/cpu.c +++ b/qemu/target-i386/cpu.c @@ -2846,8 +2846,6 @@ static void x86_cpu_reset(CPUState *s) memset(env, 0, offsetof(CPUX86State, end_reset_fields)); - tlb_flush(s, 1); - env->old_exception = -1; /* init to reset state */ diff --git a/qemu/target-i386/cpu.h b/qemu/target-i386/cpu.h index 661634aa..fc52dab6 100644 --- a/qemu/target-i386/cpu.h +++ b/qemu/target-i386/cpu.h @@ -1108,10 +1108,12 @@ typedef struct CPUX86State { uint8_t nmi_injected; uint8_t nmi_pending; + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON - /* Fields from here on are preserved across CPU reset. */ - struct {} end_reset_fields; + /* Fields after CPU_COMMON are preserved across CPU reset. */ /* processor features (e.g. for CPUID insn) */ /* Minimum level/xlevel/xlevel2, based on CPU model + features */ diff --git a/qemu/target-m68k/cpu.c b/qemu/target-m68k/cpu.c index 87ad8fdf..86a84a5f 100644 --- a/qemu/target-m68k/cpu.c +++ b/qemu/target-m68k/cpu.c @@ -52,7 +52,7 @@ static void m68k_cpu_reset(CPUState *s) mcc->parent_reset(s); - memset(env, 0, offsetof(CPUM68KState, features)); + memset(env, 0, offsetof(CPUM68KState, end_reset_fields)); #if !defined(CONFIG_USER_ONLY) env->sr = 0x2700; #endif @@ -61,7 +61,6 @@ static void m68k_cpu_reset(CPUState *s) cpu_m68k_set_ccr(env, 0); /* TODO: We should set PC from the interrupt vector. */ env->pc = 0; - tlb_flush(s, 1); } /* CPU models */ diff --git a/qemu/target-m68k/cpu.h b/qemu/target-m68k/cpu.h index cd382879..bbe2e33c 100644 --- a/qemu/target-m68k/cpu.h +++ b/qemu/target-m68k/cpu.h @@ -114,6 +114,9 @@ typedef struct CPUM68KState { uint32_t qregs[MAX_QREGS]; + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON /* Fields from here on are preserved across CPU reset. */ diff --git a/qemu/target-mips/cpu.c b/qemu/target-mips/cpu.c index 435b843b..d152dff4 100644 --- a/qemu/target-mips/cpu.c +++ b/qemu/target-mips/cpu.c @@ -99,8 +99,7 @@ static void mips_cpu_reset(CPUState *s) mcc->parent_reset(s); - memset(env, 0, offsetof(CPUMIPSState, mvp)); - tlb_flush(s, 1); + memset(env, 0, offsetof(CPUMIPSState, end_reset_fields)); cpu_state_reset(env); } diff --git a/qemu/target-mips/cpu.h b/qemu/target-mips/cpu.h index f3d6947e..c5e13ef5 100644 --- a/qemu/target-mips/cpu.h +++ b/qemu/target-mips/cpu.h @@ -603,6 +603,9 @@ struct CPUMIPSState { uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */ int insn_flags; /* Supported instruction set */ + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON /* Fields from here on are preserved across CPU reset. */ diff --git a/qemu/target-sparc/cpu.c b/qemu/target-sparc/cpu.c index ca811455..ac2eefa6 100644 --- a/qemu/target-sparc/cpu.c +++ b/qemu/target-sparc/cpu.c @@ -36,8 +36,7 @@ static void sparc_cpu_reset(CPUState *s) scc->parent_reset(s); - memset(env, 0, offsetof(CPUSPARCState, version)); - tlb_flush(s, 1); + memset(env, 0, offsetof(CPUSPARCState, end_reset_fields)); env->cwp = 0; #ifndef TARGET_SPARC64 env->wim = 1; diff --git a/qemu/target-sparc/cpu.h b/qemu/target-sparc/cpu.h index 7af3f600..88521fd0 100644 --- a/qemu/target-sparc/cpu.h +++ b/qemu/target-sparc/cpu.h @@ -413,6 +413,9 @@ struct CPUSPARCState { /* NOTE: we allow 8 more registers to handle wrapping */ target_ulong regbase[MAX_NWINDOWS * 16 + 8]; + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON /* Fields from here on are preserved across CPU reset. */