Skip to content

Commit

Permalink
powerpc/mm: Fix hash computation function
Browse files Browse the repository at this point in the history
The ASM version of hash computation function was truncating the upper bit.
Make the ASM version similar to hpt_hash function. Remove masking vsid bits.
Without this patch, we observed hang during bootup due to not satisfying page
fault request correctly. The fault handler used wrong hash values to update
the HPTE. Hence we kept looping with page fault.

hash_page(ea=000001003e260008, access=203, trap=300 ip=3fff91787134 dsisr 42000000
The computed value of hash 000000000f22f390
update: avpnv=4003e46054003e00, hash=000000000722f390, f=80000006, psize: 2 ...

BenH: The over-masking has been there for ever but only hurts with the
new 64T support introduced in 3.7

Reported-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Tested-by: Mike Qiu <qiudayu@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org> [v3.7]
  • Loading branch information
Aneesh Kumar K.V authored and Benjamin Herrenschmidt committed Feb 4, 2013
1 parent 689dfa8 commit eda8eeb
Showing 1 changed file with 35 additions and 27 deletions.
62 changes: 35 additions & 27 deletions arch/powerpc/mm/hash_low_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
sldi r29,r5,SID_SHIFT - VPN_SHIFT
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29

/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
xor r28,r5,r0
/*
* Calculate hash value for primary slot and store it in r28
* r3 = va, r5 = vsid
* r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
*/
rldicl r0,r3,64-12,48
xor r28,r5,r0 /* hash */
b 4f

3: /* Calc vpn and put it in r29 */
Expand All @@ -130,11 +132,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/*
* calculate hash value for primary slot and
* store it in r28 for 1T segment
* r3 = va, r5 = vsid
*/
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
xor r28,r28,r5
sldi r28,r5,25 /* vsid << 25 */
/* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
rldicl r0,r3,64-12,36
xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
xor r28,r28,r0 /* hash */

/* Convert linux PTE bits into HW equivalents */
Expand Down Expand Up @@ -407,11 +410,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
*/
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29

/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
xor r28,r5,r0
/*
* Calculate hash value for primary slot and store it in r28
* r3 = va, r5 = vsid
* r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
*/
rldicl r0,r3,64-12,48
xor r28,r5,r0 /* hash */
b 4f

3: /* Calc vpn and put it in r29 */
Expand All @@ -426,11 +431,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/*
* Calculate hash value for primary slot and
* store it in r28 for 1T segment
* r3 = va, r5 = vsid
*/
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
xor r28,r28,r5
sldi r28,r5,25 /* vsid << 25 */
/* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
rldicl r0,r3,64-12,36
xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
xor r28,r28,r0 /* hash */

/* Convert linux PTE bits into HW equivalents */
Expand Down Expand Up @@ -752,25 +758,27 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29

/* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */
xor r28,r5,r0
/* Calculate hash value for primary slot and store it in r28
* r3 = va, r5 = vsid
* r0 = (va >> 16) & ((1ul << (28 - 16)) -1)
*/
rldicl r0,r3,64-16,52
xor r28,r5,r0 /* hash */
b 4f

3: /* Calc vpn and put it in r29 */
sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
or r29,r28,r29

/*
* calculate hash value for primary slot and
* store it in r28 for 1T segment
* r3 = va, r5 = vsid
*/
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */
xor r28,r28,r5
sldi r28,r5,25 /* vsid << 25 */
/* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */
rldicl r0,r3,64-16,40
xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
xor r28,r28,r0 /* hash */

/* Convert linux PTE bits into HW equivalents */
Expand Down

0 comments on commit eda8eeb

Please sign in to comment.