aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/mm/fault.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 18162ce4261e..f247a3480e8e 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -175,10 +175,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
175 struct mm_struct *mm = tsk->mm; 175 struct mm_struct *mm = tsk->mm;
176 unsigned long acc_type; 176 unsigned long acc_type;
177 int fault; 177 int fault;
178 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
178 179
179 if (in_atomic() || !mm) 180 if (in_atomic() || !mm)
180 goto no_context; 181 goto no_context;
181 182
183retry:
182 down_read(&mm->mmap_sem); 184 down_read(&mm->mmap_sem);
183 vma = find_vma_prev(mm, address, &prev_vma); 185 vma = find_vma_prev(mm, address, &prev_vma);
184 if (!vma || address < vma->vm_start) 186 if (!vma || address < vma->vm_start)
@@ -201,7 +203,12 @@ good_area:
201 * fault. 203 * fault.
202 */ 204 */
203 205
204 fault = handle_mm_fault(mm, vma, address, (acc_type & VM_WRITE) ? FAULT_FLAG_WRITE : 0); 206 fault = handle_mm_fault(mm, vma, address,
207 flags | ((acc_type & VM_WRITE) ? FAULT_FLAG_WRITE : 0));
208
209 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
210 return;
211
205 if (unlikely(fault & VM_FAULT_ERROR)) { 212 if (unlikely(fault & VM_FAULT_ERROR)) {
206 /* 213 /*
207 * We hit a shared mapping outside of the file, or some 214 * We hit a shared mapping outside of the file, or some
@@ -214,10 +221,23 @@ good_area:
214 goto bad_area; 221 goto bad_area;
215 BUG(); 222 BUG();
216 } 223 }
217 if (fault & VM_FAULT_MAJOR) 224 if (flags & FAULT_FLAG_ALLOW_RETRY) {
218 current->maj_flt++; 225 if (fault & VM_FAULT_MAJOR)
219 else 226 current->maj_flt++;
220 current->min_flt++; 227 else
228 current->min_flt++;
229 if (fault & VM_FAULT_RETRY) {
230 flags &= ~FAULT_FLAG_ALLOW_RETRY;
231
232 /*
233 * No need to up_read(&mm->mmap_sem) as we would
234 * have already released it in __lock_page_or_retry
235 * in mm/filemap.c.
236 */
237
238 goto retry;
239 }
240 }
221 up_read(&mm->mmap_sem); 241 up_read(&mm->mmap_sem);
222 return; 242 return;
223 243