"Aneesh Kumar K.V" <aneesh.ku...@linux.vnet.ibm.com> writes:

> Paul Mackerras <pau...@samba.org> writes:
>
>> On Tue, Feb 26, 2013 at 01:34:59PM +0530, Aneesh Kumar K.V wrote:
>>> From: "Aneesh Kumar K.V" <aneesh.ku...@linux.vnet.ibm.com>
>>> 
>>> +static inline int hpte_actual_psize(struct hash_pte *hptep, int psize)
>>> +{
>>> +   unsigned int mask;
>>> +   int i, penc, shift;
>>> +   /* Look at the 8 bit LP value */
>>> +   unsigned int lp = (hptep->r >> LP_SHIFT) & ((1 << LP_BITS) - 1);
>>> +
>>> +   penc = 0;
>>> +   for (i = 0; i < MMU_PAGE_COUNT; i++) {
>>> +           /* valid entries have a shift value */
>>> +           if (!mmu_psize_defs[i].shift)
>>> +                   continue;
>>> +
>>> +           /* encoding bits per actual page size */
>>> +           shift = mmu_psize_defs[i].shift - 11;
>>> +           if (shift > 9)
>>> +                   shift = 9;
>>> +           mask = (1 << shift) - 1;
>>> +           if ((lp & mask) == mmu_psize_defs[psize].penc[i])
>>> +                   return i;
>>> +   }
>>> +   return -1;
>>> +}
>>
>> This doesn't look right to me.  First, it's not clear what the 11 and
>> 9 refer to, and I think the 9 should be LP_BITS (i.e. 8).  Secondly,
>> the mask for the comparison needs to depend on the actual page size
>> not the base page size.
>
> How about the below. I am yet to test this in user space. 

I needed to special case 4K case. This seems to work fine with the test.

static inline int hpte_actual_psize(struct hash_pte *hptep, int psize)
{
        unsigned int mask;
        int i, penc, shift;
        /* Look at the 8 bit LP value */
        unsigned int lp = (hptep->r >> LP_SHIFT) & ((1 << LP_BITS) - 1);

        /* First check if it is large page */
        if (!(hptep->v & HPTE_V_LARGE))
                return MMU_PAGE_4K;

        penc = 0;
        for (i = 1; i < MMU_PAGE_COUNT; i++) {
                /* valid entries have a shift value */
                if (!mmu_psize_defs[i].shift)
                        continue;
                /*
                 * 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[i].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[psize].penc[i])
                        return i;
        }
        return -1;
}

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Reply via email to