aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/fault.c')
-rw-r--r--arch/mips/mm/fault.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 937cf3368164..69ebd586d7ff 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -42,6 +42,8 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ
42 const int field = sizeof(unsigned long) * 2; 42 const int field = sizeof(unsigned long) * 2;
43 siginfo_t info; 43 siginfo_t info;
44 int fault; 44 int fault;
45 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
46 (write ? FAULT_FLAG_WRITE : 0);
45 47
46#if 0 48#if 0
47 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(), 49 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
@@ -91,6 +93,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ
91 if (in_atomic() || !mm) 93 if (in_atomic() || !mm)
92 goto bad_area_nosemaphore; 94 goto bad_area_nosemaphore;
93 95
96retry:
94 down_read(&mm->mmap_sem); 97 down_read(&mm->mmap_sem);
95 vma = find_vma(mm, address); 98 vma = find_vma(mm, address);
96 if (!vma) 99 if (!vma)
@@ -144,7 +147,11 @@ good_area:
144 * make sure we exit gracefully rather than endlessly redo 147 * make sure we exit gracefully rather than endlessly redo
145 * the fault. 148 * the fault.
146 */ 149 */
147 fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); 150 fault = handle_mm_fault(mm, vma, address, flags);
151
152 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
153 return;
154
148 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); 155 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
149 if (unlikely(fault & VM_FAULT_ERROR)) { 156 if (unlikely(fault & VM_FAULT_ERROR)) {
150 if (fault & VM_FAULT_OOM) 157 if (fault & VM_FAULT_OOM)
@@ -153,12 +160,27 @@ good_area:
153 goto do_sigbus; 160 goto do_sigbus;
154 BUG(); 161 BUG();
155 } 162 }
156 if (fault & VM_FAULT_MAJOR) { 163 if (flags & FAULT_FLAG_ALLOW_RETRY) {
157 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); 164 if (fault & VM_FAULT_MAJOR) {
158 tsk->maj_flt++; 165 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
159 } else { 166 regs, address);
160 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); 167 tsk->maj_flt++;
161 tsk->min_flt++; 168 } else {
169 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
170 regs, address);
171 tsk->min_flt++;
172 }
173 if (fault & VM_FAULT_RETRY) {
174 flags &= ~FAULT_FLAG_ALLOW_RETRY;
175
176 /*
177 * No need to up_read(&mm->mmap_sem) as we would
178 * have already released it in __lock_page_or_retry
179 * in mm/filemap.c.
180 */
181
182 goto retry;
183 }
162 } 184 }
163 185
164 up_read(&mm->mmap_sem); 186 up_read(&mm->mmap_sem);