qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-ppc] [PATCH v3 1/3] qom/cpu: move tlb_flush to cpu_common_rese


From: David Gibson
Subject: Re: [Qemu-ppc] [PATCH v3 1/3] qom/cpu: move tlb_flush to cpu_common_reset
Date: Fri, 13 Jan 2017 10:33:16 +1100
User-agent: Mutt/1.7.1 (2016-10-04)

On Thu, Jan 12, 2017 at 03:47:29PM +0000, Alex Bennée wrote:
> 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 <address@hidden>
> Reviewed-by: Richard Henderson <address@hidden>

For ppc:

Reviewed-by: David Gibson <address@hidden>

> 
> ---
> v3:
>   - split tcg_enabled() into a separate patch
> ---
>  qom/cpu.c                   | 4 ++++
>  target/arm/cpu.c            | 5 ++---
>  target/arm/cpu.h            | 5 ++++-
>  target/cris/cpu.c           | 3 +--
>  target/cris/cpu.h           | 9 ++++++---
>  target/i386/cpu.c           | 2 --
>  target/i386/cpu.h           | 6 ++++--
>  target/lm32/cpu.c           | 3 +--
>  target/lm32/cpu.h           | 3 +++
>  target/m68k/cpu.c           | 3 +--
>  target/m68k/cpu.h           | 3 +++
>  target/microblaze/cpu.c     | 3 +--
>  target/microblaze/cpu.h     | 3 +++
>  target/mips/cpu.c           | 3 +--
>  target/mips/cpu.h           | 3 +++
>  target/moxie/cpu.c          | 4 +---
>  target/moxie/cpu.h          | 3 +++
>  target/openrisc/cpu.c       | 9 +--------
>  target/openrisc/cpu.h       | 3 +++
>  target/ppc/translate_init.c | 3 ---
>  target/s390x/cpu.c          | 7 ++-----
>  target/s390x/cpu.h          | 5 +++--
>  target/sh4/cpu.c            | 3 +--
>  target/sh4/cpu.h            | 3 +++
>  target/sparc/cpu.c          | 3 +--
>  target/sparc/cpu.h          | 3 +++
>  target/tilegx/cpu.c         | 3 +--
>  target/tilegx/cpu.h         | 3 +++
>  target/tricore/cpu.c        | 2 --
>  29 files changed, 62 insertions(+), 50 deletions(-)
> 
> diff --git a/qom/cpu.c b/qom/cpu.c
> index 03d9190f8c..cc51de2a8c 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 f5cb30af6c..91046111d9 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 ab119e62ab..7bd16eec18 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 2e9ab9700e..5f766f09d6 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 43d5f9d1da..920e1c33ba 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 b0640f1e38..b76e1d8cb9 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 a7f2f6099d..8587efa8b0 100644
> --- a/target/i386/cpu.h
> +++ b/target/i386/cpu.h
> @@ -1122,10 +1122,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 8d939a7779..2b8c36b6d0 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 d8a3515244..1d972cb26b 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 ba17480098..fa10b6e4cd 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 0b4ed7b8a6..aeac95daa3 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 389c7b691e..3d58869716 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 beb75ffd26..bf6963bcb7 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 65ca607f88..1bb66b7a5a 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 5182dc74ff..3146a6017d 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 b0be4a7551..927b1a1e44 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 3e880facf4..8991aaef9a 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 698e87bb25..422139d29f 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 aaf153579a..508ef568b4 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 626e03186c..4ff987226e 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 0a39d31237..066dcd17df 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 fd36a25cf5..058ddad83a 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 a38f6a6ded..9a481c35dc 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 478ab55868..cad8989f7e 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 4e07b92fbd..d6583f1c2a 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 5fb0ed1aad..601c018a05 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 454793f94a..d90e38e88c 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 1735427233..f32be49f65 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 785b76bd3a..08f50e2ba7 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);
>  }
>  

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]