[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCHv2 09/10] target-ppc: Helper to determine page size
From: |
Benjamin Herrenschmidt |
Subject: |
Re: [Qemu-ppc] [PATCHv2 09/10] target-ppc: Helper to determine page size information from hpte alone |
Date: |
Thu, 28 Jan 2016 15:33:50 +1100 |
On Wed, 2016-01-27 at 21:13 +1100, David Gibson wrote:
> h_enter() in the spapr code needs to know the page size of the HPTE
> it's
> about to insert. Unlike other paths that do this, it doesn't have
> access
> to the SLB, so at the moment it determines this with some open-coded
> tests which assume POWER7 or POWER8 page size encodings.
>
> To make this more flexible add ppc_hash64_hpte_page_shift_noslb() to
> determine both the "base" page size per segment, and the individual
> effective page size from an HPTE alone.
>
> This means that the spapr code should now be able to handle any page
> size
> listed in the env->sps table.
>
> Signed-off-by: David Gibson <address@hidden>
Acked-by: Benjamin Herrenschmidt <address@hidden>
> ---
> hw/ppc/spapr_hcall.c | 25 ++++++-------------------
> target-ppc/mmu-hash64.c | 35 +++++++++++++++++++++++++++++++++++
> target-ppc/mmu-hash64.h | 3 +++
> 3 files changed, 44 insertions(+), 19 deletions(-)
>
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index dedc7e0..a535c73 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -72,31 +72,18 @@ static target_ulong h_enter(PowerPCCPU *cpu,
> sPAPRMachineState *spapr,
> target_ulong pte_index = args[1];
> target_ulong pteh = args[2];
> target_ulong ptel = args[3];
> - target_ulong page_shift = 12;
> + unsigned apshift, spshift;
> target_ulong raddr;
> target_ulong index;
> uint64_t token;
>
> - /* only handle 4k and 16M pages for now */
> - if (pteh & HPTE64_V_LARGE) {
> -#if 0 /* We don't support 64k pages yet */
> - if ((ptel & 0xf000) == 0x1000) {
> - /* 64k page */
> - } else
> -#endif
> - if ((ptel & 0xff000) == 0) {
> - /* 16M page */
> - page_shift = 24;
> - /* lowest AVA bit must be 0 for 16M pages */
> - if (pteh & 0x80) {
> - return H_PARAMETER;
> - }
> - } else {
> - return H_PARAMETER;
> - }
> + apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel,
> &spshift);
> + if (!apshift) {
> + /* Bad page size encoding */
> + return H_PARAMETER;
> }
>
> - raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1);
> + raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);
>
> if (is_ram_address(spapr, raddr)) {
> /* Regular RAM - should have WIMG=0010 */
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 3284776..19ee942 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -512,6 +512,41 @@ static unsigned hpte_page_shift(const struct
> ppc_one_seg_page_size *sps,
> return 0; /* Bad page size encoding */
> }
>
> +unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
> + uint64_t pte0, uint64_t
> pte1,
> + unsigned *seg_page_shift)
> +{
> + CPUPPCState *env = &cpu->env;
> + int i;
> +
> + if (!(pte0 & HPTE64_V_LARGE)) {
> + *seg_page_shift = 12;
> + return 12;
> + }
> +
> + /*
> + * The encodings in env->sps need to be carefully chosen so that
> + * this gives an unambiguous result.
> + */
> + for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
> + const struct ppc_one_seg_page_size *sps = &env->sps.sps[i];
> + unsigned shift;
> +
> + if (!sps->page_shift) {
> + break;
> + }
> +
> + shift = hpte_page_shift(sps, pte0, pte1);
> + if (shift) {
> + *seg_page_shift = sps->page_shift;
> + return shift;
> + }
> + }
> +
> + *seg_page_shift = 0;
> + return 0;
> +}
> +
> int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, target_ulong eaddr,
> int rwx, int mmu_idx)
> {
> diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
> index 293a951..34cf975 100644
> --- a/target-ppc/mmu-hash64.h
> +++ b/target-ppc/mmu-hash64.h
> @@ -16,6 +16,9 @@ void ppc_hash64_store_hpte(PowerPCCPU *cpu,
> target_ulong index,
> void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
> target_ulong pte_index,
> target_ulong pte0, target_ulong
> pte1);
> +unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
> + uint64_t pte0, uint64_t
> pte1,
> + unsigned *seg_page_shift);
> #endif
>
> /*
- Re: [Qemu-ppc] [PATCHv2 06/10] target-ppc: Remove unused mmu models from ppc_tlb_invalidate_one, (continued)
- [Qemu-ppc] [PATCHv2 08/10] target-ppc: Add new TLB invalidate by HPTE call for hash64 MMUs, David Gibson, 2016/01/27
- [Qemu-ppc] [PATCHv2 07/10] target-ppc: Split 44x tlbiva from ppc_tlb_invalidate_one(), David Gibson, 2016/01/27
- [Qemu-ppc] [PATCHv2 04/10] target-ppc: Rework SLB page size lookup, David Gibson, 2016/01/27
- [Qemu-ppc] [PATCHv2 09/10] target-ppc: Helper to determine page size information from hpte alone, David Gibson, 2016/01/27
- Re: [Qemu-ppc] [PATCHv2 09/10] target-ppc: Helper to determine page size information from hpte alone,
Benjamin Herrenschmidt <=
- [Qemu-ppc] [PATCHv2 05/10] target-ppc: Use actual page size encodings from HPTE, David Gibson, 2016/01/27
- [Qemu-ppc] [PATCHv2 03/10] target-ppc: Rework ppc_store_slb, David Gibson, 2016/01/27
- [Qemu-ppc] [PATCHv2 02/10] target-ppc: Convert mmu-hash{32, 64}.[ch] from CPUPPCState to PowerPCCPU, David Gibson, 2016/01/27
- [Qemu-ppc] [PATCHv2 01/10] target-ppc: Remove unused kvmppc_read_segment_page_sizes() stub, David Gibson, 2016/01/27