aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include/asm/pgalloc.h
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2011-05-23 04:24:23 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2011-05-23 04:24:28 -0400
commit043d07084b5347a26eab0a07aa13a4a929ad9e71 (patch)
tree13c2a902ccb2ecb779722c8b81ada32d242760c8 /arch/s390/include/asm/pgalloc.h
parent9bf05098ce34e68a9e15f09ad6cdfea4ed64057a (diff)
[S390] Remove data execution protection
The noexec support on s390 does not rely on a bit in the page table entry but utilizes the secondary space mode to distinguish between memory accesses for instructions vs. data. The noexec code relies on the assumption that the cpu will always use the secondary space page table for data accesses while it is running in the secondary space mode. Up to the z9-109 class machines this has been the case. Unfortunately this is not true anymore with z10 and later machines. The load-relative-long instructions lrl, lgrl and lgfrl access the memory operand using the same addressing-space mode that has been used to fetch the instruction. This breaks the noexec mode for all user space binaries compiled with march=z10 or later. The only option is to remove the current noexec support. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include/asm/pgalloc.h')
-rw-r--r--arch/s390/include/asm/pgalloc.h28
1 files changed, 4 insertions, 24 deletions
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 082eb4e50e8b..739ff9ec1395 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -19,14 +19,13 @@
19 19
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 *);
23void crst_table_free(struct mm_struct *, unsigned long *); 23void crst_table_free(struct mm_struct *, unsigned long *);
24void crst_table_free_rcu(struct mm_struct *, unsigned long *); 24void crst_table_free_rcu(struct mm_struct *, unsigned long *);
25 25
26unsigned long *page_table_alloc(struct mm_struct *); 26unsigned long *page_table_alloc(struct mm_struct *);
27void page_table_free(struct mm_struct *, unsigned long *); 27void page_table_free(struct mm_struct *, unsigned long *);
28void page_table_free_rcu(struct mm_struct *, unsigned long *); 28void page_table_free_rcu(struct mm_struct *, unsigned long *);
29void disable_noexec(struct mm_struct *, struct task_struct *);
30 29
31static inline void clear_table(unsigned long *s, unsigned long val, size_t n) 30static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
32{ 31{
@@ -50,9 +49,6 @@ static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
50static inline void crst_table_init(unsigned long *crst, unsigned long entry) 49static inline void crst_table_init(unsigned long *crst, unsigned long entry)
51{ 50{
52 clear_table(crst, entry, sizeof(unsigned long)*2048); 51 clear_table(crst, entry, sizeof(unsigned long)*2048);
53 crst = get_shadow_table(crst);
54 if (crst)
55 clear_table(crst, entry, sizeof(unsigned long)*2048);
56} 52}
57 53
58#ifndef __s390x__ 54#ifndef __s390x__
@@ -90,7 +86,7 @@ void crst_table_downgrade(struct mm_struct *, unsigned long limit);
90 86
91static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) 87static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
92{ 88{
93 unsigned long *table = crst_table_alloc(mm, mm->context.noexec); 89 unsigned long *table = crst_table_alloc(mm);
94 if (table) 90 if (table)
95 crst_table_init(table, _REGION3_ENTRY_EMPTY); 91 crst_table_init(table, _REGION3_ENTRY_EMPTY);
96 return (pud_t *) table; 92 return (pud_t *) table;
@@ -99,7 +95,7 @@ static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
99 95
100static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) 96static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
101{ 97{
102 unsigned long *table = crst_table_alloc(mm, mm->context.noexec); 98 unsigned long *table = crst_table_alloc(mm);
103 if (table) 99 if (table)
104 crst_table_init(table, _SEGMENT_ENTRY_EMPTY); 100 crst_table_init(table, _SEGMENT_ENTRY_EMPTY);
105 return (pmd_t *) table; 101 return (pmd_t *) table;
@@ -115,11 +111,6 @@ static inline void pgd_populate_kernel(struct mm_struct *mm,
115static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) 111static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
116{ 112{
117 pgd_populate_kernel(mm, pgd, pud); 113 pgd_populate_kernel(mm, pgd, pud);
118 if (mm->context.noexec) {
119 pgd = get_shadow_table(pgd);
120 pud = get_shadow_table(pud);
121 pgd_populate_kernel(mm, pgd, pud);
122 }
123} 114}
124 115
125static inline void pud_populate_kernel(struct mm_struct *mm, 116static inline void pud_populate_kernel(struct mm_struct *mm,
@@ -131,11 +122,6 @@ static inline void pud_populate_kernel(struct mm_struct *mm,
131static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) 122static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
132{ 123{
133 pud_populate_kernel(mm, pud, pmd); 124 pud_populate_kernel(mm, pud, pmd);
134 if (mm->context.noexec) {
135 pud = get_shadow_table(pud);
136 pmd = get_shadow_table(pmd);
137 pud_populate_kernel(mm, pud, pmd);
138 }
139} 125}
140 126
141#endif /* __s390x__ */ 127#endif /* __s390x__ */
@@ -143,10 +129,8 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
143static inline pgd_t *pgd_alloc(struct mm_struct *mm) 129static inline pgd_t *pgd_alloc(struct mm_struct *mm)
144{ 130{
145 spin_lock_init(&mm->context.list_lock); 131 spin_lock_init(&mm->context.list_lock);
146 INIT_LIST_HEAD(&mm->context.crst_list);
147 INIT_LIST_HEAD(&mm->context.pgtable_list); 132 INIT_LIST_HEAD(&mm->context.pgtable_list);
148 return (pgd_t *) 133 return (pgd_t *) crst_table_alloc(mm);
149 crst_table_alloc(mm, user_mode == SECONDARY_SPACE_MODE);
150} 134}
151#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) 135#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
152 136
@@ -160,10 +144,6 @@ static inline void pmd_populate(struct mm_struct *mm,
160 pmd_t *pmd, pgtable_t pte) 144 pmd_t *pmd, pgtable_t pte)
161{ 145{
162 pmd_populate_kernel(mm, pmd, pte); 146 pmd_populate_kernel(mm, pmd, pte);
163 if (mm->context.noexec) {
164 pmd = get_shadow_table(pmd);
165 pmd_populate_kernel(mm, pmd, pte + PTRS_PER_PTE);
166 }
167} 147}
168 148
169#define pmd_pgtable(pmd) \ 149#define pmd_pgtable(pmd) \