diff options
-rw-r--r-- | arch/s390/lib/uaccess_pt.c | 7 | ||||
-rw-r--r-- | arch/s390/mm/init.c | 4 | ||||
-rw-r--r-- | arch/s390/mm/vmem.c | 34 | ||||
-rw-r--r-- | include/asm-s390/page.h | 4 | ||||
-rw-r--r-- | include/asm-s390/pgalloc.h | 32 | ||||
-rw-r--r-- | include/asm-s390/pgtable.h | 123 | ||||
-rw-r--r-- | include/asm-s390/tlb.h | 2 |
7 files changed, 127 insertions, 79 deletions
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index dc37ea827f4e..7e8efaade2ea 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
@@ -18,13 +18,18 @@ | |||
18 | static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr) | 18 | static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr) |
19 | { | 19 | { |
20 | pgd_t *pgd; | 20 | pgd_t *pgd; |
21 | pud_t *pud; | ||
21 | pmd_t *pmd; | 22 | pmd_t *pmd; |
22 | 23 | ||
23 | pgd = pgd_offset(mm, addr); | 24 | pgd = pgd_offset(mm, addr); |
24 | if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) | 25 | if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) |
25 | return NULL; | 26 | return NULL; |
26 | 27 | ||
27 | pmd = pmd_offset(pgd, addr); | 28 | pud = pud_offset(pgd, addr); |
29 | if (pud_none(*pud) || unlikely(pud_bad(*pud))) | ||
30 | return NULL; | ||
31 | |||
32 | pmd = pmd_offset(pud, addr); | ||
28 | if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) | 33 | if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) |
29 | return NULL; | 34 | return NULL; |
30 | 35 | ||
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 90ec058aa7db..b234bb4a6da7 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -81,6 +81,7 @@ void show_mem(void) | |||
81 | static void __init setup_ro_region(void) | 81 | static void __init setup_ro_region(void) |
82 | { | 82 | { |
83 | pgd_t *pgd; | 83 | pgd_t *pgd; |
84 | pud_t *pud; | ||
84 | pmd_t *pmd; | 85 | pmd_t *pmd; |
85 | pte_t *pte; | 86 | pte_t *pte; |
86 | pte_t new_pte; | 87 | pte_t new_pte; |
@@ -91,7 +92,8 @@ static void __init setup_ro_region(void) | |||
91 | 92 | ||
92 | for (; address < end; address += PAGE_SIZE) { | 93 | for (; address < end; address += PAGE_SIZE) { |
93 | pgd = pgd_offset_k(address); | 94 | pgd = pgd_offset_k(address); |
94 | pmd = pmd_offset(pgd, address); | 95 | pud = pud_offset(pgd, address); |
96 | pmd = pmd_offset(pud, address); | ||
95 | pte = pte_offset_kernel(pmd, address); | 97 | pte = pte_offset_kernel(pmd, address); |
96 | new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO)); | 98 | new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO)); |
97 | *pte = new_pte; | 99 | *pte = new_pte; |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 1bd51d840484..fb9c5a85aa56 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -73,6 +73,8 @@ static void __init_refok *vmem_alloc_pages(unsigned int order) | |||
73 | return alloc_bootmem_pages((1 << order) * PAGE_SIZE); | 73 | return alloc_bootmem_pages((1 << order) * PAGE_SIZE); |
74 | } | 74 | } |
75 | 75 | ||
76 | #define vmem_pud_alloc() ({ BUG(); ((pud_t *) NULL); }) | ||
77 | |||
76 | static inline pmd_t *vmem_pmd_alloc(void) | 78 | static inline pmd_t *vmem_pmd_alloc(void) |
77 | { | 79 | { |
78 | pmd_t *pmd = NULL; | 80 | pmd_t *pmd = NULL; |
@@ -103,6 +105,7 @@ static int vmem_add_range(unsigned long start, unsigned long size) | |||
103 | { | 105 | { |
104 | unsigned long address; | 106 | unsigned long address; |
105 | pgd_t *pg_dir; | 107 | pgd_t *pg_dir; |
108 | pud_t *pu_dir; | ||
106 | pmd_t *pm_dir; | 109 | pmd_t *pm_dir; |
107 | pte_t *pt_dir; | 110 | pte_t *pt_dir; |
108 | pte_t pte; | 111 | pte_t pte; |
@@ -111,13 +114,21 @@ static int vmem_add_range(unsigned long start, unsigned long size) | |||
111 | for (address = start; address < start + size; address += PAGE_SIZE) { | 114 | for (address = start; address < start + size; address += PAGE_SIZE) { |
112 | pg_dir = pgd_offset_k(address); | 115 | pg_dir = pgd_offset_k(address); |
113 | if (pgd_none(*pg_dir)) { | 116 | if (pgd_none(*pg_dir)) { |
117 | pu_dir = vmem_pud_alloc(); | ||
118 | if (!pu_dir) | ||
119 | goto out; | ||
120 | pgd_populate_kernel(&init_mm, pg_dir, pu_dir); | ||
121 | } | ||
122 | |||
123 | pu_dir = pud_offset(pg_dir, address); | ||
124 | if (pud_none(*pu_dir)) { | ||
114 | pm_dir = vmem_pmd_alloc(); | 125 | pm_dir = vmem_pmd_alloc(); |
115 | if (!pm_dir) | 126 | if (!pm_dir) |
116 | goto out; | 127 | goto out; |
117 | pgd_populate_kernel(&init_mm, pg_dir, pm_dir); | 128 | pud_populate_kernel(&init_mm, pu_dir, pm_dir); |
118 | } | 129 | } |
119 | 130 | ||
120 | pm_dir = pmd_offset(pg_dir, address); | 131 | pm_dir = pmd_offset(pu_dir, address); |
121 | if (pmd_none(*pm_dir)) { | 132 | if (pmd_none(*pm_dir)) { |
122 | pt_dir = vmem_pte_alloc(); | 133 | pt_dir = vmem_pte_alloc(); |
123 | if (!pt_dir) | 134 | if (!pt_dir) |
@@ -143,6 +154,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size) | |||
143 | { | 154 | { |
144 | unsigned long address; | 155 | unsigned long address; |
145 | pgd_t *pg_dir; | 156 | pgd_t *pg_dir; |
157 | pud_t *pu_dir; | ||
146 | pmd_t *pm_dir; | 158 | pmd_t *pm_dir; |
147 | pte_t *pt_dir; | 159 | pte_t *pt_dir; |
148 | pte_t pte; | 160 | pte_t pte; |
@@ -150,9 +162,10 @@ static void vmem_remove_range(unsigned long start, unsigned long size) | |||
150 | pte_val(pte) = _PAGE_TYPE_EMPTY; | 162 | pte_val(pte) = _PAGE_TYPE_EMPTY; |
151 | for (address = start; address < start + size; address += PAGE_SIZE) { | 163 | for (address = start; address < start + size; address += PAGE_SIZE) { |
152 | pg_dir = pgd_offset_k(address); | 164 | pg_dir = pgd_offset_k(address); |
153 | if (pgd_none(*pg_dir)) | 165 | pu_dir = pud_offset(pg_dir, address); |
166 | if (pud_none(*pu_dir)) | ||
154 | continue; | 167 | continue; |
155 | pm_dir = pmd_offset(pg_dir, address); | 168 | pm_dir = pmd_offset(pu_dir, address); |
156 | if (pmd_none(*pm_dir)) | 169 | if (pmd_none(*pm_dir)) |
157 | continue; | 170 | continue; |
158 | pt_dir = pte_offset_kernel(pm_dir, address); | 171 | pt_dir = pte_offset_kernel(pm_dir, address); |
@@ -169,6 +182,7 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size) | |||
169 | unsigned long address, start_addr, end_addr; | 182 | unsigned long address, start_addr, end_addr; |
170 | struct page *map_start, *map_end; | 183 | struct page *map_start, *map_end; |
171 | pgd_t *pg_dir; | 184 | pgd_t *pg_dir; |
185 | pud_t *pu_dir; | ||
172 | pmd_t *pm_dir; | 186 | pmd_t *pm_dir; |
173 | pte_t *pt_dir; | 187 | pte_t *pt_dir; |
174 | pte_t pte; | 188 | pte_t pte; |
@@ -183,13 +197,21 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size) | |||
183 | for (address = start_addr; address < end_addr; address += PAGE_SIZE) { | 197 | for (address = start_addr; address < end_addr; address += PAGE_SIZE) { |
184 | pg_dir = pgd_offset_k(address); | 198 | pg_dir = pgd_offset_k(address); |
185 | if (pgd_none(*pg_dir)) { | 199 | if (pgd_none(*pg_dir)) { |
200 | pu_dir = vmem_pud_alloc(); | ||
201 | if (!pu_dir) | ||
202 | goto out; | ||
203 | pgd_populate_kernel(&init_mm, pg_dir, pu_dir); | ||
204 | } | ||
205 | |||
206 | pu_dir = pud_offset(pg_dir, address); | ||
207 | if (pud_none(*pu_dir)) { | ||
186 | pm_dir = vmem_pmd_alloc(); | 208 | pm_dir = vmem_pmd_alloc(); |
187 | if (!pm_dir) | 209 | if (!pm_dir) |
188 | goto out; | 210 | goto out; |
189 | pgd_populate_kernel(&init_mm, pg_dir, pm_dir); | 211 | pud_populate_kernel(&init_mm, pu_dir, pm_dir); |
190 | } | 212 | } |
191 | 213 | ||
192 | pm_dir = pmd_offset(pg_dir, address); | 214 | pm_dir = pmd_offset(pu_dir, address); |
193 | if (pmd_none(*pm_dir)) { | 215 | if (pmd_none(*pm_dir)) { |
194 | pt_dir = vmem_pte_alloc(); | 216 | pt_dir = vmem_pte_alloc(); |
195 | if (!pt_dir) | 217 | if (!pt_dir) |
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index ceec3826a67c..584d0ee3c7f6 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h | |||
@@ -82,6 +82,7 @@ typedef struct { unsigned long pte; } pte_t; | |||
82 | #ifndef __s390x__ | 82 | #ifndef __s390x__ |
83 | 83 | ||
84 | typedef struct { unsigned long pmd; } pmd_t; | 84 | typedef struct { unsigned long pmd; } pmd_t; |
85 | typedef struct { unsigned long pud; } pud_t; | ||
85 | typedef struct { | 86 | typedef struct { |
86 | unsigned long pgd0; | 87 | unsigned long pgd0; |
87 | unsigned long pgd1; | 88 | unsigned long pgd1; |
@@ -90,6 +91,7 @@ typedef struct { | |||
90 | } pgd_t; | 91 | } pgd_t; |
91 | 92 | ||
92 | #define pmd_val(x) ((x).pmd) | 93 | #define pmd_val(x) ((x).pmd) |
94 | #define pud_val(x) ((x).pud) | ||
93 | #define pgd_val(x) ((x).pgd0) | 95 | #define pgd_val(x) ((x).pgd0) |
94 | 96 | ||
95 | #else /* __s390x__ */ | 97 | #else /* __s390x__ */ |
@@ -98,10 +100,12 @@ typedef struct { | |||
98 | unsigned long pmd0; | 100 | unsigned long pmd0; |
99 | unsigned long pmd1; | 101 | unsigned long pmd1; |
100 | } pmd_t; | 102 | } pmd_t; |
103 | typedef struct { unsigned long pud; } pud_t; | ||
101 | typedef struct { unsigned long pgd; } pgd_t; | 104 | typedef struct { unsigned long pgd; } pgd_t; |
102 | 105 | ||
103 | #define pmd_val(x) ((x).pmd0) | 106 | #define pmd_val(x) ((x).pmd0) |
104 | #define pmd_val1(x) ((x).pmd1) | 107 | #define pmd_val1(x) ((x).pmd1) |
108 | #define pud_val(x) ((x).pud) | ||
105 | #define pgd_val(x) ((x).pgd) | 109 | #define pgd_val(x) ((x).pgd) |
106 | 110 | ||
107 | #endif /* __s390x__ */ | 111 | #endif /* __s390x__ */ |
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 229b0bd59331..709dd1740956 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h | |||
@@ -56,11 +56,17 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) | |||
56 | return _SEGMENT_ENTRY_EMPTY; | 56 | return _SEGMENT_ENTRY_EMPTY; |
57 | } | 57 | } |
58 | 58 | ||
59 | #define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) | ||
60 | #define pud_free(x) do { } while (0) | ||
61 | |||
59 | #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) | 62 | #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) |
60 | #define pmd_free(x) do { } while (0) | 63 | #define pmd_free(x) do { } while (0) |
61 | 64 | ||
62 | #define pgd_populate(mm, pmd, pte) BUG() | 65 | #define pgd_populate(mm, pgd, pud) BUG() |
63 | #define pgd_populate_kernel(mm, pmd, pte) BUG() | 66 | #define pgd_populate_kernel(mm, pgd, pud) BUG() |
67 | |||
68 | #define pud_populate(mm, pud, pmd) BUG() | ||
69 | #define pud_populate_kernel(mm, pud, pmd) BUG() | ||
64 | 70 | ||
65 | #else /* __s390x__ */ | 71 | #else /* __s390x__ */ |
66 | 72 | ||
@@ -69,6 +75,9 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) | |||
69 | return _REGION3_ENTRY_EMPTY; | 75 | return _REGION3_ENTRY_EMPTY; |
70 | } | 76 | } |
71 | 77 | ||
78 | #define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) | ||
79 | #define pud_free(x) do { } while (0) | ||
80 | |||
72 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) | 81 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) |
73 | { | 82 | { |
74 | unsigned long *crst = crst_table_alloc(mm, s390_noexec); | 83 | unsigned long *crst = crst_table_alloc(mm, s390_noexec); |
@@ -78,20 +87,23 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) | |||
78 | } | 87 | } |
79 | #define pmd_free(pmd) crst_table_free((unsigned long *) pmd) | 88 | #define pmd_free(pmd) crst_table_free((unsigned long *) pmd) |
80 | 89 | ||
81 | static inline void pgd_populate_kernel(struct mm_struct *mm, | 90 | #define pgd_populate(mm, pgd, pud) BUG() |
82 | pgd_t *pgd, pmd_t *pmd) | 91 | #define pgd_populate_kernel(mm, pgd, pud) BUG() |
92 | |||
93 | static inline void pud_populate_kernel(struct mm_struct *mm, | ||
94 | pud_t *pud, pmd_t *pmd) | ||
83 | { | 95 | { |
84 | pgd_val(*pgd) = _REGION3_ENTRY | __pa(pmd); | 96 | pud_val(*pud) = _REGION3_ENTRY | __pa(pmd); |
85 | } | 97 | } |
86 | 98 | ||
87 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) | 99 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) |
88 | { | 100 | { |
89 | pgd_t *shadow_pgd = get_shadow_table(pgd); | 101 | pud_t *shadow_pud = get_shadow_table(pud); |
90 | pmd_t *shadow_pmd = get_shadow_table(pmd); | 102 | pmd_t *shadow_pmd = get_shadow_table(pmd); |
91 | 103 | ||
92 | if (shadow_pgd && shadow_pmd) | 104 | if (shadow_pud && shadow_pmd) |
93 | pgd_populate_kernel(mm, shadow_pgd, shadow_pmd); | 105 | pud_populate_kernel(mm, shadow_pud, shadow_pmd); |
94 | pgd_populate_kernel(mm, pgd, pmd); | 106 | pud_populate_kernel(mm, pud, pmd); |
95 | } | 107 | } |
96 | 108 | ||
97 | #endif /* __s390x__ */ | 109 | #endif /* __s390x__ */ |
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 | |||
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h index 55ae45ef31b5..618693cfc10f 100644 --- a/include/asm-s390/tlb.h +++ b/include/asm-s390/tlb.h | |||
@@ -121,6 +121,8 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | |||
121 | #endif | 121 | #endif |
122 | } | 122 | } |
123 | 123 | ||
124 | #define pud_free_tlb(tlb, pud) do { } while (0) | ||
125 | |||
124 | #define tlb_start_vma(tlb, vma) do { } while (0) | 126 | #define tlb_start_vma(tlb, vma) do { } while (0) |
125 | #define tlb_end_vma(tlb, vma) do { } while (0) | 127 | #define tlb_end_vma(tlb, vma) do { } while (0) |
126 | #define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0) | 128 | #define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0) |