]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/blame - arch/powerpc/mm/hugetlbpage-radix.c
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[mirror_ubuntu-disco-kernel.git] / arch / powerpc / mm / hugetlbpage-radix.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
48483760
AK
2#include <linux/mm.h>
3#include <linux/hugetlb.h>
4#include <asm/pgtable.h>
5#include <asm/pgalloc.h>
6#include <asm/cacheflush.h>
7#include <asm/machdep.h>
8#include <asm/mman.h>
fbfa26d8 9#include <asm/tlb.h>
48483760
AK
10
11void radix__flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
12{
fbfa26d8 13 int psize;
48483760
AK
14 struct hstate *hstate = hstate_file(vma->vm_file);
15
fbfa26d8
AK
16 psize = hstate_get_psize(hstate);
17 radix__flush_tlb_page_psize(vma->vm_mm, vmaddr, psize);
48483760
AK
18}
19
20void radix__local_flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
21{
fbfa26d8 22 int psize;
48483760
AK
23 struct hstate *hstate = hstate_file(vma->vm_file);
24
fbfa26d8
AK
25 psize = hstate_get_psize(hstate);
26 radix__local_flush_tlb_page_psize(vma->vm_mm, vmaddr, psize);
48483760
AK
27}
28
5491ae7b
AK
29void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma, unsigned long start,
30 unsigned long end)
31{
32 int psize;
33 struct hstate *hstate = hstate_file(vma->vm_file);
34
35 psize = hstate_get_psize(hstate);
36 radix__flush_tlb_range_psize(vma->vm_mm, start, end, psize);
37}
38
48483760
AK
39/*
40 * A vairant of hugetlb_get_unmapped_area doing topdown search
41 * FIXME!! should we do as x86 does or non hugetlb area does ?
42 * ie, use topdown or not based on mmap_is_legacy check ?
43 */
44unsigned long
45radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
46 unsigned long len, unsigned long pgoff,
47 unsigned long flags)
48{
49 struct mm_struct *mm = current->mm;
50 struct vm_area_struct *vma;
51 struct hstate *h = hstate_file(file);
52 struct vm_unmapped_area_info info;
53
f4ea6dcb
AK
54 if (unlikely(addr > mm->context.addr_limit && addr < TASK_SIZE))
55 mm->context.addr_limit = TASK_SIZE;
56
48483760
AK
57 if (len & ~huge_page_mask(h))
58 return -EINVAL;
be77e999 59 if (len > mm->task_size)
48483760
AK
60 return -ENOMEM;
61
62 if (flags & MAP_FIXED) {
63 if (prepare_hugepage_range(file, addr, len))
64 return -EINVAL;
65 return addr;
66 }
67
68 if (addr) {
69 addr = ALIGN(addr, huge_page_size(h));
70 vma = find_vma(mm, addr);
be77e999 71 if (mm->task_size - len >= addr &&
1be7107f 72 (!vma || addr + len <= vm_start_gap(vma)))
48483760
AK
73 return addr;
74 }
75 /*
76 * We are always doing an topdown search here. Slice code
77 * does that too.
78 */
79 info.flags = VM_UNMAPPED_AREA_TOPDOWN;
80 info.length = len;
81 info.low_limit = PAGE_SIZE;
82 info.high_limit = current->mm->mmap_base;
83 info.align_mask = PAGE_MASK & ~huge_page_mask(h);
84 info.align_offset = 0;
f4ea6dcb
AK
85
86 if (addr > DEFAULT_MAP_WINDOW)
87 info.high_limit += mm->context.addr_limit - DEFAULT_MAP_WINDOW;
88
48483760
AK
89 return vm_unmapped_area(&info);
90}