diff options
Diffstat (limited to 'arch/x86/include/asm/pgtable.h')
-rw-r--r-- | arch/x86/include/asm/pgtable.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 437feb436efa..1cfb36b8c024 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h | |||
@@ -46,6 +46,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); | |||
46 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) | 46 | #define set_pte(ptep, pte) native_set_pte(ptep, pte) |
47 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) | 47 | #define set_pte_at(mm, addr, ptep, pte) native_set_pte_at(mm, addr, ptep, pte) |
48 | #define set_pmd_at(mm, addr, pmdp, pmd) native_set_pmd_at(mm, addr, pmdp, pmd) | 48 | #define set_pmd_at(mm, addr, pmdp, pmd) native_set_pmd_at(mm, addr, pmdp, pmd) |
49 | #define set_pud_at(mm, addr, pudp, pud) native_set_pud_at(mm, addr, pudp, pud) | ||
49 | 50 | ||
50 | #define set_pte_atomic(ptep, pte) \ | 51 | #define set_pte_atomic(ptep, pte) \ |
51 | native_set_pte_atomic(ptep, pte) | 52 | native_set_pte_atomic(ptep, pte) |
@@ -128,6 +129,16 @@ static inline int pmd_young(pmd_t pmd) | |||
128 | return pmd_flags(pmd) & _PAGE_ACCESSED; | 129 | return pmd_flags(pmd) & _PAGE_ACCESSED; |
129 | } | 130 | } |
130 | 131 | ||
132 | static inline int pud_dirty(pud_t pud) | ||
133 | { | ||
134 | return pud_flags(pud) & _PAGE_DIRTY; | ||
135 | } | ||
136 | |||
137 | static inline int pud_young(pud_t pud) | ||
138 | { | ||
139 | return pud_flags(pud) & _PAGE_ACCESSED; | ||
140 | } | ||
141 | |||
131 | static inline int pte_write(pte_t pte) | 142 | static inline int pte_write(pte_t pte) |
132 | { | 143 | { |
133 | return pte_flags(pte) & _PAGE_RW; | 144 | return pte_flags(pte) & _PAGE_RW; |
@@ -181,6 +192,13 @@ static inline int pmd_trans_huge(pmd_t pmd) | |||
181 | return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE; | 192 | return (pmd_val(pmd) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE; |
182 | } | 193 | } |
183 | 194 | ||
195 | #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD | ||
196 | static inline int pud_trans_huge(pud_t pud) | ||
197 | { | ||
198 | return (pud_val(pud) & (_PAGE_PSE|_PAGE_DEVMAP)) == _PAGE_PSE; | ||
199 | } | ||
200 | #endif | ||
201 | |||
184 | #define has_transparent_hugepage has_transparent_hugepage | 202 | #define has_transparent_hugepage has_transparent_hugepage |
185 | static inline int has_transparent_hugepage(void) | 203 | static inline int has_transparent_hugepage(void) |
186 | { | 204 | { |
@@ -192,6 +210,18 @@ static inline int pmd_devmap(pmd_t pmd) | |||
192 | { | 210 | { |
193 | return !!(pmd_val(pmd) & _PAGE_DEVMAP); | 211 | return !!(pmd_val(pmd) & _PAGE_DEVMAP); |
194 | } | 212 | } |
213 | |||
214 | #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD | ||
215 | static inline int pud_devmap(pud_t pud) | ||
216 | { | ||
217 | return !!(pud_val(pud) & _PAGE_DEVMAP); | ||
218 | } | ||
219 | #else | ||
220 | static inline int pud_devmap(pud_t pud) | ||
221 | { | ||
222 | return 0; | ||
223 | } | ||
224 | #endif | ||
195 | #endif | 225 | #endif |
196 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 226 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
197 | 227 | ||
@@ -333,6 +363,65 @@ static inline pmd_t pmd_mknotpresent(pmd_t pmd) | |||
333 | return pmd_clear_flags(pmd, _PAGE_PRESENT | _PAGE_PROTNONE); | 363 | return pmd_clear_flags(pmd, _PAGE_PRESENT | _PAGE_PROTNONE); |
334 | } | 364 | } |
335 | 365 | ||
366 | static inline pud_t pud_set_flags(pud_t pud, pudval_t set) | ||
367 | { | ||
368 | pudval_t v = native_pud_val(pud); | ||
369 | |||
370 | return __pud(v | set); | ||
371 | } | ||
372 | |||
373 | static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear) | ||
374 | { | ||
375 | pudval_t v = native_pud_val(pud); | ||
376 | |||
377 | return __pud(v & ~clear); | ||
378 | } | ||
379 | |||
380 | static inline pud_t pud_mkold(pud_t pud) | ||
381 | { | ||
382 | return pud_clear_flags(pud, _PAGE_ACCESSED); | ||
383 | } | ||
384 | |||
385 | static inline pud_t pud_mkclean(pud_t pud) | ||
386 | { | ||
387 | return pud_clear_flags(pud, _PAGE_DIRTY); | ||
388 | } | ||
389 | |||
390 | static inline pud_t pud_wrprotect(pud_t pud) | ||
391 | { | ||
392 | return pud_clear_flags(pud, _PAGE_RW); | ||
393 | } | ||
394 | |||
395 | static inline pud_t pud_mkdirty(pud_t pud) | ||
396 | { | ||
397 | return pud_set_flags(pud, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); | ||
398 | } | ||
399 | |||
400 | static inline pud_t pud_mkdevmap(pud_t pud) | ||
401 | { | ||
402 | return pud_set_flags(pud, _PAGE_DEVMAP); | ||
403 | } | ||
404 | |||
405 | static inline pud_t pud_mkhuge(pud_t pud) | ||
406 | { | ||
407 | return pud_set_flags(pud, _PAGE_PSE); | ||
408 | } | ||
409 | |||
410 | static inline pud_t pud_mkyoung(pud_t pud) | ||
411 | { | ||
412 | return pud_set_flags(pud, _PAGE_ACCESSED); | ||
413 | } | ||
414 | |||
415 | static inline pud_t pud_mkwrite(pud_t pud) | ||
416 | { | ||
417 | return pud_set_flags(pud, _PAGE_RW); | ||
418 | } | ||
419 | |||
420 | static inline pud_t pud_mknotpresent(pud_t pud) | ||
421 | { | ||
422 | return pud_clear_flags(pud, _PAGE_PRESENT | _PAGE_PROTNONE); | ||
423 | } | ||
424 | |||
336 | #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY | 425 | #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY |
337 | static inline int pte_soft_dirty(pte_t pte) | 426 | static inline int pte_soft_dirty(pte_t pte) |
338 | { | 427 | { |
@@ -344,6 +433,11 @@ static inline int pmd_soft_dirty(pmd_t pmd) | |||
344 | return pmd_flags(pmd) & _PAGE_SOFT_DIRTY; | 433 | return pmd_flags(pmd) & _PAGE_SOFT_DIRTY; |
345 | } | 434 | } |
346 | 435 | ||
436 | static inline int pud_soft_dirty(pud_t pud) | ||
437 | { | ||
438 | return pud_flags(pud) & _PAGE_SOFT_DIRTY; | ||
439 | } | ||
440 | |||
347 | static inline pte_t pte_mksoft_dirty(pte_t pte) | 441 | static inline pte_t pte_mksoft_dirty(pte_t pte) |
348 | { | 442 | { |
349 | return pte_set_flags(pte, _PAGE_SOFT_DIRTY); | 443 | return pte_set_flags(pte, _PAGE_SOFT_DIRTY); |
@@ -354,6 +448,11 @@ static inline pmd_t pmd_mksoft_dirty(pmd_t pmd) | |||
354 | return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY); | 448 | return pmd_set_flags(pmd, _PAGE_SOFT_DIRTY); |
355 | } | 449 | } |
356 | 450 | ||
451 | static inline pud_t pud_mksoft_dirty(pud_t pud) | ||
452 | { | ||
453 | return pud_set_flags(pud, _PAGE_SOFT_DIRTY); | ||
454 | } | ||
455 | |||
357 | static inline pte_t pte_clear_soft_dirty(pte_t pte) | 456 | static inline pte_t pte_clear_soft_dirty(pte_t pte) |
358 | { | 457 | { |
359 | return pte_clear_flags(pte, _PAGE_SOFT_DIRTY); | 458 | return pte_clear_flags(pte, _PAGE_SOFT_DIRTY); |
@@ -364,6 +463,11 @@ static inline pmd_t pmd_clear_soft_dirty(pmd_t pmd) | |||
364 | return pmd_clear_flags(pmd, _PAGE_SOFT_DIRTY); | 463 | return pmd_clear_flags(pmd, _PAGE_SOFT_DIRTY); |
365 | } | 464 | } |
366 | 465 | ||
466 | static inline pud_t pud_clear_soft_dirty(pud_t pud) | ||
467 | { | ||
468 | return pud_clear_flags(pud, _PAGE_SOFT_DIRTY); | ||
469 | } | ||
470 | |||
367 | #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ | 471 | #endif /* CONFIG_HAVE_ARCH_SOFT_DIRTY */ |
368 | 472 | ||
369 | /* | 473 | /* |
@@ -392,6 +496,12 @@ static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) | |||
392 | massage_pgprot(pgprot)); | 496 | massage_pgprot(pgprot)); |
393 | } | 497 | } |
394 | 498 | ||
499 | static inline pud_t pfn_pud(unsigned long page_nr, pgprot_t pgprot) | ||
500 | { | ||
501 | return __pud(((phys_addr_t)page_nr << PAGE_SHIFT) | | ||
502 | massage_pgprot(pgprot)); | ||
503 | } | ||
504 | |||
395 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 505 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
396 | { | 506 | { |
397 | pteval_t val = pte_val(pte); | 507 | pteval_t val = pte_val(pte); |
@@ -771,6 +881,14 @@ static inline pmd_t native_local_pmdp_get_and_clear(pmd_t *pmdp) | |||
771 | return res; | 881 | return res; |
772 | } | 882 | } |
773 | 883 | ||
884 | static inline pud_t native_local_pudp_get_and_clear(pud_t *pudp) | ||
885 | { | ||
886 | pud_t res = *pudp; | ||
887 | |||
888 | native_pud_clear(pudp); | ||
889 | return res; | ||
890 | } | ||
891 | |||
774 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, | 892 | static inline void native_set_pte_at(struct mm_struct *mm, unsigned long addr, |
775 | pte_t *ptep , pte_t pte) | 893 | pte_t *ptep , pte_t pte) |
776 | { | 894 | { |
@@ -783,6 +901,12 @@ static inline void native_set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
783 | native_set_pmd(pmdp, pmd); | 901 | native_set_pmd(pmdp, pmd); |
784 | } | 902 | } |
785 | 903 | ||
904 | static inline void native_set_pud_at(struct mm_struct *mm, unsigned long addr, | ||
905 | pud_t *pudp, pud_t pud) | ||
906 | { | ||
907 | native_set_pud(pudp, pud); | ||
908 | } | ||
909 | |||
786 | #ifndef CONFIG_PARAVIRT | 910 | #ifndef CONFIG_PARAVIRT |
787 | /* | 911 | /* |
788 | * Rules for using pte_update - it must be called after any PTE update which | 912 | * Rules for using pte_update - it must be called after any PTE update which |
@@ -861,10 +985,15 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, | |||
861 | extern int pmdp_set_access_flags(struct vm_area_struct *vma, | 985 | extern int pmdp_set_access_flags(struct vm_area_struct *vma, |
862 | unsigned long address, pmd_t *pmdp, | 986 | unsigned long address, pmd_t *pmdp, |
863 | pmd_t entry, int dirty); | 987 | pmd_t entry, int dirty); |
988 | extern int pudp_set_access_flags(struct vm_area_struct *vma, | ||
989 | unsigned long address, pud_t *pudp, | ||
990 | pud_t entry, int dirty); | ||
864 | 991 | ||
865 | #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG | 992 | #define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG |
866 | extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, | 993 | extern int pmdp_test_and_clear_young(struct vm_area_struct *vma, |
867 | unsigned long addr, pmd_t *pmdp); | 994 | unsigned long addr, pmd_t *pmdp); |
995 | extern int pudp_test_and_clear_young(struct vm_area_struct *vma, | ||
996 | unsigned long addr, pud_t *pudp); | ||
868 | 997 | ||
869 | #define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH | 998 | #define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH |
870 | extern int pmdp_clear_flush_young(struct vm_area_struct *vma, | 999 | extern int pmdp_clear_flush_young(struct vm_area_struct *vma, |
@@ -884,6 +1013,13 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm, unsigned long | |||
884 | return native_pmdp_get_and_clear(pmdp); | 1013 | return native_pmdp_get_and_clear(pmdp); |
885 | } | 1014 | } |
886 | 1015 | ||
1016 | #define __HAVE_ARCH_PUDP_HUGE_GET_AND_CLEAR | ||
1017 | static inline pud_t pudp_huge_get_and_clear(struct mm_struct *mm, | ||
1018 | unsigned long addr, pud_t *pudp) | ||
1019 | { | ||
1020 | return native_pudp_get_and_clear(pudp); | ||
1021 | } | ||
1022 | |||
887 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT | 1023 | #define __HAVE_ARCH_PMDP_SET_WRPROTECT |
888 | static inline void pmdp_set_wrprotect(struct mm_struct *mm, | 1024 | static inline void pmdp_set_wrprotect(struct mm_struct *mm, |
889 | unsigned long addr, pmd_t *pmdp) | 1025 | unsigned long addr, pmd_t *pmdp) |
@@ -932,6 +1068,10 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | |||
932 | unsigned long addr, pmd_t *pmd) | 1068 | unsigned long addr, pmd_t *pmd) |
933 | { | 1069 | { |
934 | } | 1070 | } |
1071 | static inline void update_mmu_cache_pud(struct vm_area_struct *vma, | ||
1072 | unsigned long addr, pud_t *pud) | ||
1073 | { | ||
1074 | } | ||
935 | 1075 | ||
936 | #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY | 1076 | #ifdef CONFIG_HAVE_ARCH_SOFT_DIRTY |
937 | static inline pte_t pte_swp_mksoft_dirty(pte_t pte) | 1077 | static inline pte_t pte_swp_mksoft_dirty(pte_t pte) |