Message ID | 20230726182230.433945-3-npiggin@gmail.com |
---|---|
State | New |
Headers | show |
Series | ppc fixes possibly for 8.1 | expand |
On 7/26/23 20:22, Nicholas Piggin wrote: > Until v2.07s, the VRMA page size (L||LP) was encoded in LPCR[VRMASD]. > In v3.0 that moved to the partition table PS field. > > The powernv machine can now run KVM HPT guests on POWER9/10 CPUs with > this fix and the patch to add ASDR. > > Fixes: 3367c62f522b ("target/ppc: Support for POWER9 native hash") > Signed-off-by: Nicholas Piggin <npiggin@gmail.com> > --- > target/ppc/mmu-hash64.c | 41 +++++++++++++++++++++++++++++++++++------ > 1 file changed, 35 insertions(+), 6 deletions(-) > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c > index a0c90df3ce..7f8bbbbdb0 100644 > --- a/target/ppc/mmu-hash64.c > +++ b/target/ppc/mmu-hash64.c > @@ -874,12 +874,41 @@ static target_ulong rmls_limit(PowerPCCPU *cpu) > return rma_sizes[rmls]; > } > > -static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb) > +/* Return the LLP in SLB_VSID format */ > +static uint64_t get_vrma_llp(PowerPCCPU *cpu) > { > CPUPPCState *env = &cpu->env; > - target_ulong lpcr = env->spr[SPR_LPCR]; > - uint32_t vrmasd = (lpcr & LPCR_VRMASD) >> LPCR_VRMASD_SHIFT; > - target_ulong vsid = SLB_VSID_VRMA | ((vrmasd << 4) & SLB_VSID_LLP_MASK); > + uint64_t llp; > + > + if (env->mmu_model == POWERPC_MMU_3_00) { > + ppc_v3_pate_t pate; > + uint64_t ps; > + > + /* > + * ISA v3.0 removes the LPCR[VRMASD] field and puts the VRMA base > + * page size (L||LP equivalent) in the PS field in the HPT partition > + * table entry. > + */ > + if (!ppc64_v3_get_pate(cpu, cpu->env.spr[SPR_LPIDR], &pate)) { > + error_report("Bad VRMA with no partition table entry"); > + return 0; > + } > + ps = pate.dw0 >> (63 - 58); > + llp = ((ps & 0x4) << (63 - 55 - 2)) | ((ps & 0x3) << (63 - 59)); Please add bitfield definitions for these numbers :) > + > + } else { > + uint64_t lpcr = env->spr[SPR_LPCR]; > + target_ulong vrmasd = (lpcr & LPCR_VRMASD) >> LPCR_VRMASD_SHIFT; > + > + llp = (vrmasd << 4) & SLB_VSID_LLP_MASK; > + } > + > + return llp; > +} > + > +static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb) > +{ > + target_ulong vsid = SLB_VSID_VRMA | get_vrma_llp(cpu); May be you could introduce a 'uint64_t llp' variable instead and use it directly in error_report and in the slb encoding test. This is minor. Thanks, C. > int i; > > for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { > @@ -897,8 +926,8 @@ static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb) > } > } > > - error_report("Bad page size encoding in LPCR[VRMASD]; LPCR=0x" > - TARGET_FMT_lx, lpcr); > + error_report("Bad VRMA page size encoding 0x" TARGET_FMT_lx, > + get_vrma_llp(cpu)); > > return -1; > }
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index a0c90df3ce..7f8bbbbdb0 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -874,12 +874,41 @@ static target_ulong rmls_limit(PowerPCCPU *cpu) return rma_sizes[rmls]; } -static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb) +/* Return the LLP in SLB_VSID format */ +static uint64_t get_vrma_llp(PowerPCCPU *cpu) { CPUPPCState *env = &cpu->env; - target_ulong lpcr = env->spr[SPR_LPCR]; - uint32_t vrmasd = (lpcr & LPCR_VRMASD) >> LPCR_VRMASD_SHIFT; - target_ulong vsid = SLB_VSID_VRMA | ((vrmasd << 4) & SLB_VSID_LLP_MASK); + uint64_t llp; + + if (env->mmu_model == POWERPC_MMU_3_00) { + ppc_v3_pate_t pate; + uint64_t ps; + + /* + * ISA v3.0 removes the LPCR[VRMASD] field and puts the VRMA base + * page size (L||LP equivalent) in the PS field in the HPT partition + * table entry. + */ + if (!ppc64_v3_get_pate(cpu, cpu->env.spr[SPR_LPIDR], &pate)) { + error_report("Bad VRMA with no partition table entry"); + return 0; + } + ps = pate.dw0 >> (63 - 58); + llp = ((ps & 0x4) << (63 - 55 - 2)) | ((ps & 0x3) << (63 - 59)); + + } else { + uint64_t lpcr = env->spr[SPR_LPCR]; + target_ulong vrmasd = (lpcr & LPCR_VRMASD) >> LPCR_VRMASD_SHIFT; + + llp = (vrmasd << 4) & SLB_VSID_LLP_MASK; + } + + return llp; +} + +static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb) +{ + target_ulong vsid = SLB_VSID_VRMA | get_vrma_llp(cpu); int i; for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { @@ -897,8 +926,8 @@ static int build_vrma_slbe(PowerPCCPU *cpu, ppc_slb_t *slb) } } - error_report("Bad page size encoding in LPCR[VRMASD]; LPCR=0x" - TARGET_FMT_lx, lpcr); + error_report("Bad VRMA page size encoding 0x" TARGET_FMT_lx, + get_vrma_llp(cpu)); return -1; }
Until v2.07s, the VRMA page size (L||LP) was encoded in LPCR[VRMASD]. In v3.0 that moved to the partition table PS field. The powernv machine can now run KVM HPT guests on POWER9/10 CPUs with this fix and the patch to add ASDR. Fixes: 3367c62f522b ("target/ppc: Support for POWER9 native hash") Signed-off-by: Nicholas Piggin <npiggin@gmail.com> --- target/ppc/mmu-hash64.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-)