diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-07-26 02:53:06 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-07-26 10:24:14 -0400 |
commit | 0f6f281b731d20bfe75c13f85d33f3f05b440222 (patch) | |
tree | 0f8c23d3fca50dd2830ddc978501cd45a0057f45 /arch/s390/mm/mmap.c | |
parent | 8143adafd2d00b13f1db96ce06b6bf479e0bfe5b (diff) |
s390/mm: downgrade page table after fork of a 31 bit process
The downgrade of the 4 level page table created by init_new_context is
currently done only in start_thread31. If a 31 bit process forks the
new mm uses a 4 level page table, including the task size of 2<<42
that goes along with it. This is incorrect as now a 31 bit process
can map memory beyond 2GB. Define arch_dup_mmap to do the downgrade
after fork.
Cc: stable@vger.kernel.org
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm/mmap.c')
-rw-r--r-- | arch/s390/mm/mmap.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 573384256c5c..c59a5efa58b1 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
@@ -103,9 +103,15 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
103 | 103 | ||
104 | int s390_mmap_check(unsigned long addr, unsigned long len) | 104 | int s390_mmap_check(unsigned long addr, unsigned long len) |
105 | { | 105 | { |
106 | int rc; | ||
107 | |||
106 | if (!is_compat_task() && | 108 | if (!is_compat_task() && |
107 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) | 109 | len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) { |
108 | return crst_table_upgrade(current->mm, 1UL << 53); | 110 | rc = crst_table_upgrade(current->mm, 1UL << 53); |
111 | if (rc) | ||
112 | return rc; | ||
113 | update_mm(current->mm, current); | ||
114 | } | ||
109 | return 0; | 115 | return 0; |
110 | } | 116 | } |
111 | 117 | ||
@@ -125,6 +131,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, | |||
125 | rc = crst_table_upgrade(mm, 1UL << 53); | 131 | rc = crst_table_upgrade(mm, 1UL << 53); |
126 | if (rc) | 132 | if (rc) |
127 | return (unsigned long) rc; | 133 | return (unsigned long) rc; |
134 | update_mm(mm, current); | ||
128 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); | 135 | area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); |
129 | } | 136 | } |
130 | return area; | 137 | return area; |
@@ -147,6 +154,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, | |||
147 | rc = crst_table_upgrade(mm, 1UL << 53); | 154 | rc = crst_table_upgrade(mm, 1UL << 53); |
148 | if (rc) | 155 | if (rc) |
149 | return (unsigned long) rc; | 156 | return (unsigned long) rc; |
157 | update_mm(mm, current); | ||
150 | area = arch_get_unmapped_area_topdown(filp, addr, len, | 158 | area = arch_get_unmapped_area_topdown(filp, addr, len, |
151 | pgoff, flags); | 159 | pgoff, flags); |
152 | } | 160 | } |