diff options
author | Johannes Weiner <hannes@cmpxchg.org> | 2011-01-13 18:47:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 20:32:44 -0500 |
commit | f2d6bfe9ff0acec30b713614260e78b03d20e909 (patch) | |
tree | 835dd9f4167513d94ae542cf92347ea98bff5ddc /arch/x86/include/asm/pgtable.h | |
parent | 5f24ce5fd34c3ca1b3d10d30da754732da64d5c0 (diff) |
thp: add x86 32bit support
Add support for transparent hugepages to x86 32bit.
Share the same VM_ bitflag for VM_MAPPED_COPY. mm/nommu.c will never
support transparent hugepages.
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
Reviewed-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/x86/include/asm/pgtable.h')
-rw-r--r-- | arch/x86/include/asm/pgtable.h | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 3278038e9706..001a3831567a 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -97,6 +97,11 @@ static inline int pte_young(pte_t pte) | |||
97 | return pte_flags(pte) & _PAGE_ACCESSED; | 97 | return pte_flags(pte) & _PAGE_ACCESSED; |
98 | } | 98 | } |
99 | 99 | ||
100 | static inline int pmd_young(pmd_t pmd) | ||
101 | { | ||
102 | return pmd_flags(pmd) & _PAGE_ACCESSED; | ||
103 | } | ||
104 | |||
100 | static inline int pte_write(pte_t pte) | 105 | static inline int pte_write(pte_t pte) |
101 | { | 106 | { |
102 | return pte_flags(pte) & _PAGE_RW; | 107 | return pte_flags(pte) & _PAGE_RW; |
@@ -145,6 +150,18 @@ static inline int pmd_large(pmd_t pte) | |||
145 | (_PAGE_PSE | _PAGE_PRESENT); | 150 | (_PAGE_PSE | _PAGE_PRESENT); |
146 | } | 151 | } |
147 | 152 | ||
153 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
154 | static inline int pmd_trans_splitting(pmd_t pmd) | ||
155 | { | ||
156 | return pmd_val(pmd) & _PAGE_SPLITTING; | ||
157 | } | ||
158 | |||
159 | static inline int pmd_trans_huge(pmd_t pmd) | ||
160 | { | ||
161 | return pmd_val(pmd) & _PAGE_PSE; | ||
162 | } | ||
163 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | ||
164 | |||
148 | static inline pte_t pte_set_flags(pte_t pte, pteval_t set) | 165 | static inline pte_t pte_set_flags(pte_t pte, pteval_t set) |
149 | { | 166 | { |
150 | pteval_t v = native_pte_val(pte); | 167 | pteval_t v = native_pte_val(pte); |
@@ -219,6 +236,55 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
219 | return pte_set_flags(pte, _PAGE_SPECIAL); | 236 | return pte_set_flags(pte, _PAGE_SPECIAL); |
220 | } | 237 | } |
221 | 238 | ||
239 | static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set) | ||
240 | { | ||
241 | pmdval_t v = native_pmd_val(pmd); | ||
242 | |||
243 | return __pmd(v | set); | ||
244 | } | ||
245 | |||
246 | static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear) | ||
247 | { | ||
248 | pmdval_t v = native_pmd_val(pmd); | ||
249 | |||
250 | return __pmd(v & ~clear); | ||
251 | } | ||
252 | |||
253 | static inline pmd_t pmd_mkold(pmd_t pmd) | ||
254 | { | ||
255 | return pmd_clear_flags(pmd, _PAGE_ACCESSED); | ||
256 | } | ||
257 | |||
258 | static inline pmd_t pmd_wrprotect(pmd_t pmd) | ||
259 | { | ||
260 | return pmd_clear_flags(pmd, _PAGE_RW); | ||
261 | } | ||
262 | |||
263 | static inline pmd_t pmd_mkdirty(pmd_t pmd) | ||
264 | { | ||
265 | return pmd_set_flags(pmd, _PAGE_DIRTY); | ||
266 | } | ||
267 | |||
268 | static inline pmd_t pmd_mkhuge(pmd_t pmd) | ||
269 | { | ||
270 | return pmd_set_flags(pmd, _PAGE_PSE); | ||
271 | } | ||
272 | |||
273 | static inline pmd_t pmd_mkyoung(pmd_t pmd) | ||
274 | { | ||
275 | return pmd_set_flags(pmd, _PAGE_ACCESSED); | ||
276 | } | ||
277 | |||
278 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | ||
279 | { | ||
280 | return pmd_set_flags(pmd, _PAGE_RW); | ||
281 | } | ||
282 | |||
283 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | ||
284 | { | ||
285 | return pmd_clear_flags(pmd, _PAGE_PRESENT); | ||
286 | } | ||
287 | |||
222 | /* | 288 | /* |
223 | * Mask out unsupported bits in a present pgprot. Non-present pgprots | 289 | * Mask out unsupported bits in a present pgprot. Non-present pgprots |
224 | * can use those bits for other purposes, so leave them be. | 290 | * can use those bits for other purposes, so leave them be. |
@@ -527,6 +593,14 @@ static inline pte_t native_local_ptep_get_and_clear(pte_t *ptep) | |||
527 | return res; | 593 | return res; |
528 | } | 594 | } |
529 | 595 | ||
596 | static inline pmd_t native_local_pmdp_get_and_clear(pmd_t *pmdp) | ||
597 | { | ||
598 | pmd_t res = *pmdp; | ||
599 | |||
600 | native_pmd_clear(pmdp); | ||
601 | return res; | ||
602 | } | ||
603 | |||
530 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, | 604 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, |
531 | pte_t *ptep , pte_t pte) | 605 | pte_t *ptep , pte_t pte) |
532 | { | 606 | { |
@@ -616,6 +690,49 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, | |||
616 | 690 | ||
617 | #define flush_tlb_fix_spurious_fault(vma, address) | 691 | #define flush_tlb_fix_spurious_fault(vma, address) |
618 | 692 | ||
693 | #define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot)) | ||
694 | |||
695 | #define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS | ||
696 | extern int pmdp_set_access_flags(struct vm_area_struct *vma, | ||
697 | unsigned long address, pmd_t *pmdp, | ||
698 | pmd_t entry, int dirty); | ||
699 | |||
700 | #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG | ||
701 | extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, | ||
702 | unsigned long addr, pmd_t *pmdp); | ||
703 | |||
704 | #define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH | ||
705 | extern int pmdp_clear_flush_young(struct vm_area_struct *vma, | ||
706 | unsigned long address, pmd_t *pmdp); | ||
707 | |||
708 | |||
709 | #define __HAVE_ARCH_PMDP_SPLITTING_FLUSH | ||
710 | extern void pmdp_splitting_flush(struct vm_area_struct *vma, | ||
711 | unsigned long addr, pmd_t *pmdp); | ||
712 | |||
713 | #define __HAVE_ARCH_PMD_WRITE | ||
714 | static inline int pmd_write(pmd_t pmd) | ||
715 | { | ||
716 | return pmd_flags(pmd) & _PAGE_RW; | ||
717 | } | ||
718 | |||
719 | #define __HAVE_ARCH_PMDP_GET_AND_CLEAR | ||
720 | static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm, unsigned long addr, | ||
721 | pmd_t *pmdp) | ||
722 | { | ||
723 | pmd_t pmd = native_pmdp_get_and_clear(pmdp); | ||
724 | pmd_update(mm, addr, pmdp); | ||
725 | return pmd; | ||
726 | } | ||
727 | |||
728 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT | ||
729 | static inline void pmdp_set_wrprotect(struct mm_struct *mm, | ||
730 | unsigned long addr, pmd_t *pmdp) | ||
731 | { | ||
732 | clear_bit(_PAGE_BIT_RW, (unsigned long *)pmdp); | ||
733 | pmd_update(mm, addr, pmdp); | ||
734 | } | ||
735 | |||
619 | /* | 736 | /* |
620 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); | 737 | * clone_pgd_range(pgd_t *dst, pgd_t *src, int count); |
621 | * | 738 | * |