aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/arch/x86/mm/fault.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-11-03 12:30:12 +0100
committerIngo Molnar <mingo@kernel.org>2017-11-03 12:30:12 +0100
commit294cbd05e32990c3b1a62be27441fc719edebbab (patch)
tree9e543bcfdaa183343f18714a256d3fd5c88d3b5c /arch/x86/mm/fault.c
parentperf/cgroup: Fix perf cgroup hierarchy support (diff)
parentKbuild: don't pass "-C" to preprocessor when processing linker scripts (diff)
downloadwireguard-linux-294cbd05e32990c3b1a62be27441fc719edebbab.tar.xz
wireguard-linux-294cbd05e32990c3b1a62be27441fc719edebbab.zip
Merge branch 'linus' into perf/urgent, to pick up dependent commits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to '')
-rw-r--r--arch/x86/mm/fault.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index e2baeaa053a5..b0ff378650a9 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 1995 Linus Torvalds
* Copyright (C) 2001, 2002 Andi Kleen, SuSE Labs.
@@ -1440,7 +1441,17 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault. Since we never set FAULT_FLAG_RETRY_NOWAIT, if
* we get VM_FAULT_RETRY back, the mmap_sem has been unlocked.
+ *
+ * Note that handle_userfault() may also release and reacquire mmap_sem
+ * (and not return with VM_FAULT_RETRY), when returning to userland to
+ * repeat the page fault later with a VM_FAULT_NOPAGE retval
+ * (potentially after handling any pending signal during the return to
+ * userland). The return to userland is identified whenever
+ * FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags.
+ * Thus we have to be careful about not touching vma after handling the
+ * fault, so we read the pkey beforehand.
*/
+ pkey = vma_pkey(vma);
fault = handle_mm_fault(vma, address, flags);
major |= fault & VM_FAULT_MAJOR;
@@ -1467,7 +1478,6 @@ good_area:
return;
}
- pkey = vma_pkey(vma);
up_read(&mm->mmap_sem);
if (unlikely(fault & VM_FAULT_ERROR)) {
mm_fault_error(regs, error_code, address, &pkey, fault);