--- /dev/null
+From 7fb08eca45270d0ae86e1ad9d39c40b7a55d0190 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Mon, 15 Dec 2014 14:46:06 -0800
+Subject: x86: mm: move mmap_sem unlock from mm_fault_error() to caller
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 7fb08eca45270d0ae86e1ad9d39c40b7a55d0190 upstream.
+
+This replaces four copies in various stages of mm_fault_error() handling
+with just a single one. It will also allow for more natural placement
+of the unlocking after some further cleanup.
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/mm/fault.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -844,11 +844,8 @@ do_sigbus(struct pt_regs *regs, unsigned
+ unsigned int fault)
+ {
+ struct task_struct *tsk = current;
+- struct mm_struct *mm = tsk->mm;
+ int code = BUS_ADRERR;
+
+- up_read(&mm->mmap_sem);
+-
+ /* Kernel mode? Handle exceptions or die: */
+ if (!(error_code & PF_USER)) {
+ no_context(regs, error_code, address, SIGBUS, BUS_ADRERR);
+@@ -879,7 +876,6 @@ mm_fault_error(struct pt_regs *regs, uns
+ unsigned long address, unsigned int fault)
+ {
+ if (fatal_signal_pending(current) && !(error_code & PF_USER)) {
+- up_read(¤t->mm->mmap_sem);
+ no_context(regs, error_code, address, 0, 0);
+ return;
+ }
+@@ -887,14 +883,11 @@ mm_fault_error(struct pt_regs *regs, uns
+ if (fault & VM_FAULT_OOM) {
+ /* Kernel mode? Handle exceptions or die: */
+ if (!(error_code & PF_USER)) {
+- up_read(¤t->mm->mmap_sem);
+ no_context(regs, error_code, address,
+ SIGSEGV, SEGV_MAPERR);
+ return;
+ }
+
+- up_read(¤t->mm->mmap_sem);
+-
+ /*
+ * We ran out of memory, call the OOM killer, and return the
+ * userspace (which will retry the fault, or kill us if we got
+@@ -1249,6 +1242,7 @@ good_area:
+ return;
+
+ if (unlikely(fault & VM_FAULT_ERROR)) {
++ up_read(&mm->mmap_sem);
+ mm_fault_error(regs, error_code, address, fault);
+ return;
+ }