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

Commit 442486ec authored by Lorenzo Stoakes's avatar Lorenzo Stoakes Committed by Linus Torvalds
Browse files

mm: replace __access_remote_vm() write parameter with gup_flags



This removes the 'write' argument from __access_remote_vm() and replaces
it with 'gup_flags' as use of this function previously silently implied
FOLL_FORCE, whereas after this patch callers explicitly pass this flag.

We make this explicit as use of FOLL_FORCE 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>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9beae1ea
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -3869,14 +3869,11 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
 * given task for page fault accounting.
 */
static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
		unsigned long addr, void *buf, int len, int write)
		unsigned long addr, void *buf, int len, unsigned int gup_flags)
{
	struct vm_area_struct *vma;
	void *old_buf = buf;
	unsigned int flags = FOLL_FORCE;

	if (write)
		flags |= FOLL_WRITE;
	int write = gup_flags & FOLL_WRITE;

	down_read(&mm->mmap_sem);
	/* ignore errors, just check how much was successfully transferred */
@@ -3886,7 +3883,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
		struct page *page = NULL;

		ret = get_user_pages_remote(tsk, mm, addr, 1,
				flags, &page, &vma);
				gup_flags, &page, &vma);
		if (ret <= 0) {
#ifndef CONFIG_HAVE_IOREMAP_PROT
			break;
@@ -3945,7 +3942,12 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
int access_remote_vm(struct mm_struct *mm, unsigned long addr,
		void *buf, int len, int write)
{
	return __access_remote_vm(NULL, mm, addr, buf, len, write);
	unsigned int flags = FOLL_FORCE;

	if (write)
		flags |= FOLL_WRITE;

	return __access_remote_vm(NULL, mm, addr, buf, len, flags);
}

/*
@@ -3958,12 +3960,17 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr,
{
	struct mm_struct *mm;
	int ret;
	unsigned int flags = FOLL_FORCE;

	mm = get_task_mm(tsk);
	if (!mm)
		return 0;

	ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
	if (write)
		flags |= FOLL_WRITE;

	ret = __access_remote_vm(tsk, mm, addr, buf, len, flags);

	mmput(mm);

	return ret;
+6 −3
Original line number Diff line number Diff line
@@ -1809,9 +1809,10 @@ void filemap_map_pages(struct fault_env *fe,
EXPORT_SYMBOL(filemap_map_pages);

static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
		unsigned long addr, void *buf, int len, int write)
		unsigned long addr, void *buf, int len, unsigned int gup_flags)
{
	struct vm_area_struct *vma;
	int write = gup_flags & FOLL_WRITE;

	down_read(&mm->mmap_sem);

@@ -1853,7 +1854,8 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
int access_remote_vm(struct mm_struct *mm, unsigned long addr,
		void *buf, int len, int write)
{
	return __access_remote_vm(NULL, mm, addr, buf, len, write);
	return __access_remote_vm(NULL, mm, addr, buf, len,
			write ? FOLL_WRITE : 0);
}

/*
@@ -1871,7 +1873,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
	if (!mm)
		return 0;

	len = __access_remote_vm(tsk, mm, addr, buf, len, write);
	len = __access_remote_vm(tsk, mm, addr, buf, len,
			write ? FOLL_WRITE : 0);

	mmput(mm);
	return len;