qom/cpu: move tlb_flush to cpu_common_reset
authorAlex Bennée <alex.bennee@linaro.org>
Mon, 14 Nov 2016 14:19:17 +0000 (14:19 +0000)
committerAlex Bennée <alex.bennee@linaro.org>
Fri, 13 Jan 2017 14:24:31 +0000 (14:24 +0000)
It is a common thing amongst the various cpu reset functions want to
flush the SoftMMU's TLB entries. This is done either by calling
tlb_flush directly or by way of a general memset of the CPU
structure (sometimes both).

This moves the tlb_flush call to the common reset function and
additionally ensures it is only done for the CONFIG_SOFTMMU case and
when tcg is enabled.

In some target cases we add an empty end_of_reset_fields structure to the
target vCPU structure so have a clear end point for any memset which
is resetting value in the structure before CPU_COMMON (where the TLB
structures are).

While this is a nice clean-up in general it is also a precursor for
changes coming to cputlb for MTTCG where the clearing of entries
can't be done arbitrarily across vCPUs. Currently the cpu_reset
function is usually called from the context of another vCPU as the
architectural power up sequence is run. By using the cputlb API
functions we can ensure the right behaviour in the future.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
29 files changed:
qom/cpu.c
target/arm/cpu.c
target/arm/cpu.h
target/cris/cpu.c
target/cris/cpu.h
target/i386/cpu.c
target/i386/cpu.h
target/lm32/cpu.c
target/lm32/cpu.h
target/m68k/cpu.c
target/m68k/cpu.h
target/microblaze/cpu.c
target/microblaze/cpu.h
target/mips/cpu.c
target/mips/cpu.h
target/moxie/cpu.c
target/moxie/cpu.h
target/openrisc/cpu.c
target/openrisc/cpu.h
target/ppc/translate_init.c
target/s390x/cpu.c
target/s390x/cpu.h
target/sh4/cpu.c
target/sh4/cpu.h
target/sparc/cpu.c
target/sparc/cpu.h
target/tilegx/cpu.c
target/tilegx/cpu.h
target/tricore/cpu.c

index 03d9190f8ce8eb60ed81a1e748869f9e82164955..cc51de2a8c8da15a8ee1727bf6d13bbcde66f4c4 100644 (file)
--- 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)
index f5cb30af6c1a08041efa091150bd5ea7f48a7ed9..91046111d9e6094b2ad9c9db91329d272114b7cc 100644 (file)
@@ -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);
index ab119e62ab0f963bcb1dd73d9e9ca3dac23fc4c6..7bd16eec18d86d2c976aa35f853bf751e33035aa 100644 (file)
@@ -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;
index 2e9ab9700e8b377ac799868d20769c0e8b520c8e..5f766f09d62b9d62ea186a5cce1c88db1c035dbc 100644 (file)
@@ -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.  */
index 43d5f9d1da6136097e770209ecf7a367c991f092..920e1c33ba3137d91dae65d5124f72a1aeeca4d5 100644 (file)
@@ -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;
 
 /**
index b0640f1e38d85a173a9fc34b40ac695fd4f97b47..b76e1d8cb9685d25388c45b87cb74168034be981 100644 (file)
@@ -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 */
index a04e46b166f91da73d062cea4f73a5b4465bb71f..6c1902b36ed0280adc3847600d65b045bf5a03c5 100644 (file)
@@ -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 */
index 8d939a7779f21b747376668351991d722729c55c..2b8c36b6d06ee757eedd478ff9b0363609c41ed2 100644 (file)
@@ -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)
index d8a3515244ea00971d3beba1c2473bbd6928dd25..1d972cb26bd579531621fc915235f53d73743cb2 100644 (file)
@@ -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. */
index ba174800982d844f46ce5371cd58957d4ed15145..fa10b6e4cd59b622d1ab5b98697de7688edb37fd 100644 (file)
@@ -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)
index 0b4ed7b8a697c4ede6995c4d6b09882cb68ff08c..aeac95daa327bb4fd74f9fe378a656fa81ac4398 100644 (file)
@@ -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. */
index 389c7b691ece8c2e3a420185e608d6c0b05bfd4e..3d588697164c92cf3b2ca9398c0f1b9cfd8e7a9e 100644 (file)
@@ -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;
index beb75ffd26d5137f56a1f01f6c4d5021104a3cc8..bf6963bcb719f55a6e1b92d434cbb3c9dbaeb68a 100644 (file)
@@ -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.  */
index 65ca607f88c0774886174db38fd1c4997f0c2f30..1bb66b7a5a06de169380e0f2d8492e39c6110cb4 100644 (file)
@@ -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);
 
index 5182dc74ffa3c22bbe03900b3478b1cf0d8f293a..3146a6017d8fcfcc07a70b43e81ce80de32a7715 100644 (file)
@@ -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. */
index b0be4a7551c1ff50a70db3249384f563b3b0a732..927b1a1e44cc37f84a69ce6e4a8c0d16e66a1f52 100644 (file)
@@ -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)
index 3e880facf4825ba794449107025159f43cfd755e..8991aaef9a8dac56992771eb12af2301d0ac8bc8 100644 (file)
@@ -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;
index 698e87bb2596355ebbfee138e9fe3c3c9c7cd94a..422139d29f1d58bfef99255711631ddfc79bc546 100644 (file)
@@ -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;
index aaf153579a9acd67e5b2cdf2aff3db6dee5a1670..508ef568b4be11ddf1760c6d0526d63cdcf2aad7 100644 (file)
@@ -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. */
index 626e03186cdacd71c5b19ccc626dd8476df5897b..4ff987226e1885cdd034f14f2200ee8a50ba7a48 100644 (file)
@@ -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
index 0a39d312379bdd2350bfbbf4dd1521c4f4623ce4..066dcd17df964b776865912416f5e6cedba3ef34 100644 (file)
@@ -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)
index fd36a25cf5e06d37e91976151ff60d047d0a9c41..058ddad83a16dba74b7783ff7b7df551994be0d6 100644 (file)
@@ -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;
index a38f6a6ded0057213d22e32439fc0efd070c8dff..9a481c35dccb6319f142898db87797977367f782 100644 (file)
@@ -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)
index 478ab558681b0b22a958158756e875ab427ffd89..cad8989f7e16077af3a72ec8ec90a57089d49def 100644 (file)
@@ -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. */
index 4e07b92fbd70cc16480c1abb2c37b0c928e976b7..d6583f1c2a1680402d06317a06d98ed0bc733065 100644 (file)
@@ -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;
index 5fb0ed1aad068b603cd91018391283ff363de1e4..601c018a054a3b684ff98307095fe789c6ef7ac8 100644 (file)
@@ -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. */
index 454793f94a1348b5a2dfe3b4395dba7cb1b8ae8c..d90e38e88cdbac765ddc94155713fa9dec71f421 100644 (file)
@@ -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)
index 17354272337da8a0694404876ec1b7d11027d5c0..f32be49f6544b14ab3e78af6f2cb970c646d5807 100644 (file)
@@ -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;
 
index 785b76bd3aa60d1cd5e28ff59a7565a3fda5d0b0..08f50e2ba7f2873148c0f7b021131a99dee4f389 100644 (file)
@@ -53,8 +53,6 @@ static void tricore_cpu_reset(CPUState *s)
 
     tcc->parent_reset(s);
 
-    tlb_flush(s, 1);
-
     cpu_state_reset(env);
 }