aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/hugetlbpage.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm/hugetlbpage.c')
-rw-r--r--arch/sparc/mm/hugetlbpage.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 4977800e9770..ba52e6466a82 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -176,17 +176,31 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
176 pte_t *ptep, pte_t entry) 176 pte_t *ptep, pte_t entry)
177{ 177{
178 int i; 178 int i;
179 pte_t orig[2];
180 unsigned long nptes;
179 181
180 if (!pte_present(*ptep) && pte_present(entry)) 182 if (!pte_present(*ptep) && pte_present(entry))
181 mm->context.huge_pte_count++; 183 mm->context.huge_pte_count++;
182 184
183 addr &= HPAGE_MASK; 185 addr &= HPAGE_MASK;
184 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { 186
185 set_pte_at(mm, addr, ptep, entry); 187 nptes = 1 << HUGETLB_PAGE_ORDER;
188 orig[0] = *ptep;
189 orig[1] = *(ptep + nptes / 2);
190 for (i = 0; i < nptes; i++) {
191 *ptep = entry;
186 ptep++; 192 ptep++;
187 addr += PAGE_SIZE; 193 addr += PAGE_SIZE;
188 pte_val(entry) += PAGE_SIZE; 194 pte_val(entry) += PAGE_SIZE;
189 } 195 }
196
197 /* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
198 addr -= REAL_HPAGE_SIZE;
199 ptep -= nptes / 2;
200 maybe_tlb_batch_add(mm, addr, ptep, orig[1], 0);
201 addr -= REAL_HPAGE_SIZE;
202 ptep -= nptes / 2;
203 maybe_tlb_batch_add(mm, addr, ptep, orig[0], 0);
190} 204}
191 205
192pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, 206pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
@@ -194,19 +208,28 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
194{ 208{
195 pte_t entry; 209 pte_t entry;
196 int i; 210 int i;
211 unsigned long nptes;
197 212
198 entry = *ptep; 213 entry = *ptep;
199 if (pte_present(entry)) 214 if (pte_present(entry))
200 mm->context.huge_pte_count--; 215 mm->context.huge_pte_count--;
201 216
202 addr &= HPAGE_MASK; 217 addr &= HPAGE_MASK;
203 218 nptes = 1 << HUGETLB_PAGE_ORDER;
204 for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { 219 for (i = 0; i < nptes; i++) {
205 pte_clear(mm, addr, ptep); 220 *ptep = __pte(0UL);
206 addr += PAGE_SIZE; 221 addr += PAGE_SIZE;
207 ptep++; 222 ptep++;
208 } 223 }
209 224
225 /* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
226 addr -= REAL_HPAGE_SIZE;
227 ptep -= nptes / 2;
228 maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
229 addr -= REAL_HPAGE_SIZE;
230 ptep -= nptes / 2;
231 maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
232
210 return entry; 233 return entry;
211} 234}
212 235