qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 05/10] target-ppc: Use actual page size encoding


From: David Gibson
Subject: Re: [Qemu-devel] [PATCH 05/10] target-ppc: Use actual page size encodings from HPTE
Date: Tue, 26 Jan 2016 00:26:35 +1100
User-agent: Mutt/1.5.24 (2015-08-30)

On Mon, Jan 25, 2016 at 04:15:47PM +1100, David Gibson wrote:
> At present the 64-bit hash MMU code uses information from the SLB to
> determine the page size of a translation.  We do need that information to
> correctly look up the hash table.  However the MMU also allows a
> possibly larger page size to be encoded into the HPTE itself, which is used
> to populate the TLB.  At present qemu doesn't check that, and so doesn't
> support the MPSS "Multiple Page Size per Segment" feature.
> 
> This makes a start on allowing this, by adding an hpte_page_shift()
> function which looks up the page size of an HPTE.  We use this to validate
> page sizes encodings on faults, and populate the qemu TLB with larger
> page sizes when appropriate.
> 
> Signed-off-by: David Gibson <address@hidden>
> ---
>  target-ppc/mmu-hash64.c | 74 
> ++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 70 insertions(+), 4 deletions(-)
> 
> diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
> index 28ad361..bcad826 100644
> --- a/target-ppc/mmu-hash64.c
> +++ b/target-ppc/mmu-hash64.c
> @@ -21,6 +21,7 @@
>  #include "exec/helper-proto.h"
>  #include "qemu/error-report.h"
>  #include "sysemu/kvm.h"
> +#include "qemu/error-report.h"
>  #include "kvm_ppc.h"
>  #include "mmu-hash64.h"
>  
> @@ -474,6 +475,43 @@ static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
>      return pte_offset;
>  }
>  
> +static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
> +    uint64_t pte0, uint64_t pte1)
> +{
> +    int i;
> +
> +    if (!(pte0 & HPTE64_V_LARGE)) {
> +        if (sps->page_shift != 12) {
> +            /* 4kiB page in a non 4kiB segment */
> +            return 0;
> +        }
> +        /* Normal 4kiB page */
> +        return 12;
> +    }
> +
> +    for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
> +        const struct ppc_one_page_size *ps = &sps->enc[i];
> +        uint64_t mask;
> +
> +        if (!ps->page_shift) {
> +            break;
> +        }
> +
> +        if (ps->page_shift == 12) {
> +            /* L bit is set so this can't be a 4kiB page */
> +            continue;
> +        }
> +
> +        mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
> +
> +        if ((pte1 & mask) == ps->pte_enc) {

Gah.  This needs to be (ps->pte_enc << HPTE64_R_RPN_SHIFT) or
everything breaks.

I remember fixing this earlier, but somehow I managed to lose the fix
in both this posting and the previous one.

-- 
David Gibson                    | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
                                | _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]