diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:35 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:40 -0500 |
commit | 146e4b3c8b92071b18f0b2e6f47165bad4f9e825 (patch) | |
tree | 7e9db61cacca0f55ce34db089f27fc22a56ebbdd /include/asm-s390/pgalloc.h | |
parent | 0c1f1dcd8c7792aeff6ef62e9508b0041928ab87 (diff) |
[S390] 1K/2K page table pages.
This patch implements 1K/2K page table pages for s390.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'include/asm-s390/pgalloc.h')
-rw-r--r-- | include/asm-s390/pgalloc.h | 79 |
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 | ||
22 | unsigned long *crst_table_alloc(struct mm_struct *, int); | 22 | unsigned long *crst_table_alloc(struct mm_struct *, int); |
23 | void crst_table_free(unsigned long *); | 23 | void crst_table_free(struct mm_struct *, unsigned long *); |
24 | 24 | ||
25 | unsigned long *page_table_alloc(int); | 25 | unsigned long *page_table_alloc(struct mm_struct *); |
26 | void page_table_free(unsigned long *); | 26 | void page_table_free(struct mm_struct *, unsigned long *); |
27 | void disable_noexec(struct mm_struct *, struct task_struct *); | ||
27 | 28 | ||
28 | static inline void clear_table(unsigned long *s, unsigned long val, size_t n) | 29 | static 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 | ||
81 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) | 82 | static 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 | ||
99 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | 100 | static 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 | ||
111 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 112 | static 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 | ||
120 | static inline void | 125 | static inline void pmd_populate_kernel(struct mm_struct *mm, |
121 | pmd_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 | ||
134 | static inline void | 131 | static inline void pmd_populate(struct mm_struct *mm, |
135 | pmd_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 */ |