Re: [Qemu-devel] [Qemu-ppc] [PULL 02/12] ppc: Use split I/D mmu modes to avoid flushes on interrupts

2016-06-01 Thread Mark Cave-Ayland
On 02/06/16 04:15, David Gibson wrote:

> On Wed, Jun 01, 2016 at 08:33:30PM +0100, Mark Cave-Ayland wrote:
>> On 31/05/16 01:41, David Gibson wrote:
>>
>>> From: Benjamin Herrenschmidt 
>>>
>>> We rework the way the MMU indices are calculated, providing separate
>>> indices for I and D side based on MSR:IR and MSR:DR respectively,
>>> and thus no longer need to flush the TLB on context changes. This also
>>> adds correct support for HV as a separate address space.
>>>
>>> Signed-off-by: Benjamin Herrenschmidt 
>>> Signed-off-by: David Gibson 
>>> ---
>>>  target-ppc/cpu.h | 11 +++---
>>>  target-ppc/excp_helper.c | 11 --
>>>  target-ppc/helper_regs.h | 54 
>>> +---
>>>  target-ppc/machine.c |  5 -
>>>  target-ppc/translate.c   |  7 ---
>>>  5 files changed, 63 insertions(+), 25 deletions(-)
>>>
>>> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
>>> index 02e71ea..2c8c8c0 100644
>>> --- a/target-ppc/cpu.h
>>> +++ b/target-ppc/cpu.h
>>> @@ -359,6 +359,8 @@ struct ppc_slb_t {
>>>  #define MSR_EP   6  /* Exception prefix on 601 
>>>   */
>>>  #define MSR_IR   5  /* Instruction relocate
>>>   */
>>>  #define MSR_DR   4  /* Data relocate   
>>>   */
>>> +#define MSR_IS   5  /* Instruction address space (BookE)   
>>>   */
>>> +#define MSR_DS   4  /* Data address space (BookE)  
>>>   */
>>>  #define MSR_PE   3  /* Protection enable on 403
>>>   */
>>>  #define MSR_PX   2  /* Protection exclusive on 403  x  
>>>   */
>>>  #define MSR_PMM  2  /* Performance monitor mark on POWERx  
>>>   */
>>> @@ -410,6 +412,8 @@ struct ppc_slb_t {
>>>  #define msr_ep   ((env->msr >> MSR_EP)   & 1)
>>>  #define msr_ir   ((env->msr >> MSR_IR)   & 1)
>>>  #define msr_dr   ((env->msr >> MSR_DR)   & 1)
>>> +#define msr_is   ((env->msr >> MSR_IS)   & 1)
>>> +#define msr_ds   ((env->msr >> MSR_DS)   & 1)
>>>  #define msr_pe   ((env->msr >> MSR_PE)   & 1)
>>>  #define msr_px   ((env->msr >> MSR_PX)   & 1)
>>>  #define msr_pmm  ((env->msr >> MSR_PMM)  & 1)
>>> @@ -889,7 +893,7 @@ struct ppc_segment_page_sizes {
>>>  
>>>  
>>> /*/
>>>  /* The whole PowerPC CPU context */
>>> -#define NB_MMU_MODES 3
>>> +#define NB_MMU_MODES8
>>>  
>>>  #define PPC_CPU_OPCODES_LEN  0x40
>>>  #define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
>>> @@ -1053,7 +1057,8 @@ struct CPUPPCState {
>>>  /* Those resources are used only in QEMU core */
>>>  target_ulong hflags;  /* hflags is a MSR & HFLAGS_MASK */
>>>  target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
>>> -int mmu_idx; /* precomputed MMU index to speed up mem accesses 
>>> */
>>> +int immu_idx; /* precomputed MMU index to speed up insn access 
>>> */
>>> +int dmmu_idx; /* precomputed MMU index to speed up data 
>>> accesses */
>>>  
>>>  /* Power management */
>>>  int (*check_pow)(CPUPPCState *env);
>>> @@ -1245,7 +1250,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, 
>>> uint32_t val);
>>>  #define MMU_USER_IDX 0
>>>  static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
>>>  {
>>> -return env->mmu_idx;
>>> +return ifetch ? env->immu_idx : env->dmmu_idx;
>>>  }
>>>  
>>>  #include "exec/cpu-all.h"
>>> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
>>> index 288903e..ba3caec 100644
>>> --- a/target-ppc/excp_helper.c
>>> +++ b/target-ppc/excp_helper.c
>>> @@ -646,9 +646,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
>>> excp_model, int excp)
>>>  
>>>  if (env->spr[SPR_LPCR] & LPCR_AIL) {
>>>  new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
>>> -} else if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
>>> -/* If we disactivated any translation, flush TLBs */
>>> -tlb_flush(cs, 1);
>>>  }
>>>  
>>>  #ifdef TARGET_PPC64
>>> @@ -721,14 +718,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
>>> excp_model, int excp)
>>>  /* Reset exception state */
>>>  cs->exception_index = POWERPC_EXCP_NONE;
>>>  env->error_code = 0;
>>> -
>>> -if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
>>> -(env->mmu_model == POWERPC_MMU_BOOKE206)) {
>>> -/* XXX: The BookE changes address space when switching modes,
>>> -we should probably implement that as different MMU indexes,
>>> -but for the moment we do it the slow way and flush all.  */
>>> -tlb_flush(cs, 1);
>>> -}
>>>  }
>>>  
>>>  void ppc_cpu_do_interrupt(CPUState *cs)
>>> diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
>>> index 271fddf..f7edd5b 100644
>>> --- a/target-ppc/helper_regs.h
>>> +++ b/target-ppc/helper_regs.h
>>> @@ -41,11 +41,50 @@ static inlin

