summaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorAndrea Arcangeli <aarcange@redhat.com>2015-09-04 18:46:20 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-04 19:54:41 -0400
commit6b251fc96cf2cdf1ce4b5db055547e2a5679bc77 (patch)
tree5c5fdd9cdcd1d67ff74b1ac533e5362567b65098 /mm/memory.c
parent16ba6f811dfe44bc14f7946a4b257b85476fc16e (diff)
userfaultfd: call handle_userfault() for userfaultfd_missing() faults
This is where the page faults must be modified to call handle_userfault() if userfaultfd_missing() is true (so if the vma->vm_flags had VM_UFFD_MISSING set). handle_userfault() then takes care of blocking the page fault and delivering it to userland. The fault flags must also be passed as parameter so the "read|write" kind of fault can be passed to userland. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Acked-by: Pavel Emelyanov <xemul@parallels.com> Cc: Sanidhya Kashyap <sanidhya.gatech@gmail.com> Cc: zhang.zhanghailiang@huawei.com Cc: "Kirill A. Shutemov" <kirill@shutemov.name> Cc: Andres Lagar-Cavilla <andreslc@google.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Rik van Riel <riel@redhat.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Hugh Dickins <hughd@google.com> Cc: Peter Feiner <pfeiner@google.com> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: "Huangpeng (Peter)" <peter.huangpeng@huawei.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 388dcf9aa283..2961fb654369 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -61,6 +61,7 @@
61#include <linux/string.h> 61#include <linux/string.h>
62#include <linux/dma-debug.h> 62#include <linux/dma-debug.h>
63#include <linux/debugfs.h> 63#include <linux/debugfs.h>
64#include <linux/userfaultfd_k.h>
64 65
65#include <asm/io.h> 66#include <asm/io.h>
66#include <asm/pgalloc.h> 67#include <asm/pgalloc.h>
@@ -2685,6 +2686,12 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
2685 page_table = pte_offset_map_lock(mm, pmd, address, &ptl); 2686 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
2686 if (!pte_none(*page_table)) 2687 if (!pte_none(*page_table))
2687 goto unlock; 2688 goto unlock;
2689 /* Deliver the page fault to userland, check inside PT lock */
2690 if (userfaultfd_missing(vma)) {
2691 pte_unmap_unlock(page_table, ptl);
2692 return handle_userfault(vma, address, flags,
2693 VM_UFFD_MISSING);
2694 }
2688 goto setpte; 2695 goto setpte;
2689 } 2696 }
2690 2697
@@ -2713,6 +2720,15 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
2713 if (!pte_none(*page_table)) 2720 if (!pte_none(*page_table))
2714 goto release; 2721 goto release;
2715 2722
2723 /* Deliver the page fault to userland, check inside PT lock */
2724 if (userfaultfd_missing(vma)) {
2725 pte_unmap_unlock(page_table, ptl);
2726 mem_cgroup_cancel_charge(page, memcg);
2727 page_cache_release(page);
2728 return handle_userfault(vma, address, flags,
2729 VM_UFFD_MISSING);
2730 }
2731
2716 inc_mm_counter_fast(mm, MM_ANONPAGES); 2732 inc_mm_counter_fast(mm, MM_ANONPAGES);
2717 page_add_new_anon_rmap(page, vma, address); 2733 page_add_new_anon_rmap(page, vma, address);
2718 mem_cgroup_commit_charge(page, memcg, false); 2734 mem_cgroup_commit_charge(page, memcg, false);