aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390/pgalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-s390/pgalloc.h')
-rw-r--r--include/asm-s390/pgalloc.h79
1 files changed, 36 insertions, 43 deletions
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index 900d44807e10..af4aee856df3 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -20,10 +20,11 @@
20#define check_pgt_cache() do {} while (0) 20#define check_pgt_cache() do {} while (0)
21 21
22unsigned long *crst_table_alloc(struct mm_struct *, int); 22unsigned long *crst_table_alloc(struct mm_struct *, int);
23void crst_table_free(unsigned long *); 23void crst_table_free(struct mm_struct *, unsigned long *);
24 24
25unsigned long *page_table_alloc(int); 25unsigned long *page_table_alloc(struct mm_struct *);
26void page_table_free(unsigned long *); 26void page_table_free(struct mm_struct *, unsigned long *);
27void disable_noexec(struct mm_struct *, struct task_struct *);
27 28
28static inline void clear_table(unsigned long *s, unsigned long val, size_t n) 29static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
29{ 30{
@@ -80,12 +81,12 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm)
80 81
81static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 82static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
82{ 83{
83 unsigned long *crst = crst_table_alloc(mm, s390_noexec); 84 unsigned long *table = crst_table_alloc(mm, mm->context.noexec);
84 if (crst) 85 if (table)
85 crst_table_init(crst, _SEGMENT_ENTRY_EMPTY); 86 crst_table_init(table, _SEGMENT_ENTRY_EMPTY);
86 return (pmd_t *) crst; 87 return (pmd_t *) table;
87} 88}
88#define pmd_free(mm, pmd) crst_table_free((unsigned long *)pmd) 89#define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd)
89 90
90#define pgd_populate(mm, pgd, pud) BUG() 91#define pgd_populate(mm, pgd, pud) BUG()
91#define pgd_populate_kernel(mm, pgd, pud) BUG() 92#define pgd_populate_kernel(mm, pgd, pud) BUG()
@@ -98,63 +99,55 @@ static inline void pud_populate_kernel(struct mm_struct *mm,
98 99
99static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 100static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
100{ 101{
101 pud_t *shadow_pud = get_shadow_table(pud);
102 pmd_t *shadow_pmd = get_shadow_table(pmd);
103
104 if (shadow_pud && shadow_pmd)
105 pud_populate_kernel(mm, shadow_pud, shadow_pmd);
106 pud_populate_kernel(mm, pud, pmd); 102 pud_populate_kernel(mm, pud, pmd);
103 if (mm->context.noexec) {
104 pud = get_shadow_table(pud);
105 pmd = get_shadow_table(pmd);
106 pud_populate_kernel(mm, pud, pmd);
107 }
107} 108}
108 109
109#endif /* __s390x__ */ 110#endif /* __s390x__ */
110 111
111static inline pgd_t *pgd_alloc(struct mm_struct *mm) 112static inline pgd_t *pgd_alloc(struct mm_struct *mm)
112{ 113{
113 unsigned long *crst = crst_table_alloc(mm, s390_noexec); 114 unsigned long *crst;
115
116 INIT_LIST_HEAD(&mm->context.crst_list);
117 INIT_LIST_HEAD(&mm->context.pgtable_list);
118 crst = crst_table_alloc(mm, s390_noexec);
114 if (crst) 119 if (crst)
115 crst_table_init(crst, pgd_entry_type(mm)); 120 crst_table_init(crst, pgd_entry_type(mm));
116 return (pgd_t *) crst; 121 return (pgd_t *) crst;
117} 122}
118#define pgd_free(mm, pgd) crst_table_free((unsigned long *) pgd) 123#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
119 124
120static inline void 125static inline void pmd_populate_kernel(struct mm_struct *mm,
121pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) 126 pmd_t *pmd, pte_t *pte)
122{ 127{
123#ifndef __s390x__
124 pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte);
125 pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256);
126 pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512);
127 pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768);
128#else /* __s390x__ */
129 pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte); 128 pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
130 pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256);
131#endif /* __s390x__ */
132} 129}
133 130
134static inline void 131static inline void pmd_populate(struct mm_struct *mm,
135pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) 132 pmd_t *pmd, pgtable_t pte)
136{ 133{
137 pte_t *pte = (pte_t *)page_to_phys(page);
138 pmd_t *shadow_pmd = get_shadow_table(pmd);
139 pte_t *shadow_pte = get_shadow_pte(pte);
140
141 pmd_populate_kernel(mm, pmd, pte); 134 pmd_populate_kernel(mm, pmd, pte);
142 if (shadow_pmd && shadow_pte) 135 if (mm->context.noexec) {
143 pmd_populate_kernel(mm, shadow_pmd, shadow_pte); 136 pmd = get_shadow_table(pmd);
137 pmd_populate_kernel(mm, pmd, pte + PTRS_PER_PTE);
138 }
144} 139}
145#define pmd_pgtable(pmd) pmd_page(pmd) 140
141#define pmd_pgtable(pmd) \
142 (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE)
146 143
147/* 144/*
148 * page table entry allocation/free routines. 145 * page table entry allocation/free routines.
149 */ 146 */
150#define pte_alloc_one_kernel(mm, vmaddr) \ 147#define pte_alloc_one_kernel(mm, vmaddr) ((pte_t *) page_table_alloc(mm))
151 ((pte_t *) page_table_alloc(s390_noexec)) 148#define pte_alloc_one(mm, vmaddr) ((pte_t *) page_table_alloc(mm))
152#define pte_alloc_one(mm, vmaddr) \ 149
153 virt_to_page(page_table_alloc(s390_noexec)) 150#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte)
154 151#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte)
155#define pte_free_kernel(mm, pte) \
156 page_table_free((unsigned long *) pte)
157#define pte_free(mm, pte) \
158 page_table_free((unsigned long *) page_to_phys((struct page *) pte))
159 152
160#endif /* _S390_PGALLOC_H */ 153#endif /* _S390_PGALLOC_H */