Re: [Qemu-devel] [Qemu-ppc] [PULL 02/12] ppc: Use split I/D mmu modes to avoid flushes on interrupts
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
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
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