diff --git a/qom/cpu.c b/qom/cpu.c index 03d9190f8ce8eb60ed81a1e748869f9e82164955..cc51de2a8c8da15a8ee1727bf6d13bbcde66f4c4 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -273,6 +273,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/target/arm/cpu.c b/target/arm/cpu.c index f5cb30af6c1a08041efa091150bd5ea7f48a7ed9..91046111d9e6094b2ad9c9db91329d272114b7cc 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -122,7 +122,8 @@ 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); @@ -226,8 +227,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); - #ifndef CONFIG_USER_ONLY if (kvm_enabled()) { kvm_arm_reset_vcpu(cpu); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index ab119e62ab0f963bcb1dd73d9e9ca3dac23fc4c6..7bd16eec18d86d2c976aa35f853bf751e33035aa 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -491,9 +491,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/target/cris/cpu.c b/target/cris/cpu.c index 2e9ab9700e8b377ac799868d20769c0e8b520c8e..5f766f09d62b9d62ea186a5cce1c88db1c035dbc 100644 --- a/target/cris/cpu.c +++ b/target/cris/cpu.c @@ -52,9 +52,8 @@ static void cris_cpu_reset(CPUState *s) ccc->parent_reset(s); vr = env->pregs[PR_VR]; - memset(env, 0, offsetof(CPUCRISState, load_info)); + memset(env, 0, offsetof(CPUCRISState, end_reset_fields)); env->pregs[PR_VR] = vr; - tlb_flush(s, 1); #if defined(CONFIG_USER_ONLY) /* start in user mode with interrupts enabled. */ diff --git a/target/cris/cpu.h b/target/cris/cpu.h index 43d5f9d1da6136097e770209ecf7a367c991f092..920e1c33ba3137d91dae65d5124f72a1aeeca4d5 100644 --- a/target/cris/cpu.h +++ b/target/cris/cpu.h @@ -167,10 +167,13 @@ typedef struct CPUCRISState { */ TLBSet tlbsets[2][4][16]; - CPU_COMMON + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; - /* Members from load_info on are preserved across resets. */ - void *load_info; + CPU_COMMON + + /* Members from load_info on are preserved across resets. */ + void *load_info; } CPUCRISState; /** diff --git a/target/i386/cpu.c b/target/i386/cpu.c index b0640f1e38d85a173a9fc34b40ac695fd4f97b47..b76e1d8cb9685d25388c45b87cb74168034be981 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2819,8 +2819,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/target/i386/cpu.h b/target/i386/cpu.h index a04e46b166f91da73d062cea4f73a5b4465bb71f..6c1902b36ed0280adc3847600d65b045bf5a03c5 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1123,10 +1123,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/target/lm32/cpu.c b/target/lm32/cpu.c index 8d939a7779f21b747376668351991d722729c55c..2b8c36b6d06ee757eedd478ff9b0363609c41ed2 100644 --- a/target/lm32/cpu.c +++ b/target/lm32/cpu.c @@ -128,10 +128,9 @@ static void lm32_cpu_reset(CPUState *s) lcc->parent_reset(s); /* reset cpu state */ - memset(env, 0, offsetof(CPULM32State, eba)); + memset(env, 0, offsetof(CPULM32State, end_reset_fields)); lm32_cpu_init_cfg_reg(cpu); - tlb_flush(s, 1); } static void lm32_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h index d8a3515244ea00971d3beba1c2473bbd6928dd25..1d972cb26bd579531621fc915235f53d73743cb2 100644 --- a/target/lm32/cpu.h +++ b/target/lm32/cpu.h @@ -165,6 +165,9 @@ struct CPULM32State { struct CPUBreakpoint *cpu_breakpoint[4]; struct CPUWatchpoint *cpu_watchpoint[4]; + /* 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/target/m68k/cpu.c b/target/m68k/cpu.c index ba174800982d844f46ce5371cd58957d4ed15145..fa10b6e4cd59b622d1ab5b98697de7688edb37fd 100644 --- a/target/m68k/cpu.c +++ b/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); } static void m68k_cpu_disas_set_info(CPUState *s, disassemble_info *info) diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 0b4ed7b8a697c4ede6995c4d6b09882cb68ff08c..aeac95daa327bb4fd74f9fe378a656fa81ac4398 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -111,6 +111,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/target/microblaze/cpu.c b/target/microblaze/cpu.c index 389c7b691ece8c2e3a420185e608d6c0b05bfd4e..3d588697164c92cf3b2ca9398c0f1b9cfd8e7a9e 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c @@ -103,9 +103,8 @@ static void mb_cpu_reset(CPUState *s) mcc->parent_reset(s); - memset(env, 0, offsetof(CPUMBState, pvr)); + memset(env, 0, offsetof(CPUMBState, end_reset_fields)); env->res_addr = RES_ADDR_NONE; - tlb_flush(s, 1); /* Disable stack protector. */ env->shr = ~0; diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index beb75ffd26d5137f56a1f01f6c4d5021104a3cc8..bf6963bcb719f55a6e1b92d434cbb3c9dbaeb68a 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -267,6 +267,9 @@ struct CPUMBState { struct microblaze_mmu mmu; #endif + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON /* These fields are preserved on reset. */ diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 65ca607f88c0774886174db38fd1c4997f0c2f30..1bb66b7a5a06de169380e0f2d8492e39c6110cb4 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -100,8 +100,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/target/mips/cpu.h b/target/mips/cpu.h index 5182dc74ffa3c22bbe03900b3478b1cf0d8f293a..3146a6017d8fcfcc07a70b43e81ce80de32a7715 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -607,6 +607,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/target/moxie/cpu.c b/target/moxie/cpu.c index b0be4a7551c1ff50a70db3249384f563b3b0a732..927b1a1e44cc37f84a69ce6e4a8c0d16e66a1f52 100644 --- a/target/moxie/cpu.c +++ b/target/moxie/cpu.c @@ -45,10 +45,8 @@ static void moxie_cpu_reset(CPUState *s) mcc->parent_reset(s); - memset(env, 0, sizeof(CPUMoxieState)); + memset(env, 0, offsetof(CPUMoxieState, end_reset_fields)); env->pc = 0x1000; - - tlb_flush(s, 1); } static void moxie_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h index 3e880facf4825ba794449107025159f43cfd755e..8991aaef9a8dac56992771eb12af2301d0ac8bc8 100644 --- a/target/moxie/cpu.h +++ b/target/moxie/cpu.h @@ -56,6 +56,9 @@ typedef struct CPUMoxieState { void *irq[8]; + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON } CPUMoxieState; diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index 698e87bb2596355ebbfee138e9fe3c3c9c7cd94a..422139d29f1d58bfef99255711631ddfc79bc546 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c @@ -44,14 +44,7 @@ static void openrisc_cpu_reset(CPUState *s) occ->parent_reset(s); -#ifndef CONFIG_USER_ONLY - memset(&cpu->env, 0, offsetof(CPUOpenRISCState, tlb)); -#else - memset(&cpu->env, 0, offsetof(CPUOpenRISCState, irq)); -#endif - - tlb_flush(s, 1); - /*tb_flush(&cpu->env); FIXME: Do we need it? */ + memset(&cpu->env, 0, offsetof(CPUOpenRISCState, end_reset_fields)); cpu->env.pc = 0x100; cpu->env.sr = SR_FO | SR_SM; diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index aaf153579a9acd67e5b2cdf2aff3db6dee5a1670..508ef568b4be11ddf1760c6d0526d63cdcf2aad7 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -300,6 +300,9 @@ typedef struct CPUOpenRISCState { in solt so far. */ uint32_t btaken; /* the SR_F bit */ + /* 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/target/ppc/translate_init.c b/target/ppc/translate_init.c index 626e03186cdacd71c5b19ccc626dd8476df5897b..4ff987226e1885cdd034f14f2200ee8a50ba7a48 100644 --- a/target/ppc/translate_init.c +++ b/target/ppc/translate_init.c @@ -10415,9 +10415,6 @@ static void ppc_cpu_reset(CPUState *s) } env->spr[i] = spr->default_value; } - - /* Flush all TLBs */ - tlb_flush(s, 1); } #ifndef CONFIG_USER_ONLY diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index 0a39d312379bdd2350bfbbf4dd1521c4f4623ce4..066dcd17df964b776865912416f5e6cedba3ef34 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -82,7 +82,6 @@ static void s390_cpu_reset(CPUState *s) scc->parent_reset(s); cpu->env.sigp_order = 0; s390_cpu_set_state(CPU_STATE_STOPPED, cpu); - tlb_flush(s, 1); } /* S390CPUClass::initial_reset() */ @@ -94,7 +93,7 @@ static void s390_cpu_initial_reset(CPUState *s) s390_cpu_reset(s); /* initial reset does not touch regs,fregs and aregs */ - memset(&env->fpc, 0, offsetof(CPUS390XState, cpu_num) - + memset(&env->fpc, 0, offsetof(CPUS390XState, end_reset_fields) - offsetof(CPUS390XState, fpc)); /* architectured initial values for CR 0 and 14 */ @@ -118,7 +117,6 @@ static void s390_cpu_initial_reset(CPUState *s) if (kvm_enabled()) { kvm_s390_reset_vcpu(cpu); } - tlb_flush(s, 1); } /* CPUClass:reset() */ @@ -133,7 +131,7 @@ static void s390_cpu_full_reset(CPUState *s) cpu->env.sigp_order = 0; s390_cpu_set_state(CPU_STATE_STOPPED, cpu); - memset(env, 0, offsetof(CPUS390XState, cpu_num)); + memset(env, 0, offsetof(CPUS390XState, end_reset_fields)); /* architectured initial values for CR 0 and 14 */ env->cregs[0] = CR0_RESET; @@ -156,7 +154,6 @@ static void s390_cpu_full_reset(CPUState *s) if (kvm_enabled()) { kvm_s390_reset_vcpu(cpu); } - tlb_flush(s, 1); } #if !defined(CONFIG_USER_ONLY) diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index fd36a25cf5e06d37e91976151ff60d047d0a9c41..058ddad83a16dba74b7783ff7b7df551994be0d6 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -139,9 +139,10 @@ typedef struct CPUS390XState { uint8_t riccb[64]; - CPU_COMMON + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; - /* reset does memset(0) up to here */ + CPU_COMMON uint32_t cpu_num; uint32_t machine_type; diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index a38f6a6ded0057213d22e32439fc0efd070c8dff..9a481c35dccb6319f142898db87797977367f782 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c @@ -56,8 +56,7 @@ static void superh_cpu_reset(CPUState *s) scc->parent_reset(s); - memset(env, 0, offsetof(CPUSH4State, id)); - tlb_flush(s, 1); + memset(env, 0, offsetof(CPUSH4State, end_reset_fields)); env->pc = 0xA0000000; #if defined(CONFIG_USER_ONLY) diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 478ab558681b0b22a958158756e875ab427ffd89..cad8989f7e16077af3a72ec8ec90a57089d49def 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -175,6 +175,9 @@ typedef struct CPUSH4State { uint32_t ldst; + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON /* Fields from here on are preserved over CPU reset. */ diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index 4e07b92fbd70cc16480c1abb2c37b0c928e976b7..d6583f1c2a1680402d06317a06d98ed0bc733065 100644 --- a/target/sparc/cpu.c +++ b/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/target/sparc/cpu.h b/target/sparc/cpu.h index 5fb0ed1aad068b603cd91018391283ff363de1e4..601c018a054a3b684ff98307095fe789c6ef7ac8 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -419,6 +419,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. */ diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c index 454793f94a1348b5a2dfe3b4395dba7cb1b8ae8c..d90e38e88cdbac765ddc94155713fa9dec71f421 100644 --- a/target/tilegx/cpu.c +++ b/target/tilegx/cpu.c @@ -84,8 +84,7 @@ static void tilegx_cpu_reset(CPUState *s) tcc->parent_reset(s); - memset(env, 0, sizeof(CPUTLGState)); - tlb_flush(s, 1); + memset(env, 0, offsetof(CPUTLGState, end_reset_fields)); } static void tilegx_cpu_realizefn(DeviceState *dev, Error **errp) diff --git a/target/tilegx/cpu.h b/target/tilegx/cpu.h index 17354272337da8a0694404876ec1b7d11027d5c0..f32be49f6544b14ab3e78af6f2cb970c646d5807 100644 --- a/target/tilegx/cpu.h +++ b/target/tilegx/cpu.h @@ -97,6 +97,9 @@ typedef struct CPUTLGState { uint32_t sigcode; /* Signal code */ #endif + /* Fields up to this point are cleared by a CPU reset */ + struct {} end_reset_fields; + CPU_COMMON } CPUTLGState; diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c index 785b76bd3aa60d1cd5e28ff59a7565a3fda5d0b0..08f50e2ba7f2873148c0f7b021131a99dee4f389 100644 --- a/target/tricore/cpu.c +++ b/target/tricore/cpu.c @@ -53,8 +53,6 @@ static void tricore_cpu_reset(CPUState *s) tcc->parent_reset(s); - tlb_flush(s, 1); - cpu_state_reset(env); }