Re: [Qemu-devel] [Qemu-ppc] [PULL 02/12] ppc: Use split I/D mmu modes to avoid flushes on interrupts

2016-06-01 Thread David Gibson
On Wed, Jun 01, 2016 at 08:33:30PM +0100, Mark Cave-Ayland wrote:
> On 31/05/16 01:41, David Gibson wrote:
> 
> > From: Benjamin Herrenschmidt 
> > 
> > We rework the way the MMU indices are calculated, providing separate
> > indices for I and D side based on MSR:IR and MSR:DR respectively,
> > and thus no longer need to flush the TLB on context changes. This also
> > adds correct support for HV as a separate address space.
> > 
> > Signed-off-by: Benjamin Herrenschmidt 
> > Signed-off-by: David Gibson 
> > ---
> >  target-ppc/cpu.h | 11 +++---
> >  target-ppc/excp_helper.c | 11 --
> >  target-ppc/helper_regs.h | 54 
> > +---
> >  target-ppc/machine.c |  5 -
> >  target-ppc/translate.c   |  7 ---
> >  5 files changed, 63 insertions(+), 25 deletions(-)
> > 
> > diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> > index 02e71ea..2c8c8c0 100644
> > --- a/target-ppc/cpu.h
> > +++ b/target-ppc/cpu.h
> > @@ -359,6 +359,8 @@ struct ppc_slb_t {
> >  #define MSR_EP   6  /* Exception prefix on 601 
> >   */
> >  #define MSR_IR   5  /* Instruction relocate
> >   */
> >  #define MSR_DR   4  /* Data relocate   
> >   */
> > +#define MSR_IS   5  /* Instruction address space (BookE)   
> >   */
> > +#define MSR_DS   4  /* Data address space (BookE)  
> >   */
> >  #define MSR_PE   3  /* Protection enable on 403
> >   */
> >  #define MSR_PX   2  /* Protection exclusive on 403  x  
> >   */
> >  #define MSR_PMM  2  /* Performance monitor mark on POWERx  
> >   */
> > @@ -410,6 +412,8 @@ struct ppc_slb_t {
> >  #define msr_ep   ((env->msr >> MSR_EP)   & 1)
> >  #define msr_ir   ((env->msr >> MSR_IR)   & 1)
> >  #define msr_dr   ((env->msr >> MSR_DR)   & 1)
> > +#define msr_is   ((env->msr >> MSR_IS)   & 1)
> > +#define msr_ds   ((env->msr >> MSR_DS)   & 1)
> >  #define msr_pe   ((env->msr >> MSR_PE)   & 1)
> >  #define msr_px   ((env->msr >> MSR_PX)   & 1)
> >  #define msr_pmm  ((env->msr >> MSR_PMM)  & 1)
> > @@ -889,7 +893,7 @@ struct ppc_segment_page_sizes {
> >  
> >  
> > /*/
> >  /* The whole PowerPC CPU context */
> > -#define NB_MMU_MODES 3
> > +#define NB_MMU_MODES8
> >  
> >  #define PPC_CPU_OPCODES_LEN  0x40
> >  #define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
> > @@ -1053,7 +1057,8 @@ struct CPUPPCState {
> >  /* Those resources are used only in QEMU core */
> >  target_ulong hflags;  /* hflags is a MSR & HFLAGS_MASK */
> >  target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
> > -int mmu_idx; /* precomputed MMU index to speed up mem accesses 
> > */
> > +int immu_idx; /* precomputed MMU index to speed up insn access 
> > */
> > +int dmmu_idx; /* precomputed MMU index to speed up data 
> > accesses */
> >  
> >  /* Power management */
> >  int (*check_pow)(CPUPPCState *env);
> > @@ -1245,7 +1250,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, 
> > uint32_t val);
> >  #define MMU_USER_IDX 0
> >  static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
> >  {
> > -return env->mmu_idx;
> > +return ifetch ? env->immu_idx : env->dmmu_idx;
> >  }
> >  
> >  #include "exec/cpu-all.h"
> > diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> > index 288903e..ba3caec 100644
> > --- a/target-ppc/excp_helper.c
> > +++ b/target-ppc/excp_helper.c
> > @@ -646,9 +646,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> > excp_model, int excp)
> >  
> >  if (env->spr[SPR_LPCR] & LPCR_AIL) {
> >  new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> > -} else if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
> > -/* If we disactivated any translation, flush TLBs */
> > -tlb_flush(cs, 1);
> >  }
> >  
> >  #ifdef TARGET_PPC64
> > @@ -721,14 +718,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> > excp_model, int excp)
> >  /* Reset exception state */
> >  cs->exception_index = POWERPC_EXCP_NONE;
> >  env->error_code = 0;
> > -
> > -if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> > -(env->mmu_model == POWERPC_MMU_BOOKE206)) {
> > -/* XXX: The BookE changes address space when switching modes,
> > -we should probably implement that as different MMU indexes,
> > -but for the moment we do it the slow way and flush all.  */
> > -tlb_flush(cs, 1);
> > -}
> >  }
> >  
> >  void ppc_cpu_do_interrupt(CPUState *cs)
> > diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
> > index 271fddf..f7edd5b 100644
> > --- a/target-ppc/helper_regs.h
> > +++ b/target-ppc/helper_regs.h
> > @@ -41,11 +41,50 @@ static inline void hreg_swap_gpr_tgpr(CPUPPCState *e

Re: [Qemu-devel] [Qemu-ppc] [PULL 02/12] ppc: Use split I/D mmu modes to avoid flushes on interrupts

2016-06-01 Thread Mark Cave-Ayland
On 31/05/16 01:41, David Gibson wrote:

> From: Benjamin Herrenschmidt 
> 
> We rework the way the MMU indices are calculated, providing separate
> indices for I and D side based on MSR:IR and MSR:DR respectively,
> and thus no longer need to flush the TLB on context changes. This also
> adds correct support for HV as a separate address space.
> 
> Signed-off-by: Benjamin Herrenschmidt 
> Signed-off-by: David Gibson 
> ---
>  target-ppc/cpu.h | 11 +++---
>  target-ppc/excp_helper.c | 11 --
>  target-ppc/helper_regs.h | 54 
> +---
>  target-ppc/machine.c |  5 -
>  target-ppc/translate.c   |  7 ---
>  5 files changed, 63 insertions(+), 25 deletions(-)
> 
> diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
> index 02e71ea..2c8c8c0 100644
> --- a/target-ppc/cpu.h
> +++ b/target-ppc/cpu.h
> @@ -359,6 +359,8 @@ struct ppc_slb_t {
>  #define MSR_EP   6  /* Exception prefix on 601   
> */
>  #define MSR_IR   5  /* Instruction relocate  
> */
>  #define MSR_DR   4  /* Data relocate 
> */
> +#define MSR_IS   5  /* Instruction address space (BookE) 
> */
> +#define MSR_DS   4  /* Data address space (BookE)
> */
>  #define MSR_PE   3  /* Protection enable on 403  
> */
>  #define MSR_PX   2  /* Protection exclusive on 403  x
> */
>  #define MSR_PMM  2  /* Performance monitor mark on POWERx
> */
> @@ -410,6 +412,8 @@ struct ppc_slb_t {
>  #define msr_ep   ((env->msr >> MSR_EP)   & 1)
>  #define msr_ir   ((env->msr >> MSR_IR)   & 1)
>  #define msr_dr   ((env->msr >> MSR_DR)   & 1)
> +#define msr_is   ((env->msr >> MSR_IS)   & 1)
> +#define msr_ds   ((env->msr >> MSR_DS)   & 1)
>  #define msr_pe   ((env->msr >> MSR_PE)   & 1)
>  #define msr_px   ((env->msr >> MSR_PX)   & 1)
>  #define msr_pmm  ((env->msr >> MSR_PMM)  & 1)
> @@ -889,7 +893,7 @@ struct ppc_segment_page_sizes {
>  
>  
> /*/
>  /* The whole PowerPC CPU context */
> -#define NB_MMU_MODES 3
> +#define NB_MMU_MODES8
>  
>  #define PPC_CPU_OPCODES_LEN  0x40
>  #define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
> @@ -1053,7 +1057,8 @@ struct CPUPPCState {
>  /* Those resources are used only in QEMU core */
>  target_ulong hflags;  /* hflags is a MSR & HFLAGS_MASK */
>  target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
> -int mmu_idx; /* precomputed MMU index to speed up mem accesses */
> +int immu_idx; /* precomputed MMU index to speed up insn access */
> +int dmmu_idx; /* precomputed MMU index to speed up data accesses 
> */
>  
>  /* Power management */
>  int (*check_pow)(CPUPPCState *env);
> @@ -1245,7 +1250,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, 
> uint32_t val);
>  #define MMU_USER_IDX 0
>  static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
>  {
> -return env->mmu_idx;
> +return ifetch ? env->immu_idx : env->dmmu_idx;
>  }
>  
>  #include "exec/cpu-all.h"
> diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
> index 288903e..ba3caec 100644
> --- a/target-ppc/excp_helper.c
> +++ b/target-ppc/excp_helper.c
> @@ -646,9 +646,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp_model, int excp)
>  
>  if (env->spr[SPR_LPCR] & LPCR_AIL) {
>  new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
> -} else if (msr & ((1 << MSR_IR) | (1 << MSR_DR))) {
> -/* If we disactivated any translation, flush TLBs */
> -tlb_flush(cs, 1);
>  }
>  
>  #ifdef TARGET_PPC64
> @@ -721,14 +718,6 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
> excp_model, int excp)
>  /* Reset exception state */
>  cs->exception_index = POWERPC_EXCP_NONE;
>  env->error_code = 0;
> -
> -if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
> -(env->mmu_model == POWERPC_MMU_BOOKE206)) {
> -/* XXX: The BookE changes address space when switching modes,
> -we should probably implement that as different MMU indexes,
> -but for the moment we do it the slow way and flush all.  */
> -tlb_flush(cs, 1);
> -}
>  }
>  
>  void ppc_cpu_do_interrupt(CPUState *cs)
> diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
> index 271fddf..f7edd5b 100644
> --- a/target-ppc/helper_regs.h
> +++ b/target-ppc/helper_regs.h
> @@ -41,11 +41,50 @@ static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
>  
>  static inline void hreg_compute_mem_idx(CPUPPCState *env)
>  {
> -/* Precompute MMU index */
> -if (msr_pr == 0 && msr_hv != 0) {
> -env->mmu_idx = 2;
> +/* This is our encoding for server processors
> + *
> + *   0 = Guest User space virtual mode
> + *   1 = Guest K