4.4-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lorenzo Stoakes <lstoa...@gmail.com>

commit 7f23b3504a0df63b724180262c5f3f117f21bcae upstream.

This removes the 'write' and 'force' from get_vaddr_frames() and
replaces them with 'gup_flags' to make the use of FOLL_FORCE explicit in
callers as use of this flag can result in surprising behaviour (and
hence bugs) within the mm subsystem.

Signed-off-by: Lorenzo Stoakes <lstoa...@gmail.com>
Acked-by: Michal Hocko <mho...@suse.com>
Reviewed-by: Jan Kara <j...@suse.cz>
Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
Signed-off-by: Ben Hutchings <ben.hutchi...@codethink.co.uk>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/gpu/drm/exynos/exynos_drm_g2d.c    |    3 ++-
 drivers/media/platform/omap/omap_vout.c    |    2 +-
 drivers/media/v4l2-core/videobuf2-memops.c |    6 +++++-
 include/linux/mm.h                         |    2 +-
 mm/frame_vector.c                          |   13 ++-----------
 5 files changed, 11 insertions(+), 15 deletions(-)

--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -471,7 +471,8 @@ static dma_addr_t *g2d_userptr_get_dma_a
                goto err_free;
        }
 
-       ret = get_vaddr_frames(start, npages, true, true, g2d_userptr->vec);
+       ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
+               g2d_userptr->vec);
        if (ret != npages) {
                DRM_ERROR("failed to get user pages from userptr.\n");
                if (ret < 0)
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -214,7 +214,7 @@ static int omap_vout_get_userptr(struct
        if (!vec)
                return -ENOMEM;
 
-       ret = get_vaddr_frames(virtp, 1, true, false, vec);
+       ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
        if (ret != 1) {
                frame_vector_destroy(vec);
                return -EINVAL;
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -42,6 +42,10 @@ struct frame_vector *vb2_create_framevec
        unsigned long first, last;
        unsigned long nr;
        struct frame_vector *vec;
+       unsigned int flags = FOLL_FORCE;
+
+       if (write)
+               flags |= FOLL_WRITE;
 
        first = start >> PAGE_SHIFT;
        last = (start + length - 1) >> PAGE_SHIFT;
@@ -49,7 +53,7 @@ struct frame_vector *vb2_create_framevec
        vec = frame_vector_create(nr);
        if (!vec)
                return ERR_PTR(-ENOMEM);
-       ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec);
+       ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec);
        if (ret < 0)
                goto out_destroy;
        /* We accept only complete set of PFNs */
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1227,7 +1227,7 @@ struct frame_vector {
 struct frame_vector *frame_vector_create(unsigned int nr_frames);
 void frame_vector_destroy(struct frame_vector *vec);
 int get_vaddr_frames(unsigned long start, unsigned int nr_pfns,
-                    bool write, bool force, struct frame_vector *vec);
+                    unsigned int gup_flags, struct frame_vector *vec);
 void put_vaddr_frames(struct frame_vector *vec);
 int frame_vector_to_pages(struct frame_vector *vec);
 void frame_vector_to_pfns(struct frame_vector *vec);
--- a/mm/frame_vector.c
+++ b/mm/frame_vector.c
@@ -11,10 +11,7 @@
  * get_vaddr_frames() - map virtual addresses to pfns
  * @start:     starting user address
  * @nr_frames: number of pages / pfns from start to map
- * @write:     whether pages will be written to by the caller
- * @force:     whether to force write access even if user mapping is
- *             readonly. See description of the same argument of
-               get_user_pages().
+ * @gup_flags: flags modifying lookup behaviour
  * @vec:       structure which receives pages / pfns of the addresses mapped.
  *             It should have space for at least nr_frames entries.
  *
@@ -34,23 +31,17 @@
  * This function takes care of grabbing mmap_sem as necessary.
  */
 int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
-                    bool write, bool force, struct frame_vector *vec)
+                    unsigned int gup_flags, struct frame_vector *vec)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
        int ret = 0;
        int err;
        int locked;
-       unsigned int gup_flags = 0;
 
        if (nr_frames == 0)
                return 0;
 
-       if (write)
-               gup_flags |= FOLL_WRITE;
-       if (force)
-               gup_flags |= FOLL_FORCE;
-
        if (WARN_ON_ONCE(nr_frames > vec->nr_allocated))
                nr_frames = vec->nr_allocated;
 


Reply via email to