aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm
diff options
context:
space:
mode:
authorLi Zhong <zhong@linux.vnet.ibm.com>2013-04-15 12:53:19 -0400
committerMichael Ellerman <michael@ellerman.id.au>2013-04-18 01:59:59 -0400
commitb170bd3de6a7f6fbfba331e300751450f55d8822 (patch)
treed703646cc3179549eb40eb99741f04b887ec0637 /arch/powerpc/mm
parent2c3c0693d9cf06d7baf99cfdc10f9c4d40198c6b (diff)
powerpc: Split the code trying to insert hpte repeatedly as an helper function
Move the logic trying to insert hpte in __hash_page_huge() to an helper function, so it could also be used by others. Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/mm')
-rw-r--r--arch/powerpc/mm/hash_utils_64.c35
-rw-r--r--arch/powerpc/mm/hugetlbpage-hash64.c31
2 files changed, 41 insertions, 25 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index f410c3e12c1e..ead9fa84ffd9 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1230,6 +1230,41 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc)
1230 bad_page_fault(regs, address, SIGBUS); 1230 bad_page_fault(regs, address, SIGBUS);
1231} 1231}
1232 1232
1233long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
1234 unsigned long pa, unsigned long rflags,
1235 unsigned long vflags, int psize, int ssize)
1236{
1237 unsigned long hpte_group;
1238 long slot;
1239
1240repeat:
1241 hpte_group = ((hash & htab_hash_mask) *
1242 HPTES_PER_GROUP) & ~0x7UL;
1243
1244 /* Insert into the hash table, primary slot */
1245 slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, vflags,
1246 psize, ssize);
1247
1248 /* Primary is full, try the secondary */
1249 if (unlikely(slot == -1)) {
1250 hpte_group = ((~hash & htab_hash_mask) *
1251 HPTES_PER_GROUP) & ~0x7UL;
1252 slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags,
1253 vflags | HPTE_V_SECONDARY,
1254 psize, ssize);
1255 if (slot == -1) {
1256 if (mftb() & 0x1)
1257 hpte_group = ((hash & htab_hash_mask) *
1258 HPTES_PER_GROUP)&~0x7UL;
1259
1260 ppc_md.hpte_remove(hpte_group);
1261 goto repeat;
1262 }
1263 }
1264
1265 return slot;
1266}
1267
1233#ifdef CONFIG_DEBUG_PAGEALLOC 1268#ifdef CONFIG_DEBUG_PAGEALLOC
1234static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) 1269static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
1235{ 1270{
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index edb4129b182a..b913f416d97a 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -14,6 +14,10 @@
14#include <asm/cacheflush.h> 14#include <asm/cacheflush.h>
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16 16
17extern long hpte_insert_repeating(unsigned long hash, unsigned long vpn,
18 unsigned long pa, unsigned long rlags,
19 unsigned long vflags, int psize, int ssize);
20
17int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, 21int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
18 pte_t *ptep, unsigned long trap, int local, int ssize, 22 pte_t *ptep, unsigned long trap, int local, int ssize,
19 unsigned int shift, unsigned int mmu_psize) 23 unsigned int shift, unsigned int mmu_psize)
@@ -83,7 +87,6 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
83 87
84 if (likely(!(old_pte & _PAGE_HASHPTE))) { 88 if (likely(!(old_pte & _PAGE_HASHPTE))) {
85 unsigned long hash = hpt_hash(vpn, shift, ssize); 89 unsigned long hash = hpt_hash(vpn, shift, ssize);
86 unsigned long hpte_group;
87 90
88 pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; 91 pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
89 92
@@ -97,30 +100,8 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
97 rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE | 100 rflags |= (new_pte & (_PAGE_WRITETHRU | _PAGE_NO_CACHE |
98 _PAGE_COHERENT | _PAGE_GUARDED)); 101 _PAGE_COHERENT | _PAGE_GUARDED));
99 102
100repeat: 103 slot = hpte_insert_repeating(hash, vpn, pa, rflags, 0,
101 hpte_group = ((hash & htab_hash_mask) * 104 mmu_psize, ssize);
102 HPTES_PER_GROUP) & ~0x7UL;
103
104 /* Insert into the hash table, primary slot */
105 slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
106 mmu_psize, ssize);
107
108 /* Primary is full, try the secondary */
109 if (unlikely(slot == -1)) {
110 hpte_group = ((~hash & htab_hash_mask) *
111 HPTES_PER_GROUP) & ~0x7UL;
112 slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags,
113 HPTE_V_SECONDARY,
114 mmu_psize, ssize);
115 if (slot == -1) {
116 if (mftb() & 0x1)
117 hpte_group = ((hash & htab_hash_mask) *
118 HPTES_PER_GROUP)&~0x7UL;
119
120 ppc_md.hpte_remove(hpte_group);
121 goto repeat;
122 }
123 }
124 105
125 /* 106 /*
126 * Hypervisor failure. Restore old pte and return -1 107 * Hypervisor failure. Restore old pte and return -1