mm/huge_memory.c: use head to emphasize the purpose of page
[linux-2.6-microblaze.git] / fs / userfaultfd.c
index d7f54e5..37df7c9 100644 (file)
@@ -1460,7 +1460,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
                        start = vma->vm_start;
                vma_end = min(end, vma->vm_end);
 
-               new_flags = (vma->vm_flags & ~vm_flags) | vm_flags;
+               new_flags = (vma->vm_flags &
+                            ~(VM_UFFD_MISSING|VM_UFFD_WP)) | vm_flags;
                prev = vma_merge(mm, prev, start, vma_end, new_flags,
                                 vma->anon_vma, vma->vm_file, vma->vm_pgoff,
                                 vma_policy(vma),
@@ -1834,13 +1835,12 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        if (copy_from_user(&uffdio_api, buf, sizeof(uffdio_api)))
                goto out;
        features = uffdio_api.features;
-       if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES)) {
-               memset(&uffdio_api, 0, sizeof(uffdio_api));
-               if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api)))
-                       goto out;
-               ret = -EINVAL;
-               goto out;
-       }
+       ret = -EINVAL;
+       if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES))
+               goto err_out;
+       ret = -EPERM;
+       if ((features & UFFD_FEATURE_EVENT_FORK) && !capable(CAP_SYS_PTRACE))
+               goto err_out;
        /* report all available features and ioctls to userland */
        uffdio_api.features = UFFD_API_FEATURES;
        uffdio_api.ioctls = UFFD_API_IOCTLS;
@@ -1853,6 +1853,11 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,
        ret = 0;
 out:
        return ret;
+err_out:
+       memset(&uffdio_api, 0, sizeof(uffdio_api));
+       if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api)))
+               ret = -EFAULT;
+       goto out;
 }
 
 static long userfaultfd_ioctl(struct file *file, unsigned cmd,