1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2c6557e7fSMartin Schwidefsky /*
3c6557e7fSMartin Schwidefsky * IBM System z Huge TLB Page Support for Kernel.
4c6557e7fSMartin Schwidefsky *
5c6557e7fSMartin Schwidefsky * Copyright IBM Corp. 2008
6c6557e7fSMartin Schwidefsky * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>
7c6557e7fSMartin Schwidefsky */
8c6557e7fSMartin Schwidefsky
9c6557e7fSMartin Schwidefsky #ifndef _ASM_S390_HUGETLB_H
10c6557e7fSMartin Schwidefsky #define _ASM_S390_HUGETLB_H
11c6557e7fSMartin Schwidefsky
12ca5999fdSMike Rapoport #include <linux/pgtable.h>
1365fddcfcSMike Rapoport #include <asm/page.h>
14c6557e7fSMartin Schwidefsky
15c6557e7fSMartin Schwidefsky #define hugetlb_free_pgd_range free_pgd_range
16466178fcSHeiko Carstens #define hugepages_supported() (MACHINE_HAS_EDAT1)
17c6557e7fSMartin Schwidefsky
18c6557e7fSMartin Schwidefsky void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
19935d4f0cSRyan Roberts pte_t *ptep, pte_t pte, unsigned long sz);
20935d4f0cSRyan Roberts void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
21c6557e7fSMartin Schwidefsky pte_t *ptep, pte_t pte);
22e5098611SMartin Schwidefsky pte_t huge_ptep_get(pte_t *ptep);
23*c04035ceSRyan Roberts pte_t __huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
24*c04035ceSRyan Roberts pte_t *ptep);
25*c04035ceSRyan Roberts
huge_ptep_get_and_clear(struct mm_struct * mm,unsigned long addr,pte_t * ptep,unsigned long sz)26*c04035ceSRyan Roberts static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
27*c04035ceSRyan Roberts unsigned long addr, pte_t *ptep,
28*c04035ceSRyan Roberts unsigned long sz)
29*c04035ceSRyan Roberts {
30*c04035ceSRyan Roberts return __huge_ptep_get_and_clear(mm, addr, ptep);
31*c04035ceSRyan Roberts }
32c6557e7fSMartin Schwidefsky
33c6557e7fSMartin Schwidefsky /*
34c6557e7fSMartin Schwidefsky * If the arch doesn't supply something else, assume that hugepage
35c6557e7fSMartin Schwidefsky * size aligned regions are ok without further preparation.
36c6557e7fSMartin Schwidefsky */
prepare_hugepage_range(struct file * file,unsigned long addr,unsigned long len)37c6557e7fSMartin Schwidefsky static inline int prepare_hugepage_range(struct file *file,
38c6557e7fSMartin Schwidefsky unsigned long addr, unsigned long len)
39c6557e7fSMartin Schwidefsky {
407c8d42fdSGerald Schaefer struct hstate *h = hstate_file(file);
417c8d42fdSGerald Schaefer
427c8d42fdSGerald Schaefer if (len & ~huge_page_mask(h))
43c6557e7fSMartin Schwidefsky return -EINVAL;
447c8d42fdSGerald Schaefer if (addr & ~huge_page_mask(h))
45c6557e7fSMartin Schwidefsky return -EINVAL;
46c6557e7fSMartin Schwidefsky return 0;
47c6557e7fSMartin Schwidefsky }
48c6557e7fSMartin Schwidefsky
arch_clear_hugepage_flags(struct page * page)493afdfca6SJanosch Frank static inline void arch_clear_hugepage_flags(struct page *page)
503afdfca6SJanosch Frank {
513afdfca6SJanosch Frank clear_bit(PG_arch_1, &page->flags);
523afdfca6SJanosch Frank }
535be99343SAnshuman Khandual #define arch_clear_hugepage_flags arch_clear_hugepage_flags
54c6557e7fSMartin Schwidefsky
huge_pte_clear(struct mm_struct * mm,unsigned long addr,pte_t * ptep,unsigned long sz)55e5098611SMartin Schwidefsky static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
569386fac3SPunit Agrawal pte_t *ptep, unsigned long sz)
57c6557e7fSMartin Schwidefsky {
58d08de8e2SGerald Schaefer if ((pte_val(*ptep) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
59b8e3b379SHeiko Carstens set_pte(ptep, __pte(_REGION3_ENTRY_EMPTY));
60d08de8e2SGerald Schaefer else
61b8e3b379SHeiko Carstens set_pte(ptep, __pte(_SEGMENT_ENTRY_EMPTY));
62c6557e7fSMartin Schwidefsky }
63c6557e7fSMartin Schwidefsky
huge_ptep_clear_flush(struct vm_area_struct * vma,unsigned long address,pte_t * ptep)64ae075629SBaolin Wang static inline pte_t huge_ptep_clear_flush(struct vm_area_struct *vma,
65c6557e7fSMartin Schwidefsky unsigned long address, pte_t *ptep)
66c6557e7fSMartin Schwidefsky {
67*c04035ceSRyan Roberts return __huge_ptep_get_and_clear(vma->vm_mm, address, ptep);
68e5098611SMartin Schwidefsky }
69e5098611SMartin Schwidefsky
huge_ptep_set_access_flags(struct vm_area_struct * vma,unsigned long addr,pte_t * ptep,pte_t pte,int dirty)70e5098611SMartin Schwidefsky static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
71e5098611SMartin Schwidefsky unsigned long addr, pte_t *ptep,
72e5098611SMartin Schwidefsky pte_t pte, int dirty)
73e5098611SMartin Schwidefsky {
74e5098611SMartin Schwidefsky int changed = !pte_same(huge_ptep_get(ptep), pte);
75e5098611SMartin Schwidefsky if (changed) {
76*c04035ceSRyan Roberts __huge_ptep_get_and_clear(vma->vm_mm, addr, ptep);
77935d4f0cSRyan Roberts __set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
78e5098611SMartin Schwidefsky }
79e5098611SMartin Schwidefsky return changed;
80e5098611SMartin Schwidefsky }
81e5098611SMartin Schwidefsky
huge_ptep_set_wrprotect(struct mm_struct * mm,unsigned long addr,pte_t * ptep)82e5098611SMartin Schwidefsky static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
83e5098611SMartin Schwidefsky unsigned long addr, pte_t *ptep)
84e5098611SMartin Schwidefsky {
85*c04035ceSRyan Roberts pte_t pte = __huge_ptep_get_and_clear(mm, addr, ptep);
86935d4f0cSRyan Roberts __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(pte));
87c6557e7fSMartin Schwidefsky }
88c6557e7fSMartin Schwidefsky
mk_huge_pte(struct page * page,pgprot_t pgprot)89106c992aSGerald Schaefer static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot)
90106c992aSGerald Schaefer {
91e5098611SMartin Schwidefsky return mk_pte(page, pgprot);
92e5098611SMartin Schwidefsky }
93106c992aSGerald Schaefer
huge_pte_none(pte_t pte)94e5098611SMartin Schwidefsky static inline int huge_pte_none(pte_t pte)
95e5098611SMartin Schwidefsky {
96e5098611SMartin Schwidefsky return pte_none(pte);
97106c992aSGerald Schaefer }
98106c992aSGerald Schaefer
huge_pte_none_mostly(pte_t pte)99679d1033SPeter Xu static inline int huge_pte_none_mostly(pte_t pte)
100679d1033SPeter Xu {
101679d1033SPeter Xu return huge_pte_none(pte);
102679d1033SPeter Xu }
103679d1033SPeter Xu
huge_pte_write(pte_t pte)104106c992aSGerald Schaefer static inline int huge_pte_write(pte_t pte)
105106c992aSGerald Schaefer {
106e5098611SMartin Schwidefsky return pte_write(pte);
107106c992aSGerald Schaefer }
108106c992aSGerald Schaefer
huge_pte_dirty(pte_t pte)109106c992aSGerald Schaefer static inline int huge_pte_dirty(pte_t pte)
110106c992aSGerald Schaefer {
111e5098611SMartin Schwidefsky return pte_dirty(pte);
112106c992aSGerald Schaefer }
113106c992aSGerald Schaefer
huge_pte_mkwrite(pte_t pte)114106c992aSGerald Schaefer static inline pte_t huge_pte_mkwrite(pte_t pte)
115106c992aSGerald Schaefer {
1162f0584f3SRick Edgecombe return pte_mkwrite_novma(pte);
117106c992aSGerald Schaefer }
118106c992aSGerald Schaefer
huge_pte_mkdirty(pte_t pte)119106c992aSGerald Schaefer static inline pte_t huge_pte_mkdirty(pte_t pte)
120106c992aSGerald Schaefer {
121e5098611SMartin Schwidefsky return pte_mkdirty(pte);
122e5098611SMartin Schwidefsky }
123e5098611SMartin Schwidefsky
huge_pte_wrprotect(pte_t pte)124e5098611SMartin Schwidefsky static inline pte_t huge_pte_wrprotect(pte_t pte)
125e5098611SMartin Schwidefsky {
126e5098611SMartin Schwidefsky return pte_wrprotect(pte);
127106c992aSGerald Schaefer }
128106c992aSGerald Schaefer
huge_pte_modify(pte_t pte,pgprot_t newprot)129106c992aSGerald Schaefer static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot)
130106c992aSGerald Schaefer {
131e5098611SMartin Schwidefsky return pte_modify(pte, newprot);
132106c992aSGerald Schaefer }
133106c992aSGerald Schaefer
huge_pte_mkuffd_wp(pte_t pte)134229f3fa7SPeter Xu static inline pte_t huge_pte_mkuffd_wp(pte_t pte)
135229f3fa7SPeter Xu {
136229f3fa7SPeter Xu return pte;
137229f3fa7SPeter Xu }
138229f3fa7SPeter Xu
huge_pte_clear_uffd_wp(pte_t pte)139229f3fa7SPeter Xu static inline pte_t huge_pte_clear_uffd_wp(pte_t pte)
140229f3fa7SPeter Xu {
141229f3fa7SPeter Xu return pte;
142229f3fa7SPeter Xu }
143229f3fa7SPeter Xu
huge_pte_uffd_wp(pte_t pte)144229f3fa7SPeter Xu static inline int huge_pte_uffd_wp(pte_t pte)
145229f3fa7SPeter Xu {
146229f3fa7SPeter Xu return 0;
147229f3fa7SPeter Xu }
148229f3fa7SPeter Xu
gigantic_page_runtime_supported(void)1494eb0716eSAlexandre Ghiti static inline bool gigantic_page_runtime_supported(void)
1504eb0716eSAlexandre Ghiti {
1514eb0716eSAlexandre Ghiti return true;
1524eb0716eSAlexandre Ghiti }
1534eb0716eSAlexandre Ghiti
154c6557e7fSMartin Schwidefsky #endif /* _ASM_S390_HUGETLB_H */
155