Commit 8381979d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'gate-page-refcount' (patches from Dave Hansen)

Merge gate page refcount fix from Dave Hansen:
 "During the conversion over to pin_user_pages(), gate pages were missed.

  The fix is pretty simple, and is accompanied by a new test from Andy
  which probably would have caught this earlier"

* emailed patches from Dave Hansen <dave.hansen@linux.intel.com>:
  selftests/x86/test_vsyscall: Improve the process_vm_readv() test
  mm: fix pin vs. gup mismatch with gate pages
parents e28f0104 8891adc6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -843,7 +843,7 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
			goto unmap;
		*page = pte_page(*pte);
	}
	if (unlikely(!try_get_page(*page))) {
	if (unlikely(!try_grab_page(*page, gup_flags))) {
		ret = -ENOMEM;
		goto unmap;
	}
+20 −2
Original line number Diff line number Diff line
@@ -462,6 +462,17 @@ static int test_vsys_x(void)
	return 0;
}

/*
 * Debuggers expect ptrace() to be able to peek at the vsyscall page.
 * Use process_vm_readv() as a proxy for ptrace() to test this.  We
 * want it to work in the vsyscall=emulate case and to fail in the
 * vsyscall=xonly case.
 *
 * It's worth noting that this ABI is a bit nutty.  write(2) can't
 * read from the vsyscall page on any kernel version or mode.  The
 * fact that ptrace() ever worked was a nice courtesy of old kernels,
 * but the code to support it is fairly gross.
 */
static int test_process_vm_readv(void)
{
#ifdef __x86_64__
@@ -477,8 +488,12 @@ static int test_process_vm_readv(void)
	remote.iov_len = 4096;
	ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0);
	if (ret != 4096) {
		printf("[OK]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", ret, errno);
		return 0;
		/*
		 * We expect process_vm_readv() to work if and only if the
		 * vsyscall page is readable.
		 */
		printf("[%s]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", vsyscall_map_r ? "FAIL" : "OK", ret, errno);
		return vsyscall_map_r ? 1 : 0;
	}

	if (vsyscall_map_r) {
@@ -488,6 +503,9 @@ static int test_process_vm_readv(void)
			printf("[FAIL]\tIt worked but returned incorrect data\n");
			return 1;
		}
	} else {
		printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n");
		return 1;
	}
#endif