Commit eda8eebd authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Benjamin Herrenschmidt

powerpc/mm: Fix hash computation function

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: default avatarMike Qiu <qiudayu@linux.vnet.ibm.com>
Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Tested-by: default avatarMike Qiu <qiudayu@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
CC: <stable@vger.kernel.org> [v3.7]
parent 689dfa89
...@@ -115,11 +115,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -115,11 +115,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
sldi r29,r5,SID_SHIFT - VPN_SHIFT sldi r29,r5,SID_SHIFT - VPN_SHIFT
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29 or r29,r28,r29
/*
/* Calculate hash value for primary slot and store it in r28 */ * Calculate hash value for primary slot and store it in r28
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ * r3 = va, r5 = vsid
rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */ * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
xor r28,r5,r0 */
rldicl r0,r3,64-12,48
xor r28,r5,r0 /* hash */
b 4f b 4f
3: /* Calc vpn and put it in r29 */ 3: /* Calc vpn and put it in r29 */
...@@ -130,11 +132,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -130,11 +132,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/* /*
* calculate hash value for primary slot and * calculate hash value for primary slot and
* store it in r28 for 1T segment * store it in r28 for 1T segment
* r3 = va, r5 = vsid
*/ */
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ sldi r28,r5,25 /* vsid << 25 */
clrldi r5,r5,40 /* vsid & 0xffffff */ /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ rldicl r0,r3,64-12,36
xor r28,r28,r5 xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
xor r28,r28,r0 /* hash */ xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */ /* Convert linux PTE bits into HW equivalents */
...@@ -407,11 +410,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -407,11 +410,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
*/ */
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29 or r29,r28,r29
/*
/* Calculate hash value for primary slot and store it in r28 */ * Calculate hash value for primary slot and store it in r28
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ * r3 = va, r5 = vsid
rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */ * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
xor r28,r5,r0 */
rldicl r0,r3,64-12,48
xor r28,r5,r0 /* hash */
b 4f b 4f
3: /* Calc vpn and put it in r29 */ 3: /* Calc vpn and put it in r29 */
...@@ -426,11 +431,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -426,11 +431,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/* /*
* Calculate hash value for primary slot and * Calculate hash value for primary slot and
* store it in r28 for 1T segment * store it in r28 for 1T segment
* r3 = va, r5 = vsid
*/ */
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ sldi r28,r5,25 /* vsid << 25 */
clrldi r5,r5,40 /* vsid & 0xffffff */ /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ rldicl r0,r3,64-12,36
xor r28,r28,r5 xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
xor r28,r28,r0 /* hash */ xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */ /* Convert linux PTE bits into HW equivalents */
...@@ -752,25 +758,27 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -752,25 +758,27 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29 or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */ /* Calculate hash value for primary slot and store it in r28
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ * r3 = va, r5 = vsid
rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */ * r0 = (va >> 16) & ((1ul << (28 - 16)) -1)
xor r28,r5,r0 */
rldicl r0,r3,64-16,52
xor r28,r5,r0 /* hash */
b 4f b 4f
3: /* Calc vpn and put it in r29 */ 3: /* Calc vpn and put it in r29 */
sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
or r29,r28,r29 or r29,r28,r29
/* /*
* calculate hash value for primary slot and * calculate hash value for primary slot and
* store it in r28 for 1T segment * store it in r28 for 1T segment
* r3 = va, r5 = vsid
*/ */
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ sldi r28,r5,25 /* vsid << 25 */
clrldi r5,r5,40 /* vsid & 0xffffff */ /* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */
rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */ rldicl r0,r3,64-16,40
xor r28,r28,r5 xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
xor r28,r28,r0 /* hash */ xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */ /* Convert linux PTE bits into HW equivalents */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment