Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9beae1ea authored by Lorenzo Stoakes's avatar Lorenzo Stoakes Committed by Linus Torvalds
Browse files

mm: replace get_user_pages_remote() write/force parameters with gup_flags



This removes the 'write' and 'force' from get_user_pages_remote() 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: default avatarLorenzo Stoakes <lstoakes@gmail.com>
Acked-by: default avatarMichal Hocko <mhocko@suse.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 768ae309
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -748,19 +748,22 @@ static struct page **etnaviv_gem_userptr_do_get_pages(
	int ret = 0, pinned, npages = etnaviv_obj->base.size >> PAGE_SHIFT;
	struct page **pvec;
	uintptr_t ptr;
	unsigned int flags = 0;

	pvec = drm_malloc_ab(npages, sizeof(struct page *));
	if (!pvec)
		return ERR_PTR(-ENOMEM);

	if (!etnaviv_obj->userptr.ro)
		flags |= FOLL_WRITE;

	pinned = 0;
	ptr = etnaviv_obj->userptr.ptr;

	down_read(&mm->mmap_sem);
	while (pinned < npages) {
		ret = get_user_pages_remote(task, mm, ptr, npages - pinned,
					    !etnaviv_obj->userptr.ro, 0,
					    pvec + pinned, NULL);
					    flags, pvec + pinned, NULL);
		if (ret < 0)
			break;

+5 −1
Original line number Diff line number Diff line
@@ -508,6 +508,10 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
	pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY);
	if (pvec != NULL) {
		struct mm_struct *mm = obj->userptr.mm->mm;
		unsigned int flags = 0;

		if (!obj->userptr.read_only)
			flags |= FOLL_WRITE;

		ret = -EFAULT;
		if (atomic_inc_not_zero(&mm->mm_users)) {
@@ -517,7 +521,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
					(work->task, mm,
					 obj->userptr.ptr + pinned * PAGE_SIZE,
					 npages - pinned,
					 !obj->userptr.read_only, 0,
					 flags,
					 pvec + pinned, NULL);
				if (ret < 0)
					break;
+5 −2
Original line number Diff line number Diff line
@@ -527,6 +527,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
	u64 off;
	int j, k, ret = 0, start_idx, npages = 0;
	u64 base_virt_addr;
	unsigned int flags = 0;

	if (access_mask == 0)
		return -EINVAL;
@@ -556,6 +557,9 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
		goto out_put_task;
	}

	if (access_mask & ODP_WRITE_ALLOWED_BIT)
		flags |= FOLL_WRITE;

	start_idx = (user_virt - ib_umem_start(umem)) >> PAGE_SHIFT;
	k = start_idx;

@@ -574,8 +578,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
		 */
		npages = get_user_pages_remote(owning_process, owning_mm,
				user_virt, gup_num_pages,
				access_mask & ODP_WRITE_ALLOWED_BIT,
				0, local_page_list, NULL);
				flags, local_page_list, NULL);
		up_read(&owning_mm->mmap_sem);

		if (npages < 0)
+7 −2
Original line number Diff line number Diff line
@@ -191,6 +191,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
{
	struct page *page;
	int ret;
	unsigned int gup_flags = FOLL_FORCE;

#ifdef CONFIG_STACK_GROWSUP
	if (write) {
@@ -199,12 +200,16 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
			return NULL;
	}
#endif

	if (write)
		gup_flags |= FOLL_WRITE;

	/*
	 * We are doing an exec().  'current' is the process
	 * doing the exec and bprm->mm is the new process's mm.
	 */
	ret = get_user_pages_remote(current, bprm->mm, pos, 1, write,
			1, &page, NULL);
	ret = get_user_pages_remote(current, bprm->mm, pos, 1, gup_flags,
			&page, NULL);
	if (ret <= 0)
		return NULL;

+1 −1
Original line number Diff line number Diff line
@@ -1276,7 +1276,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
		      struct vm_area_struct **vmas, int *nonblocking);
long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
			    unsigned long start, unsigned long nr_pages,
			    int write, int force, struct page **pages,
			    unsigned int gup_flags, struct page **pages,
			    struct vm_area_struct **vmas);
long get_user_pages(unsigned long start, unsigned long nr_pages,
			    unsigned int gup_flags, struct page **pages,
Loading