[PATCH -V1 09/24] powerpc: Decode the pte-lp-encoding bits correctly.
Aneesh Kumar K.V
aneesh.kumar at linux.vnet.ibm.com
Mon Mar 4 22:52:50 EST 2013
Paul Mackerras <paulus at samba.org> writes:
> On Tue, Feb 26, 2013 at 01:34:59PM +0530, Aneesh Kumar K.V wrote:
>> From: "Aneesh Kumar K.V" <aneesh.kumar at 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.
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
* 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;
}
More information about the Linuxppc-dev
mailing list