drm/panthor: Don't add write fences to the shared BOs
[drm/drm-misc.git] / arch / sparc / mm / hugetlbpage.c
blobcc91ca7a1e182cf6f6de2c96be13c0e7e248bed1
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * SPARC64 Huge TLB page support.
5 * Copyright (C) 2002, 2003, 2006 David S. Miller (davem@davemloft.net)
6 */
8 #include <linux/fs.h>
9 #include <linux/mm.h>
10 #include <linux/sched/mm.h>
11 #include <linux/hugetlb.h>
12 #include <linux/pagemap.h>
13 #include <linux/sysctl.h>
15 #include <asm/mman.h>
16 #include <asm/pgalloc.h>
17 #include <asm/tlb.h>
18 #include <asm/tlbflush.h>
19 #include <asm/cacheflush.h>
20 #include <asm/mmu_context.h>
22 /* Slightly simplified from the non-hugepage variant because by
23 * definition we don't have to worry about any page coloring stuff
26 static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *filp,
27 unsigned long addr,
28 unsigned long len,
29 unsigned long pgoff,
30 unsigned long flags)
32 struct hstate *h = hstate_file(filp);
33 unsigned long task_size = TASK_SIZE;
34 struct vm_unmapped_area_info info = {};
36 if (test_thread_flag(TIF_32BIT))
37 task_size = STACK_TOP32;
39 info.length = len;
40 info.low_limit = TASK_UNMAPPED_BASE;
41 info.high_limit = min(task_size, VA_EXCLUDE_START);
42 info.align_mask = PAGE_MASK & ~huge_page_mask(h);
43 addr = vm_unmapped_area(&info);
45 if ((addr & ~PAGE_MASK) && task_size > VA_EXCLUDE_END) {
46 VM_BUG_ON(addr != -ENOMEM);
47 info.low_limit = VA_EXCLUDE_END;
48 info.high_limit = task_size;
49 addr = vm_unmapped_area(&info);
52 return addr;
55 static unsigned long
56 hugetlb_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
57 const unsigned long len,
58 const unsigned long pgoff,
59 const unsigned long flags)
61 struct hstate *h = hstate_file(filp);
62 struct mm_struct *mm = current->mm;
63 unsigned long addr = addr0;
64 struct vm_unmapped_area_info info = {};
66 /* This should only ever run for 32-bit processes. */
67 BUG_ON(!test_thread_flag(TIF_32BIT));
69 info.flags = VM_UNMAPPED_AREA_TOPDOWN;
70 info.length = len;
71 info.low_limit = PAGE_SIZE;
72 info.high_limit = mm->mmap_base;
73 info.align_mask = PAGE_MASK & ~huge_page_mask(h);
74 addr = vm_unmapped_area(&info);
77 * A failed mmap() very likely causes application failure,
78 * so fall back to the bottom-up function here. This scenario
79 * can happen with large stack limits and large mmap()
80 * allocations.
82 if (addr & ~PAGE_MASK) {
83 VM_BUG_ON(addr != -ENOMEM);
84 info.flags = 0;
85 info.low_limit = TASK_UNMAPPED_BASE;
86 info.high_limit = STACK_TOP32;
87 addr = vm_unmapped_area(&info);
90 return addr;
93 unsigned long
94 hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
95 unsigned long len, unsigned long pgoff, unsigned long flags)
97 struct hstate *h = hstate_file(file);
98 struct mm_struct *mm = current->mm;
99 struct vm_area_struct *vma;
100 unsigned long task_size = TASK_SIZE;
102 if (test_thread_flag(TIF_32BIT))
103 task_size = STACK_TOP32;
105 if (len & ~huge_page_mask(h))
106 return -EINVAL;
107 if (len > task_size)
108 return -ENOMEM;
110 if (flags & MAP_FIXED) {
111 if (prepare_hugepage_range(file, addr, len))
112 return -EINVAL;
113 return addr;
116 if (addr) {
117 addr = ALIGN(addr, huge_page_size(h));
118 vma = find_vma(mm, addr);
119 if (task_size - len >= addr &&
120 (!vma || addr + len <= vm_start_gap(vma)))
121 return addr;
123 if (!test_bit(MMF_TOPDOWN, &mm->flags))
124 return hugetlb_get_unmapped_area_bottomup(file, addr, len,
125 pgoff, flags);
126 else
127 return hugetlb_get_unmapped_area_topdown(file, addr, len,
128 pgoff, flags);
131 static pte_t sun4u_hugepage_shift_to_tte(pte_t entry, unsigned int shift)
133 return entry;
136 static pte_t sun4v_hugepage_shift_to_tte(pte_t entry, unsigned int shift)
138 unsigned long hugepage_size = _PAGE_SZ4MB_4V;
140 pte_val(entry) = pte_val(entry) & ~_PAGE_SZALL_4V;
142 switch (shift) {
143 case HPAGE_16GB_SHIFT:
144 hugepage_size = _PAGE_SZ16GB_4V;
145 pte_val(entry) |= _PAGE_PUD_HUGE;
146 break;
147 case HPAGE_2GB_SHIFT:
148 hugepage_size = _PAGE_SZ2GB_4V;
149 pte_val(entry) |= _PAGE_PMD_HUGE;
150 break;
151 case HPAGE_256MB_SHIFT:
152 hugepage_size = _PAGE_SZ256MB_4V;
153 pte_val(entry) |= _PAGE_PMD_HUGE;
154 break;
155 case HPAGE_SHIFT:
156 pte_val(entry) |= _PAGE_PMD_HUGE;
157 break;
158 case HPAGE_64K_SHIFT:
159 hugepage_size = _PAGE_SZ64K_4V;
160 break;
161 default:
162 WARN_ONCE(1, "unsupported hugepage shift=%u\n", shift);
165 pte_val(entry) = pte_val(entry) | hugepage_size;
166 return entry;
169 static pte_t hugepage_shift_to_tte(pte_t entry, unsigned int shift)
171 if (tlb_type == hypervisor)
172 return sun4v_hugepage_shift_to_tte(entry, shift);
173 else
174 return sun4u_hugepage_shift_to_tte(entry, shift);
177 pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags)
179 pte_t pte;
181 entry = pte_mkhuge(entry);
182 pte = hugepage_shift_to_tte(entry, shift);
184 #ifdef CONFIG_SPARC64
185 /* If this vma has ADI enabled on it, turn on TTE.mcd
187 if (flags & VM_SPARC_ADI)
188 return pte_mkmcd(pte);
189 else
190 return pte_mknotmcd(pte);
191 #else
192 return pte;
193 #endif
196 static unsigned int sun4v_huge_tte_to_shift(pte_t entry)
198 unsigned long tte_szbits = pte_val(entry) & _PAGE_SZALL_4V;
199 unsigned int shift;
201 switch (tte_szbits) {
202 case _PAGE_SZ16GB_4V:
203 shift = HPAGE_16GB_SHIFT;
204 break;
205 case _PAGE_SZ2GB_4V:
206 shift = HPAGE_2GB_SHIFT;
207 break;
208 case _PAGE_SZ256MB_4V:
209 shift = HPAGE_256MB_SHIFT;
210 break;
211 case _PAGE_SZ4MB_4V:
212 shift = REAL_HPAGE_SHIFT;
213 break;
214 case _PAGE_SZ64K_4V:
215 shift = HPAGE_64K_SHIFT;
216 break;
217 default:
218 shift = PAGE_SHIFT;
219 break;
221 return shift;
224 static unsigned int sun4u_huge_tte_to_shift(pte_t entry)
226 unsigned long tte_szbits = pte_val(entry) & _PAGE_SZALL_4U;
227 unsigned int shift;
229 switch (tte_szbits) {
230 case _PAGE_SZ256MB_4U:
231 shift = HPAGE_256MB_SHIFT;
232 break;
233 case _PAGE_SZ4MB_4U:
234 shift = REAL_HPAGE_SHIFT;
235 break;
236 case _PAGE_SZ64K_4U:
237 shift = HPAGE_64K_SHIFT;
238 break;
239 default:
240 shift = PAGE_SHIFT;
241 break;
243 return shift;
246 static unsigned long tte_to_shift(pte_t entry)
248 if (tlb_type == hypervisor)
249 return sun4v_huge_tte_to_shift(entry);
251 return sun4u_huge_tte_to_shift(entry);
254 static unsigned int huge_tte_to_shift(pte_t entry)
256 unsigned long shift = tte_to_shift(entry);
258 if (shift == PAGE_SHIFT)
259 WARN_ONCE(1, "tto_to_shift: invalid hugepage tte=0x%lx\n",
260 pte_val(entry));
262 return shift;
265 static unsigned long huge_tte_to_size(pte_t pte)
267 unsigned long size = 1UL << huge_tte_to_shift(pte);
269 if (size == REAL_HPAGE_SIZE)
270 size = HPAGE_SIZE;
271 return size;
274 unsigned long pud_leaf_size(pud_t pud) { return 1UL << tte_to_shift(*(pte_t *)&pud); }
275 unsigned long pmd_leaf_size(pmd_t pmd) { return 1UL << tte_to_shift(*(pte_t *)&pmd); }
276 unsigned long pte_leaf_size(pte_t pte) { return 1UL << tte_to_shift(pte); }
278 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
279 unsigned long addr, unsigned long sz)
281 pgd_t *pgd;
282 p4d_t *p4d;
283 pud_t *pud;
284 pmd_t *pmd;
286 pgd = pgd_offset(mm, addr);
287 p4d = p4d_offset(pgd, addr);
288 pud = pud_alloc(mm, p4d, addr);
289 if (!pud)
290 return NULL;
291 if (sz >= PUD_SIZE)
292 return (pte_t *)pud;
293 pmd = pmd_alloc(mm, pud, addr);
294 if (!pmd)
295 return NULL;
296 if (sz >= PMD_SIZE)
297 return (pte_t *)pmd;
298 return pte_alloc_huge(mm, pmd, addr);
301 pte_t *huge_pte_offset(struct mm_struct *mm,
302 unsigned long addr, unsigned long sz)
304 pgd_t *pgd;
305 p4d_t *p4d;
306 pud_t *pud;
307 pmd_t *pmd;
309 pgd = pgd_offset(mm, addr);
310 if (pgd_none(*pgd))
311 return NULL;
312 p4d = p4d_offset(pgd, addr);
313 if (p4d_none(*p4d))
314 return NULL;
315 pud = pud_offset(p4d, addr);
316 if (pud_none(*pud))
317 return NULL;
318 if (is_hugetlb_pud(*pud))
319 return (pte_t *)pud;
320 pmd = pmd_offset(pud, addr);
321 if (pmd_none(*pmd))
322 return NULL;
323 if (is_hugetlb_pmd(*pmd))
324 return (pte_t *)pmd;
325 return pte_offset_huge(pmd, addr);
328 void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
329 pte_t *ptep, pte_t entry)
331 unsigned int nptes, orig_shift, shift;
332 unsigned long i, size;
333 pte_t orig;
335 size = huge_tte_to_size(entry);
337 shift = PAGE_SHIFT;
338 if (size >= PUD_SIZE)
339 shift = PUD_SHIFT;
340 else if (size >= PMD_SIZE)
341 shift = PMD_SHIFT;
342 else
343 shift = PAGE_SHIFT;
345 nptes = size >> shift;
347 if (!pte_present(*ptep) && pte_present(entry))
348 mm->context.hugetlb_pte_count += nptes;
350 addr &= ~(size - 1);
351 orig = *ptep;
352 orig_shift = pte_none(orig) ? PAGE_SHIFT : huge_tte_to_shift(orig);
354 for (i = 0; i < nptes; i++)
355 ptep[i] = __pte(pte_val(entry) + (i << shift));
357 maybe_tlb_batch_add(mm, addr, ptep, orig, 0, orig_shift);
358 /* An HPAGE_SIZE'ed page is composed of two REAL_HPAGE_SIZE'ed pages */
359 if (size == HPAGE_SIZE)
360 maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, orig, 0,
361 orig_shift);
364 void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
365 pte_t *ptep, pte_t entry, unsigned long sz)
367 __set_huge_pte_at(mm, addr, ptep, entry);
370 pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
371 pte_t *ptep)
373 unsigned int i, nptes, orig_shift, shift;
374 unsigned long size;
375 pte_t entry;
377 entry = *ptep;
378 size = huge_tte_to_size(entry);
380 shift = PAGE_SHIFT;
381 if (size >= PUD_SIZE)
382 shift = PUD_SHIFT;
383 else if (size >= PMD_SIZE)
384 shift = PMD_SHIFT;
385 else
386 shift = PAGE_SHIFT;
388 nptes = size >> shift;
389 orig_shift = pte_none(entry) ? PAGE_SHIFT : huge_tte_to_shift(entry);
391 if (pte_present(entry))
392 mm->context.hugetlb_pte_count -= nptes;
394 addr &= ~(size - 1);
395 for (i = 0; i < nptes; i++)
396 ptep[i] = __pte(0UL);
398 maybe_tlb_batch_add(mm, addr, ptep, entry, 0, orig_shift);
399 /* An HPAGE_SIZE'ed page is composed of two REAL_HPAGE_SIZE'ed pages */
400 if (size == HPAGE_SIZE)
401 maybe_tlb_batch_add(mm, addr + REAL_HPAGE_SIZE, ptep, entry, 0,
402 orig_shift);
404 return entry;
407 static void hugetlb_free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
408 unsigned long addr)
410 pgtable_t token = pmd_pgtable(*pmd);
412 pmd_clear(pmd);
413 pte_free_tlb(tlb, token, addr);
414 mm_dec_nr_ptes(tlb->mm);
417 static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
418 unsigned long addr, unsigned long end,
419 unsigned long floor, unsigned long ceiling)
421 pmd_t *pmd;
422 unsigned long next;
423 unsigned long start;
425 start = addr;
426 pmd = pmd_offset(pud, addr);
427 do {
428 next = pmd_addr_end(addr, end);
429 if (pmd_none(*pmd))
430 continue;
431 if (is_hugetlb_pmd(*pmd))
432 pmd_clear(pmd);
433 else
434 hugetlb_free_pte_range(tlb, pmd, addr);
435 } while (pmd++, addr = next, addr != end);
437 start &= PUD_MASK;
438 if (start < floor)
439 return;
440 if (ceiling) {
441 ceiling &= PUD_MASK;
442 if (!ceiling)
443 return;
445 if (end - 1 > ceiling - 1)
446 return;
448 pmd = pmd_offset(pud, start);
449 pud_clear(pud);
450 pmd_free_tlb(tlb, pmd, start);
451 mm_dec_nr_pmds(tlb->mm);
454 static void hugetlb_free_pud_range(struct mmu_gather *tlb, p4d_t *p4d,
455 unsigned long addr, unsigned long end,
456 unsigned long floor, unsigned long ceiling)
458 pud_t *pud;
459 unsigned long next;
460 unsigned long start;
462 start = addr;
463 pud = pud_offset(p4d, addr);
464 do {
465 next = pud_addr_end(addr, end);
466 if (pud_none_or_clear_bad(pud))
467 continue;
468 if (is_hugetlb_pud(*pud))
469 pud_clear(pud);
470 else
471 hugetlb_free_pmd_range(tlb, pud, addr, next, floor,
472 ceiling);
473 } while (pud++, addr = next, addr != end);
475 start &= PGDIR_MASK;
476 if (start < floor)
477 return;
478 if (ceiling) {
479 ceiling &= PGDIR_MASK;
480 if (!ceiling)
481 return;
483 if (end - 1 > ceiling - 1)
484 return;
486 pud = pud_offset(p4d, start);
487 p4d_clear(p4d);
488 pud_free_tlb(tlb, pud, start);
489 mm_dec_nr_puds(tlb->mm);
492 void hugetlb_free_pgd_range(struct mmu_gather *tlb,
493 unsigned long addr, unsigned long end,
494 unsigned long floor, unsigned long ceiling)
496 pgd_t *pgd;
497 p4d_t *p4d;
498 unsigned long next;
500 addr &= PMD_MASK;
501 if (addr < floor) {
502 addr += PMD_SIZE;
503 if (!addr)
504 return;
506 if (ceiling) {
507 ceiling &= PMD_MASK;
508 if (!ceiling)
509 return;
511 if (end - 1 > ceiling - 1)
512 end -= PMD_SIZE;
513 if (addr > end - 1)
514 return;
516 pgd = pgd_offset(tlb->mm, addr);
517 p4d = p4d_offset(pgd, addr);
518 do {
519 next = p4d_addr_end(addr, end);
520 if (p4d_none_or_clear_bad(p4d))
521 continue;
522 hugetlb_free_pud_range(tlb, p4d, addr, next, floor, ceiling);
523 } while (p4d++, addr = next, addr != end);