diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index 34a1d35995ef..4602326b8f5b 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c @@ -18,6 +18,7 @@ #include #include #include +#include #ifdef __x86_64__ # define VSYS(x) (x) @@ -459,6 +460,38 @@ static int test_vsys_x(void) return 0; } +static int test_process_vm_readv(void) +{ +#ifdef __x86_64__ + char buf[4096]; + struct iovec local, remote; + int ret; + + printf("[RUN]\tprocess_vm_readv() from vsyscall page\n"); + + local.iov_base = buf; + local.iov_len = 4096; + remote.iov_base = (void *)0xffffffffff600000; + 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; + } + + if (vsyscall_map_r) { + if (!memcmp(buf, (const void *)0xffffffffff600000, 4096)) { + printf("[OK]\tIt worked and read correct data\n"); + } else { + printf("[FAIL]\tIt worked but returned incorrect data\n"); + return 1; + } + } +#endif + + return 0; +} + #ifdef __x86_64__ #define X86_EFLAGS_TF (1UL << 8) static volatile sig_atomic_t num_vsyscall_traps; @@ -533,6 +566,8 @@ int main(int argc, char **argv) nerrs += test_vsys_r(); nerrs += test_vsys_x(); + nerrs += test_process_vm_readv(); + #ifdef __x86_64__ nerrs += test_emulation(); #endif