diff options
Diffstat (limited to 'include/asm-s390/pgtable.h')
-rw-r--r-- | include/asm-s390/pgtable.h | 123 |
1 files changed, 62 insertions, 61 deletions
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index f9f59a805e5d..f2cc25b74adf 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h | |||
@@ -13,8 +13,6 @@ | |||
13 | #ifndef _ASM_S390_PGTABLE_H | 13 | #ifndef _ASM_S390_PGTABLE_H |
14 | #define _ASM_S390_PGTABLE_H | 14 | #define _ASM_S390_PGTABLE_H |
15 | 15 | ||
16 | #include <asm-generic/4level-fixup.h> | ||
17 | |||
18 | /* | 16 | /* |
19 | * The Linux memory management assumes a three-level page table setup. For | 17 | * The Linux memory management assumes a three-level page table setup. For |
20 | * s390 31 bit we "fold" the mid level into the top-level page table, so | 18 | * s390 31 bit we "fold" the mid level into the top-level page table, so |
@@ -60,14 +58,18 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
60 | */ | 58 | */ |
61 | #ifndef __s390x__ | 59 | #ifndef __s390x__ |
62 | # define PMD_SHIFT 22 | 60 | # define PMD_SHIFT 22 |
61 | # define PUD_SHIFT 22 | ||
63 | # define PGDIR_SHIFT 22 | 62 | # define PGDIR_SHIFT 22 |
64 | #else /* __s390x__ */ | 63 | #else /* __s390x__ */ |
65 | # define PMD_SHIFT 21 | 64 | # define PMD_SHIFT 21 |
65 | # define PUD_SHIFT 31 | ||
66 | # define PGDIR_SHIFT 31 | 66 | # define PGDIR_SHIFT 31 |
67 | #endif /* __s390x__ */ | 67 | #endif /* __s390x__ */ |
68 | 68 | ||
69 | #define PMD_SIZE (1UL << PMD_SHIFT) | 69 | #define PMD_SIZE (1UL << PMD_SHIFT) |
70 | #define PMD_MASK (~(PMD_SIZE-1)) | 70 | #define PMD_MASK (~(PMD_SIZE-1)) |
71 | #define PUD_SIZE (1UL << PUD_SHIFT) | ||
72 | #define PUD_MASK (~(PUD_SIZE-1)) | ||
71 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | 73 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) |
72 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 74 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
73 | 75 | ||
@@ -80,10 +82,12 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
80 | #ifndef __s390x__ | 82 | #ifndef __s390x__ |
81 | # define PTRS_PER_PTE 1024 | 83 | # define PTRS_PER_PTE 1024 |
82 | # define PTRS_PER_PMD 1 | 84 | # define PTRS_PER_PMD 1 |
85 | # define PTRS_PER_PUD 1 | ||
83 | # define PTRS_PER_PGD 512 | 86 | # define PTRS_PER_PGD 512 |
84 | #else /* __s390x__ */ | 87 | #else /* __s390x__ */ |
85 | # define PTRS_PER_PTE 512 | 88 | # define PTRS_PER_PTE 512 |
86 | # define PTRS_PER_PMD 1024 | 89 | # define PTRS_PER_PMD 1024 |
90 | # define PTRS_PER_PUD 1 | ||
87 | # define PTRS_PER_PGD 2048 | 91 | # define PTRS_PER_PGD 2048 |
88 | #endif /* __s390x__ */ | 92 | #endif /* __s390x__ */ |
89 | 93 | ||
@@ -93,6 +97,8 @@ extern char empty_zero_page[PAGE_SIZE]; | |||
93 | printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e)) | 97 | printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e)) |
94 | #define pmd_ERROR(e) \ | 98 | #define pmd_ERROR(e) \ |
95 | printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) | 99 | printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) |
100 | #define pud_ERROR(e) \ | ||
101 | printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e)) | ||
96 | #define pgd_ERROR(e) \ | 102 | #define pgd_ERROR(e) \ |
97 | printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) | 103 | printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) |
98 | 104 | ||
@@ -192,7 +198,7 @@ extern unsigned long vmalloc_end; | |||
192 | * I Segment-Invalid Bit: Segment is not available for address-translation | 198 | * I Segment-Invalid Bit: Segment is not available for address-translation |
193 | * TT Type 01 | 199 | * TT Type 01 |
194 | * TF | 200 | * TF |
195 | * TL Table lenght | 201 | * TL Table length |
196 | * | 202 | * |
197 | * The 64 bit regiontable origin of S390 has following format: | 203 | * The 64 bit regiontable origin of S390 has following format: |
198 | * | region table origon | DTTL | 204 | * | region table origon | DTTL |
@@ -435,22 +441,30 @@ static inline int pgd_present(pgd_t pgd) { return 1; } | |||
435 | static inline int pgd_none(pgd_t pgd) { return 0; } | 441 | static inline int pgd_none(pgd_t pgd) { return 0; } |
436 | static inline int pgd_bad(pgd_t pgd) { return 0; } | 442 | static inline int pgd_bad(pgd_t pgd) { return 0; } |
437 | 443 | ||
444 | static inline int pud_present(pud_t pud) { return 1; } | ||
445 | static inline int pud_none(pud_t pud) { return 0; } | ||
446 | static inline int pud_bad(pud_t pud) { return 0; } | ||
447 | |||
438 | #else /* __s390x__ */ | 448 | #else /* __s390x__ */ |
439 | 449 | ||
440 | static inline int pgd_present(pgd_t pgd) | 450 | static inline int pgd_present(pgd_t pgd) { return 1; } |
451 | static inline int pgd_none(pgd_t pgd) { return 0; } | ||
452 | static inline int pgd_bad(pgd_t pgd) { return 0; } | ||
453 | |||
454 | static inline int pud_present(pud_t pud) | ||
441 | { | 455 | { |
442 | return pgd_val(pgd) & _REGION_ENTRY_ORIGIN; | 456 | return pud_val(pud) & _REGION_ENTRY_ORIGIN; |
443 | } | 457 | } |
444 | 458 | ||
445 | static inline int pgd_none(pgd_t pgd) | 459 | static inline int pud_none(pud_t pud) |
446 | { | 460 | { |
447 | return pgd_val(pgd) & _REGION_ENTRY_INV; | 461 | return pud_val(pud) & _REGION_ENTRY_INV; |
448 | } | 462 | } |
449 | 463 | ||
450 | static inline int pgd_bad(pgd_t pgd) | 464 | static inline int pud_bad(pud_t pud) |
451 | { | 465 | { |
452 | unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV; | 466 | unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV; |
453 | return (pgd_val(pgd) & mask) != _REGION3_ENTRY; | 467 | return (pud_val(pud) & mask) != _REGION3_ENTRY; |
454 | } | 468 | } |
455 | 469 | ||
456 | #endif /* __s390x__ */ | 470 | #endif /* __s390x__ */ |
@@ -526,7 +540,8 @@ static inline int pte_young(pte_t pte) | |||
526 | 540 | ||
527 | #ifndef __s390x__ | 541 | #ifndef __s390x__ |
528 | 542 | ||
529 | static inline void pgd_clear(pgd_t * pgdp) { } | 543 | #define pgd_clear(pgd) do { } while (0) |
544 | #define pud_clear(pud) do { } while (0) | ||
530 | 545 | ||
531 | static inline void pmd_clear_kernel(pmd_t * pmdp) | 546 | static inline void pmd_clear_kernel(pmd_t * pmdp) |
532 | { | 547 | { |
@@ -538,18 +553,20 @@ static inline void pmd_clear_kernel(pmd_t * pmdp) | |||
538 | 553 | ||
539 | #else /* __s390x__ */ | 554 | #else /* __s390x__ */ |
540 | 555 | ||
541 | static inline void pgd_clear_kernel(pgd_t * pgdp) | 556 | #define pgd_clear(pgd) do { } while (0) |
557 | |||
558 | static inline void pud_clear_kernel(pud_t *pud) | ||
542 | { | 559 | { |
543 | pgd_val(*pgdp) = _REGION3_ENTRY_EMPTY; | 560 | pud_val(*pud) = _REGION3_ENTRY_EMPTY; |
544 | } | 561 | } |
545 | 562 | ||
546 | static inline void pgd_clear(pgd_t * pgdp) | 563 | static inline void pud_clear(pud_t * pud) |
547 | { | 564 | { |
548 | pgd_t *shadow_pgd = get_shadow_table(pgdp); | 565 | pud_t *shadow = get_shadow_table(pud); |
549 | 566 | ||
550 | pgd_clear_kernel(pgdp); | 567 | pud_clear_kernel(pud); |
551 | if (shadow_pgd) | 568 | if (shadow) |
552 | pgd_clear_kernel(shadow_pgd); | 569 | pud_clear_kernel(shadow); |
553 | } | 570 | } |
554 | 571 | ||
555 | static inline void pmd_clear_kernel(pmd_t * pmdp) | 572 | static inline void pmd_clear_kernel(pmd_t * pmdp) |
@@ -810,63 +827,48 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) | |||
810 | return mk_pte_phys(physpage, pgprot); | 827 | return mk_pte_phys(physpage, pgprot); |
811 | } | 828 | } |
812 | 829 | ||
813 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) | 830 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) |
814 | { | 831 | #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
815 | unsigned long physpage = __pa((pfn) << PAGE_SHIFT); | 832 | #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) |
816 | 833 | #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) | |
817 | return mk_pte_phys(physpage, pgprot); | ||
818 | } | ||
819 | |||
820 | #ifdef __s390x__ | ||
821 | |||
822 | static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot) | ||
823 | { | ||
824 | unsigned long physpage = __pa((pfn) << PAGE_SHIFT); | ||
825 | |||
826 | return __pmd(physpage + pgprot_val(pgprot)); | ||
827 | } | ||
828 | |||
829 | #endif /* __s390x__ */ | ||
830 | |||
831 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) | ||
832 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | ||
833 | 834 | ||
834 | #define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK) | 835 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) |
836 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | ||
835 | 837 | ||
836 | #define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) | 838 | #ifndef __s390x__ |
837 | 839 | ||
838 | #define pgd_page_vaddr(pgd) (pgd_val(pgd) & PAGE_MASK) | 840 | #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) |
841 | #define pud_deref(pmd) ({ BUG(); 0UL; }) | ||
842 | #define pgd_deref(pmd) ({ BUG(); 0UL; }) | ||
839 | 843 | ||
840 | #define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT) | 844 | #define pud_offset(pgd, address) ((pud_t *) pgd) |
845 | #define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address)) | ||
841 | 846 | ||
842 | /* to find an entry in a page-table-directory */ | 847 | #else /* __s390x__ */ |
843 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) | ||
844 | #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) | ||
845 | 848 | ||
846 | /* to find an entry in a kernel page-table-directory */ | 849 | #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) |
847 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | 850 | #define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) |
851 | #define pgd_deref(pgd) ({ BUG(); 0UL; }) | ||
848 | 852 | ||
849 | #ifndef __s390x__ | 853 | #define pud_offset(pgd, address) ((pud_t *) pgd) |
850 | 854 | ||
851 | /* Find an entry in the second-level page table.. */ | 855 | static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) |
852 | static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) | ||
853 | { | 856 | { |
854 | return (pmd_t *) dir; | 857 | pmd_t *pmd = (pmd_t *) pud_deref(*pud); |
858 | return pmd + pmd_index(address); | ||
855 | } | 859 | } |
856 | 860 | ||
857 | #else /* __s390x__ */ | 861 | #endif /* __s390x__ */ |
858 | 862 | ||
859 | /* Find an entry in the second-level page table.. */ | 863 | #define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot)) |
860 | #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) | 864 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) |
861 | #define pmd_offset(dir,addr) \ | 865 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
862 | ((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(addr)) | ||
863 | 866 | ||
864 | #endif /* __s390x__ */ | 867 | #define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) |
865 | 868 | ||
866 | /* Find an entry in the third-level page table.. */ | 869 | /* Find an entry in the lowest level page table.. */ |
867 | #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) | 870 | #define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr)) |
868 | #define pte_offset_kernel(pmd, address) \ | 871 | #define pte_offset_kernel(pmd, address) pte_offset(pmd,address) |
869 | ((pte_t *) pmd_page_vaddr(*(pmd)) + pte_index(address)) | ||
870 | #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address) | 872 | #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address) |
871 | #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address) | 873 | #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address) |
872 | #define pte_unmap(pte) do { } while (0) | 874 | #define pte_unmap(pte) do { } while (0) |
@@ -959,4 +961,3 @@ extern void memmap_init(unsigned long, int, unsigned long, unsigned long); | |||
959 | #include <asm-generic/pgtable.h> | 961 | #include <asm-generic/pgtable.h> |
960 | 962 | ||
961 | #endif /* _S390_PAGE_H */ | 963 | #endif /* _S390_PAGE_H */ |
962 | |||