summaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/fault_64.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-18 15:57:31 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-18 15:57:31 -0700
commit665ab0f3c8b8f86bb77b25285ac93870c7054d63 (patch)
treec7d12c3559982eb3fb1847438d4b45ce034851e5 /arch/sparc/mm/fault_64.c
parentbf03f65b7967df5807ddef7b99f8a41d4c94fc70 (diff)
parente816b57a337ea3b755de72bec38c10c864f23015 (diff)
downloadblackbird-obmc-linux-665ab0f3c8b8f86bb77b25285ac93870c7054d63.tar.gz
blackbird-obmc-linux-665ab0f3c8b8f86bb77b25285ac93870c7054d63.zip
Merge 3.4-rc3 into tty-next
This allows us to pick up some changes needed for other serial patches. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/sparc/mm/fault_64.c')
-rw-r--r--arch/sparc/mm/fault_64.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 504c0622f729..1fe0429b6314 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
unsigned int insn = 0;
int si_code, fault_code, fault;
unsigned long address, mm_rss;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
fault_code = get_thread_fault_code();
@@ -333,6 +334,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
insn = get_fault_insn(regs, insn);
goto handle_kernel_fault;
}
+
+retry:
down_read(&mm->mmap_sem);
}
@@ -423,7 +426,12 @@ good_area:
goto bad_area;
}
- fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
+ flags |= ((fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
+ fault = handle_mm_fault(mm, vma, address, flags);
+
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return;
+
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -431,12 +439,27 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR) {
- current->maj_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
- } else {
- current->min_flt++;
- perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
+
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR) {
+ current->maj_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,
+ 1, regs, address);
+ } else {
+ current->min_flt++;
+ perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
+ 1, regs, address);
+ }
+ if (fault & VM_FAULT_RETRY) {
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+ /* No need to up_read(&mm->mmap_sem) as we would
+ * have already released it in __lock_page_or_retry
+ * in mm/filemap.c.
+ */
+
+ goto retry;
+ }
}
up_read(&mm->mmap_sem);
OpenPOWER on IntegriCloud