| Submitter | Aneesh Kumar K.V |
|---|---|
| Date | March 6, 2013, 6:10 a.m. |
| Message ID | <1362550227-575-12-git-send-email-aneesh.kumar@linux.vnet.ibm.com> |
| Download | mbox | patch |
| Permalink | /patch/225352/ |
| State | Superseded, archived |
| Headers | show |
Comments
On Wed, Mar 06, 2013 at 11:40:12AM +0530, Aneesh Kumar K.V wrote: > From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com> > > As per ISA doc, we encode base and actual page size in the LP bits of > PTE. The number of bit used to encode the page sizes depend on actual > page size. ISA doc lists this as > > PTE LP actual page size > rrrr rrrz ≥8KB > rrrr rrzz ≥16KB > rrrr rzzz ≥32KB > rrrr zzzz ≥64KB > rrrz zzzz ≥128KB > rrzz zzzz ≥256KB > rzzz zzzz ≥512KB > zzzz zzzz ≥1MB > > ISA doc also says > "The values of the “z” bits used to specify each size, along with all possible > values of “r” bits in the LP field, must result in LP values distinct from > other LP values for other sizes." > > based on the above update hpte_decode to use the correct decoding for LP bits. > > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> [snip] > + shift = mmu_psize_defs[a_size].shift - > + mmu_psize_defs[MMU_PAGE_4K].shift; "mmu_psize_defs[MMU_PAGE_4K].shift" seems like an overly complicated way to write "LP_SHIFT" (or even "12"). After all, you did: > + unsigned int lp = (hpte->r >> LP_SHIFT) & ((1 << LP_BITS) - 1); earlier. If LP_SHIFT is good enough in that expression it's good enough when calculating shift. Apart from that minor nit, Acked-by: Paul Mackerras <paulus@samba.org>
Patch
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 7b5bf94..5e7f45c 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -412,41 +412,48 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, int *psize, int *apsize, int *ssize, unsigned long *vpn) { unsigned long avpn, pteg, vpi; - unsigned long hpte_r = hpte->r; unsigned long hpte_v = hpte->v; unsigned long vsid, seg_off; - int i, size, a_size, shift, penc; + int size, a_size, shift, mask; + /* Look at the 8 bit LP value */ + unsigned int lp = (hpte->r >> LP_SHIFT) & ((1 << LP_BITS) - 1); if (!(hpte_v & HPTE_V_LARGE)) { size = MMU_PAGE_4K; a_size = MMU_PAGE_4K; } else { - for (i = 0; i < LP_BITS; i++) { - if ((hpte_r & LP_MASK(i+1)) == LP_MASK(i+1)) - break; - } - penc = LP_MASK(i+1) >> LP_SHIFT; for (size = 0; size < MMU_PAGE_COUNT; size++) { /* valid entries have a shift value */ if (!mmu_psize_defs[size].shift) continue; - for (a_size = 0; a_size < MMU_PAGE_COUNT; a_size++) { - - /* 4K pages are not represented by LP */ - if (a_size == MMU_PAGE_4K) - continue; + /* start from 1 ignoring MMU_PAGE_4K */ + for (a_size = 1; a_size < MMU_PAGE_COUNT; a_size++) { /* valid entries have a shift value */ if (!mmu_psize_defs[a_size].shift) continue; - - if (penc == mmu_psize_defs[size].penc[a_size]) + /* + * encoding bits per actual page size + * PTE LP actual page size + * rrrr rrrz ≥8KB + * rrrr rrzz ≥16KB + * rrrr rzzz ≥32KB + * rrrr zzzz ≥64KB + * ....... + */ + shift = mmu_psize_defs[a_size].shift - + mmu_psize_defs[MMU_PAGE_4K].shift; + if (shift > LP_BITS) + shift = LP_BITS; + mask = (1 << shift) - 1; + if ((lp & mask) == + mmu_psize_defs[size].penc[a_size]) { goto out; + } } } } - out: /* This works for all page sizes, and for 256M and 1T segments */ *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;