aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/fault.c')
-rw-r--r--arch/powerpc/mm/fault.c181
1 files changed, 131 insertions, 50 deletions
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 2f0d1b032a89..19f2f9498b27 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -105,6 +105,82 @@ static int store_updates_sp(struct pt_regs *regs)
105 } 105 }
106 return 0; 106 return 0;
107} 107}
108/*
109 * do_page_fault error handling helpers
110 */
111
112#define MM_FAULT_RETURN 0
113#define MM_FAULT_CONTINUE -1
114#define MM_FAULT_ERR(sig) (sig)
115
116static int out_of_memory(struct pt_regs *regs)
117{
118 /*
119 * We ran out of memory, or some other thing happened to us that made
120 * us unable to handle the page fault gracefully.
121 */
122 up_read(&current->mm->mmap_sem);
123 if (!user_mode(regs))
124 return MM_FAULT_ERR(SIGKILL);
125 pagefault_out_of_memory();
126 return MM_FAULT_RETURN;
127}
128
129static int do_sigbus(struct pt_regs *regs, unsigned long address)
130{
131 siginfo_t info;
132
133 up_read(&current->mm->mmap_sem);
134
135 if (user_mode(regs)) {
136 info.si_signo = SIGBUS;
137 info.si_errno = 0;
138 info.si_code = BUS_ADRERR;
139 info.si_addr = (void __user *)address;
140 force_sig_info(SIGBUS, &info, current);
141 return MM_FAULT_RETURN;
142 }
143 return MM_FAULT_ERR(SIGBUS);
144}
145
146static int mm_fault_error(struct pt_regs *regs, unsigned long addr, int fault)
147{
148 /*
149 * Pagefault was interrupted by SIGKILL. We have no reason to
150 * continue the pagefault.
151 */
152 if (fatal_signal_pending(current)) {
153 /*
154 * If we have retry set, the mmap semaphore will have
155 * alrady been released in __lock_page_or_retry(). Else
156 * we release it now.
157 */
158 if (!(fault & VM_FAULT_RETRY))
159 up_read(&current->mm->mmap_sem);
160 /* Coming from kernel, we need to deal with uaccess fixups */
161 if (user_mode(regs))
162 return MM_FAULT_RETURN;
163 return MM_FAULT_ERR(SIGKILL);
164 }
165
166 /* No fault: be happy */
167 if (!(fault & VM_FAULT_ERROR))
168 return MM_FAULT_CONTINUE;
169
170 /* Out of memory */
171 if (fault & VM_FAULT_OOM)
172 return out_of_memory(regs);
173
174 /* Bus error. x86 handles HWPOISON here, we'll add this if/when
175 * we support the feature in HW
176 */
177 if (fault & VM_FAULT_SIGBUS)
178 return do_sigbus(regs, addr);
179
180 /* We don't understand the fault code, this is fatal */
181 BUG();
182 return MM_FAULT_CONTINUE;
183}
108 184
109/* 185/*
110 * For 600- and 800-family processors, the error_code parameter is DSISR 186 * For 600- and 800-family processors, the error_code parameter is DSISR
@@ -124,11 +200,12 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
124{ 200{
125 struct vm_area_struct * vma; 201 struct vm_area_struct * vma;
126 struct mm_struct *mm = current->mm; 202 struct mm_struct *mm = current->mm;
127 siginfo_t info; 203 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
128 int code = SEGV_MAPERR; 204 int code = SEGV_MAPERR;
129 int is_write = 0, ret; 205 int is_write = 0;
130 int trap = TRAP(regs); 206 int trap = TRAP(regs);
131 int is_exec = trap == 0x400; 207 int is_exec = trap == 0x400;
208 int fault;
132 209
133#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) 210#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
134 /* 211 /*
@@ -145,6 +222,9 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
145 is_write = error_code & ESR_DST; 222 is_write = error_code & ESR_DST;
146#endif /* CONFIG_4xx || CONFIG_BOOKE */ 223#endif /* CONFIG_4xx || CONFIG_BOOKE */
147 224
225 if (is_write)
226 flags |= FAULT_FLAG_WRITE;
227
148#ifdef CONFIG_PPC_ICSWX 228#ifdef CONFIG_PPC_ICSWX
149 /* 229 /*
150 * we need to do this early because this "data storage 230 * we need to do this early because this "data storage
@@ -152,13 +232,11 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
152 * look at it 232 * look at it
153 */ 233 */
154 if (error_code & ICSWX_DSI_UCT) { 234 if (error_code & ICSWX_DSI_UCT) {
155 int ret; 235 int rc = acop_handle_fault(regs, address, error_code);
156 236 if (rc)
157 ret = acop_handle_fault(regs, address, error_code); 237 return rc;
158 if (ret)
159 return ret;
160 } 238 }
161#endif 239#endif /* CONFIG_PPC_ICSWX */
162 240
163 if (notify_page_fault(regs)) 241 if (notify_page_fault(regs))
164 return 0; 242 return 0;
@@ -179,6 +257,10 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
179 } 257 }
180#endif 258#endif
181 259
260 /* We restore the interrupt state now */
261 if (!arch_irq_disabled_regs(regs))
262 local_irq_enable();
263
182 if (in_atomic() || mm == NULL) { 264 if (in_atomic() || mm == NULL) {
183 if (!user_mode(regs)) 265 if (!user_mode(regs))
184 return SIGSEGV; 266 return SIGSEGV;
@@ -212,7 +294,15 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
212 if (!user_mode(regs) && !search_exception_tables(regs->nip)) 294 if (!user_mode(regs) && !search_exception_tables(regs->nip))
213 goto bad_area_nosemaphore; 295 goto bad_area_nosemaphore;
214 296
297retry:
215 down_read(&mm->mmap_sem); 298 down_read(&mm->mmap_sem);
299 } else {
300 /*
301 * The above down_read_trylock() might have succeeded in
302 * which case we'll have missed the might_sleep() from
303 * down_read():
304 */
305 might_sleep();
216 } 306 }
217 307
218 vma = find_vma(mm, address); 308 vma = find_vma(mm, address);
@@ -327,30 +417,43 @@ good_area:
327 * make sure we exit gracefully rather than endlessly redo 417 * make sure we exit gracefully rather than endlessly redo
328 * the fault. 418 * the fault.
329 */ 419 */
330 ret = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); 420 fault = handle_mm_fault(mm, vma, address, flags);
331 if (unlikely(ret & VM_FAULT_ERROR)) { 421 if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
332 if (ret & VM_FAULT_OOM) 422 int rc = mm_fault_error(regs, address, fault);
333 goto out_of_memory; 423 if (rc >= MM_FAULT_RETURN)
334 else if (ret & VM_FAULT_SIGBUS) 424 return rc;
335 goto do_sigbus;
336 BUG();
337 } 425 }
338 if (ret & VM_FAULT_MAJOR) { 426
339 current->maj_flt++; 427 /*
340 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 428 * Major/minor page fault accounting is only done on the
341 regs, address); 429 * initial attempt. If we go through a retry, it is extremely
430 * likely that the page will be found in page cache at that point.
431 */
432 if (flags & FAULT_FLAG_ALLOW_RETRY) {
433 if (fault & VM_FAULT_MAJOR) {
434 current->maj_flt++;
435 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1,
436 regs, address);
342#ifdef CONFIG_PPC_SMLPAR 437#ifdef CONFIG_PPC_SMLPAR
343 if (firmware_has_feature(FW_FEATURE_CMO)) { 438 if (firmware_has_feature(FW_FEATURE_CMO)) {
344 preempt_disable(); 439 preempt_disable();
345 get_lppaca()->page_ins += (1 << PAGE_FACTOR); 440 get_lppaca()->page_ins += (1 << PAGE_FACTOR);
346 preempt_enable(); 441 preempt_enable();
442 }
443#endif /* CONFIG_PPC_SMLPAR */
444 } else {
445 current->min_flt++;
446 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
447 regs, address);
448 }
449 if (fault & VM_FAULT_RETRY) {
450 /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
451 * of starvation. */
452 flags &= ~FAULT_FLAG_ALLOW_RETRY;
453 goto retry;
347 } 454 }
348#endif
349 } else {
350 current->min_flt++;
351 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1,
352 regs, address);
353 } 455 }
456
354 up_read(&mm->mmap_sem); 457 up_read(&mm->mmap_sem);
355 return 0; 458 return 0;
356 459
@@ -371,28 +474,6 @@ bad_area_nosemaphore:
371 474
372 return SIGSEGV; 475 return SIGSEGV;
373 476
374/*
375 * We ran out of memory, or some other thing happened to us that made
376 * us unable to handle the page fault gracefully.
377 */
378out_of_memory:
379 up_read(&mm->mmap_sem);
380 if (!user_mode(regs))
381 return SIGKILL;
382 pagefault_out_of_memory();
383 return 0;
384
385do_sigbus:
386 up_read(&mm->mmap_sem);
387 if (user_mode(regs)) {
388 info.si_signo = SIGBUS;
389 info.si_errno = 0;
390 info.si_code = BUS_ADRERR;
391 info.si_addr = (void __user *)address;
392 force_sig_info(SIGBUS, &info, current);
393 return 0;
394 }
395 return SIGBUS;
396} 477}
397 478
398/* 479/*