On 06/18/2018 08:36 AM, David Gibson wrote: > The paravirtualized PAPR platform sometimes needs to restrict the guest to > using only some of the page sizes actually supported by the host's MMU. > At the moment this is handled in KVM specific code, but for consistency we > want to apply the same limitations to all accelerators. > > This makes a start on this by providing a helper function in the cpu code > to allow platform code to remove some of the cpu's page size definitions > via a caller supplied callback. > > Signed-off-by: David Gibson <da...@gibson.dropbear.id.au>
it looks correct. Reviewed-by: Cédric Le Goater <c...@kaod.org> Thanks, C. > --- > target/ppc/mmu-hash64.c | 59 +++++++++++++++++++++++++++++++++++++++++ > target/ppc/mmu-hash64.h | 3 +++ > 2 files changed, 62 insertions(+) > > diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c > index aa200cba4c..276d9015e7 100644 > --- a/target/ppc/mmu-hash64.c > +++ b/target/ppc/mmu-hash64.c > @@ -1166,3 +1166,62 @@ const PPCHash64Options ppc_hash64_opts_POWER7 = { > }, > } > }; > + > +void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu, > + bool (*cb)(void *, uint32_t, uint32_t), > + void *opaque) > +{ > + PPCHash64Options *opts = cpu->hash64_opts; > + int i; > + int n = 0; > + bool ci_largepage = false; > + > + assert(opts); > + > + n = 0; > + for (i = 0; i < ARRAY_SIZE(opts->sps); i++) { > + PPCHash64SegmentPageSizes *sps = &opts->sps[i]; > + int j; > + int m = 0; > + > + assert(n <= i); > + > + if (!sps->page_shift) { > + break; > + } > + > + for (j = 0; j < ARRAY_SIZE(sps->enc); j++) { > + PPCHash64PageSize *ps = &sps->enc[j]; > + > + assert(m <= j); > + if (!ps->page_shift) { > + break; > + } > + > + if (cb(opaque, sps->page_shift, ps->page_shift)) { > + if (ps->page_shift >= 16) { > + ci_largepage = true; > + } > + sps->enc[m++] = *ps; > + } > + } > + > + /* Clear rest of the row */ > + for (j = m; j < ARRAY_SIZE(sps->enc); j++) { > + memset(&sps->enc[j], 0, sizeof(sps->enc[j])); > + } > + > + if (m) { > + n++; > + } > + } > + > + /* Clear the rest of the table */ > + for (i = n; i < ARRAY_SIZE(opts->sps); i++) { > + memset(&opts->sps[i], 0, sizeof(opts->sps[i])); > + } > + > + if (!ci_largepage) { > + opts->flags &= ~PPC_HASH64_CI_LARGEPAGE; > + } > +} > diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h > index 53dcec5b93..f11efc9cbc 100644 > --- a/target/ppc/mmu-hash64.h > +++ b/target/ppc/mmu-hash64.h > @@ -20,6 +20,9 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu, > void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); > void ppc_hash64_init(PowerPCCPU *cpu); > void ppc_hash64_finalize(PowerPCCPU *cpu); > +void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu, > + bool (*cb)(void *, uint32_t, uint32_t), > + void *opaque); > #endif > > /* >