Commit eda8eebdd153c48a4e2a3a3ac3cd9e2e31f5c6b3

Authored by Aneesh Kumar K.V
Committed by Benjamin Herrenschmidt
1 parent 689dfa894c

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: 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]

Showing 1 changed file with 35 additions and 27 deletions Side-by-side Diff

arch/powerpc/mm/hash_low_64.S
... ... @@ -115,11 +115,13 @@
115 115 sldi r29,r5,SID_SHIFT - VPN_SHIFT
116 116 rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
117 117 or r29,r28,r29
118   -
119   - /* Calculate hash value for primary slot and store it in r28 */
120   - rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
121   - rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
122   - xor r28,r5,r0
  118 + /*
  119 + * Calculate hash value for primary slot and store it in r28
  120 + * r3 = va, r5 = vsid
  121 + * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
  122 + */
  123 + rldicl r0,r3,64-12,48
  124 + xor r28,r5,r0 /* hash */
123 125 b 4f
124 126  
125 127 3: /* Calc vpn and put it in r29 */
126 128  
... ... @@ -130,11 +132,12 @@
130 132 /*
131 133 * calculate hash value for primary slot and
132 134 * store it in r28 for 1T segment
  135 + * r3 = va, r5 = vsid
133 136 */
134   - rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
135   - clrldi r5,r5,40 /* vsid & 0xffffff */
136   - rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
137   - xor r28,r28,r5
  137 + sldi r28,r5,25 /* vsid << 25 */
  138 + /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
  139 + rldicl r0,r3,64-12,36
  140 + xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
138 141 xor r28,r28,r0 /* hash */
139 142  
140 143 /* Convert linux PTE bits into HW equivalents */
... ... @@ -407,11 +410,13 @@
407 410 */
408 411 rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
409 412 or r29,r28,r29
410   -
411   - /* Calculate hash value for primary slot and store it in r28 */
412   - rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
413   - rldicl r0,r3,64-12,48 /* (ea >> 12) & 0xffff */
414   - xor r28,r5,r0
  413 + /*
  414 + * Calculate hash value for primary slot and store it in r28
  415 + * r3 = va, r5 = vsid
  416 + * r0 = (va >> 12) & ((1ul << (28 - 12)) -1)
  417 + */
  418 + rldicl r0,r3,64-12,48
  419 + xor r28,r5,r0 /* hash */
415 420 b 4f
416 421  
417 422 3: /* Calc vpn and put it in r29 */
418 423  
... ... @@ -426,11 +431,12 @@
426 431 /*
427 432 * Calculate hash value for primary slot and
428 433 * store it in r28 for 1T segment
  434 + * r3 = va, r5 = vsid
429 435 */
430   - rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
431   - clrldi r5,r5,40 /* vsid & 0xffffff */
432   - rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
433   - xor r28,r28,r5
  436 + sldi r28,r5,25 /* vsid << 25 */
  437 + /* r0 = (va >> 12) & ((1ul << (40 - 12)) -1) */
  438 + rldicl r0,r3,64-12,36
  439 + xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
434 440 xor r28,r28,r0 /* hash */
435 441  
436 442 /* Convert linux PTE bits into HW equivalents */
437 443  
438 444  
439 445  
... ... @@ -752,25 +758,27 @@
752 758 rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
753 759 or r29,r28,r29
754 760  
755   - /* Calculate hash value for primary slot and store it in r28 */
756   - rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
757   - rldicl r0,r3,64-16,52 /* (ea >> 16) & 0xfff */
758   - xor r28,r5,r0
  761 + /* Calculate hash value for primary slot and store it in r28
  762 + * r3 = va, r5 = vsid
  763 + * r0 = (va >> 16) & ((1ul << (28 - 16)) -1)
  764 + */
  765 + rldicl r0,r3,64-16,52
  766 + xor r28,r5,r0 /* hash */
759 767 b 4f
760 768  
761 769 3: /* Calc vpn and put it in r29 */
762 770 sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
763 771 rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
764 772 or r29,r28,r29
765   -
766 773 /*
767 774 * calculate hash value for primary slot and
768 775 * store it in r28 for 1T segment
  776 + * r3 = va, r5 = vsid
769 777 */
770   - rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
771   - clrldi r5,r5,40 /* vsid & 0xffffff */
772   - rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */
773   - xor r28,r28,r5
  778 + sldi r28,r5,25 /* vsid << 25 */
  779 + /* r0 = (va >> 16) & ((1ul << (40 - 16)) -1) */
  780 + rldicl r0,r3,64-16,40
  781 + xor r28,r28,r5 /* vsid ^ ( vsid << 25) */
774 782 xor r28,r28,r0 /* hash */
775 783  
776 784 /* Convert linux PTE bits into HW equivalents */