aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/lib/uaccess_pt.c7
-rw-r--r--arch/s390/mm/init.c4
-rw-r--r--arch/s390/mm/vmem.c34
-rw-r--r--include/asm-s390/page.h4
-rw-r--r--include/asm-s390/pgalloc.h32
-rw-r--r--include/asm-s390/pgtable.h123
-rw-r--r--include/asm-s390/tlb.h2
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 @@
18static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr) 18static 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)
81static void __init setup_ro_region(void) 81static 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
76static inline pmd_t *vmem_pmd_alloc(void) 78static 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
84typedef struct { unsigned long pmd; } pmd_t; 84typedef struct { unsigned long pmd; } pmd_t;
85typedef struct { unsigned long pud; } pud_t;
85typedef struct { 86typedef 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;
103typedef struct { unsigned long pud; } pud_t;
101typedef struct { unsigned long pgd; } pgd_t; 104typedef 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
72static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 81static 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
81static 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
93static 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
87static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) 99static 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; }
435static inline int pgd_none(pgd_t pgd) { return 0; } 441static inline int pgd_none(pgd_t pgd) { return 0; }
436static inline int pgd_bad(pgd_t pgd) { return 0; } 442static inline int pgd_bad(pgd_t pgd) { return 0; }
437 443
444static inline int pud_present(pud_t pud) { return 1; }
445static inline int pud_none(pud_t pud) { return 0; }
446static inline int pud_bad(pud_t pud) { return 0; }
447
438#else /* __s390x__ */ 448#else /* __s390x__ */
439 449
440static inline int pgd_present(pgd_t pgd) 450static inline int pgd_present(pgd_t pgd) { return 1; }
451static inline int pgd_none(pgd_t pgd) { return 0; }
452static inline int pgd_bad(pgd_t pgd) { return 0; }
453
454static 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
445static inline int pgd_none(pgd_t pgd) 459static 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
450static inline int pgd_bad(pgd_t pgd) 464static 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
529static 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
531static inline void pmd_clear_kernel(pmd_t * pmdp) 546static 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
541static inline void pgd_clear_kernel(pgd_t * pgdp) 556#define pgd_clear(pgd) do { } while (0)
557
558static 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
546static inline void pgd_clear(pgd_t * pgdp) 563static 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
555static inline void pmd_clear_kernel(pmd_t * pmdp) 572static 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
813static 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
822static 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.. */ 855static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
852static 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)