Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+21 -3
+1 -1
mm/gup.c
··· 843 843 goto unmap; 844 844 *page = pte_page(*pte); 845 845 } 846 - if (unlikely(!try_get_page(*page))) { 846 + if (unlikely(!try_grab_page(*page, gup_flags))) { 847 847 ret = -ENOMEM; 848 848 goto unmap; 849 849 }
+20 -2
tools/testing/selftests/x86/test_vsyscall.c
··· 462 462 return 0; 463 463 } 464 464 465 + /* 466 + * Debuggers expect ptrace() to be able to peek at the vsyscall page. 467 + * Use process_vm_readv() as a proxy for ptrace() to test this. We 468 + * want it to work in the vsyscall=emulate case and to fail in the 469 + * vsyscall=xonly case. 470 + * 471 + * It's worth noting that this ABI is a bit nutty. write(2) can't 472 + * read from the vsyscall page on any kernel version or mode. The 473 + * fact that ptrace() ever worked was a nice courtesy of old kernels, 474 + * but the code to support it is fairly gross. 475 + */ 465 476 static int test_process_vm_readv(void) 466 477 { 467 478 #ifdef __x86_64__ ··· 488 477 remote.iov_len = 4096; 489 478 ret = process_vm_readv(getpid(), &local, 1, &remote, 1, 0); 490 479 if (ret != 4096) { 491 - printf("[OK]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", ret, errno); 492 - return 0; 480 + /* 481 + * We expect process_vm_readv() to work if and only if the 482 + * vsyscall page is readable. 483 + */ 484 + printf("[%s]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", vsyscall_map_r ? "FAIL" : "OK", ret, errno); 485 + return vsyscall_map_r ? 1 : 0; 493 486 } 494 487 495 488 if (vsyscall_map_r) { ··· 503 488 printf("[FAIL]\tIt worked but returned incorrect data\n"); 504 489 return 1; 505 490 } 491 + } else { 492 + printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n"); 493 + return 1; 506 494 } 507 495 #endif 508 496