From: Dave Hansen <[email protected]>

This code matches a fault condition up with the VMA and ensures
that the VMA allows the fault to be handled instead of just
erroring out.

We will be extending this in a moment to comprehend protection
keys.

Signed-off-by: Dave Hansen <[email protected]>
Reviewed-by: Thomas Gleixner <[email protected]>
---

 b/mm/gup.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff -puN mm/gup.c~pkeys-10-pte-fault mm/gup.c
--- a/mm/gup.c~pkeys-10-pte-fault       2016-02-12 10:44:21.164472103 -0800
+++ b/mm/gup.c  2016-02-12 10:44:21.167472240 -0800
@@ -610,6 +610,18 @@ next_page:
 }
 EXPORT_SYMBOL(__get_user_pages);
 
+bool vma_permits_fault(struct vm_area_struct *vma, unsigned int fault_flags)
+{
+       vm_flags_t vm_flags;
+
+       vm_flags = (fault_flags & FAULT_FLAG_WRITE) ? VM_WRITE : VM_READ;
+
+       if (!(vm_flags & vma->vm_flags))
+               return false;
+
+       return true;
+}
+
 /*
  * fixup_user_fault() - manually resolve a user page fault
  * @tsk:       the task_struct to use for page fault accounting, or
@@ -645,7 +657,6 @@ int fixup_user_fault(struct task_struct
                     bool *unlocked)
 {
        struct vm_area_struct *vma;
-       vm_flags_t vm_flags;
        int ret, major = 0;
 
        if (unlocked)
@@ -656,8 +667,7 @@ retry:
        if (!vma || address < vma->vm_start)
                return -EFAULT;
 
-       vm_flags = (fault_flags & FAULT_FLAG_WRITE) ? VM_WRITE : VM_READ;
-       if (!(vm_flags & vma->vm_flags))
+       if (!vma_permits_fault(vma, fault_flags))
                return -EFAULT;
 
        ret = handle_mm_fault(mm, vma, address, fault_flags);
_

Reply via email to