diff options
Diffstat (limited to 'include/asm-generic/pgtable.h')
-rw-r--r-- | include/asm-generic/pgtable.h | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index f4ca23b158b3..1fad160f35de 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h | |||
@@ -10,9 +10,9 @@ | |||
10 | #include <linux/bug.h> | 10 | #include <linux/bug.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | 12 | ||
13 | #if 4 - defined(__PAGETABLE_PUD_FOLDED) - defined(__PAGETABLE_PMD_FOLDED) != \ | 13 | #if 5 - defined(__PAGETABLE_P4D_FOLDED) - defined(__PAGETABLE_PUD_FOLDED) - \ |
14 | CONFIG_PGTABLE_LEVELS | 14 | defined(__PAGETABLE_PMD_FOLDED) != CONFIG_PGTABLE_LEVELS |
15 | #error CONFIG_PGTABLE_LEVELS is not consistent with __PAGETABLE_{PUD,PMD}_FOLDED | 15 | #error CONFIG_PGTABLE_LEVELS is not consistent with __PAGETABLE_{P4D,PUD,PMD}_FOLDED |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /* | 18 | /* |
@@ -424,6 +424,13 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | |||
424 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ | 424 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ |
425 | }) | 425 | }) |
426 | 426 | ||
427 | #ifndef p4d_addr_end | ||
428 | #define p4d_addr_end(addr, end) \ | ||
429 | ({ unsigned long __boundary = ((addr) + P4D_SIZE) & P4D_MASK; \ | ||
430 | (__boundary - 1 < (end) - 1)? __boundary: (end); \ | ||
431 | }) | ||
432 | #endif | ||
433 | |||
427 | #ifndef pud_addr_end | 434 | #ifndef pud_addr_end |
428 | #define pud_addr_end(addr, end) \ | 435 | #define pud_addr_end(addr, end) \ |
429 | ({ unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK; \ | 436 | ({ unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK; \ |
@@ -444,6 +451,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) | |||
444 | * Do the tests inline, but report and clear the bad entry in mm/memory.c. | 451 | * Do the tests inline, but report and clear the bad entry in mm/memory.c. |
445 | */ | 452 | */ |
446 | void pgd_clear_bad(pgd_t *); | 453 | void pgd_clear_bad(pgd_t *); |
454 | void p4d_clear_bad(p4d_t *); | ||
447 | void pud_clear_bad(pud_t *); | 455 | void pud_clear_bad(pud_t *); |
448 | void pmd_clear_bad(pmd_t *); | 456 | void pmd_clear_bad(pmd_t *); |
449 | 457 | ||
@@ -458,6 +466,17 @@ static inline int pgd_none_or_clear_bad(pgd_t *pgd) | |||
458 | return 0; | 466 | return 0; |
459 | } | 467 | } |
460 | 468 | ||
469 | static inline int p4d_none_or_clear_bad(p4d_t *p4d) | ||
470 | { | ||
471 | if (p4d_none(*p4d)) | ||
472 | return 1; | ||
473 | if (unlikely(p4d_bad(*p4d))) { | ||
474 | p4d_clear_bad(p4d); | ||
475 | return 1; | ||
476 | } | ||
477 | return 0; | ||
478 | } | ||
479 | |||
461 | static inline int pud_none_or_clear_bad(pud_t *pud) | 480 | static inline int pud_none_or_clear_bad(pud_t *pud) |
462 | { | 481 | { |
463 | if (pud_none(*pud)) | 482 | if (pud_none(*pud)) |
@@ -844,11 +863,30 @@ static inline int pmd_protnone(pmd_t pmd) | |||
844 | #endif /* CONFIG_MMU */ | 863 | #endif /* CONFIG_MMU */ |
845 | 864 | ||
846 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP | 865 | #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP |
866 | |||
867 | #ifndef __PAGETABLE_P4D_FOLDED | ||
868 | int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot); | ||
869 | int p4d_clear_huge(p4d_t *p4d); | ||
870 | #else | ||
871 | static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) | ||
872 | { | ||
873 | return 0; | ||
874 | } | ||
875 | static inline int p4d_clear_huge(p4d_t *p4d) | ||
876 | { | ||
877 | return 0; | ||
878 | } | ||
879 | #endif /* !__PAGETABLE_P4D_FOLDED */ | ||
880 | |||
847 | int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot); | 881 | int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot); |
848 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); | 882 | int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot); |
849 | int pud_clear_huge(pud_t *pud); | 883 | int pud_clear_huge(pud_t *pud); |
850 | int pmd_clear_huge(pmd_t *pmd); | 884 | int pmd_clear_huge(pmd_t *pmd); |
851 | #else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */ | 885 | #else /* !CONFIG_HAVE_ARCH_HUGE_VMAP */ |
886 | static inline int p4d_set_huge(p4d_t *p4d, phys_addr_t addr, pgprot_t prot) | ||
887 | { | ||
888 | return 0; | ||
889 | } | ||
852 | static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) | 890 | static inline int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) |
853 | { | 891 | { |
854 | return 0; | 892 | return 0; |
@@ -857,6 +895,10 @@ static inline int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) | |||
857 | { | 895 | { |
858 | return 0; | 896 | return 0; |
859 | } | 897 | } |
898 | static inline int p4d_clear_huge(p4d_t *p4d) | ||
899 | { | ||
900 | return 0; | ||
901 | } | ||
860 | static inline int pud_clear_huge(pud_t *pud) | 902 | static inline int pud_clear_huge(pud_t *pud) |
861 | { | 903 | { |
862 | return 0; | 904 | return 0; |