From c7ef9c84dce87a8bea54776326f4205e03389f5a Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Tue, 1 Sep 2020 07:49:56 +0000 Subject: VTS: kselftest rtctest Only enforce test if an RTC is present. Exempt-From-Owner-Approval: smuckle is out Bug: 81352189 Test: linux-kselftest$ mma && adb sync data && adb shell ./data/nativetest/linux-kselftest/rtc/rtctest Change-Id: I7363cf9837f3a1ea10d6fc82b025ee7336c3c4ce --- tools/testing/selftests/rtc/rtctest.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c index d82bd8cd937e..2c61bd22e26e 100644 --- a/tools/testing/selftests/rtc/rtctest.c +++ b/tools/testing/selftests/rtc/rtctest.c @@ -5,11 +5,13 @@ * Copyright (c) 2018 Alexandre Belloni */ +#include #include #include #include #include #include +#include #include #include #include @@ -23,6 +25,25 @@ static char *rtc_file = "/dev/rtc0"; +/* Returns 1 if file matching /dev/rtc* is found, else 0. */ +static int has_rtc(void) +{ + DIR *dev_dir; + struct dirent *dir; + + dev_dir = opendir("/dev"); + if (!dev_dir) + return 0; + while ((dir = readdir(dev_dir))) { + if (!strncmp(dir->d_name, "rtc", 3)) { + closedir(dev_dir); + return 1; + } + } + closedir(dev_dir); + return 0; +} + FIXTURE(rtc) { int fd; }; @@ -40,6 +61,9 @@ TEST_F(rtc, date_read) { int rc; struct rtc_time rtc_tm; + if (!has_rtc()) + return; + /* Read the RTC time/date */ rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm); ASSERT_NE(-1, rc); -- cgit v1.2.3 From 50b4a0ffbdfdcf305f93b877c0bad956652f1eed Mon Sep 17 00:00:00 2001 From: Gregory Montoir Date: Tue, 8 Sep 2020 11:06:13 +0800 Subject: VTS: kselftest rtctest Return early and do not try to setup the test if no RTC is present. Exempt-From-Owner-Approval: smuckle@ is OOO Bug: 166143014 Change-Id: I302b77bb216e60457bfd04f6e8b42b7a44ab3882 --- tools/testing/selftests/rtc/rtctest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c index 2c61bd22e26e..efc7bcfdbd46 100644 --- a/tools/testing/selftests/rtc/rtctest.c +++ b/tools/testing/selftests/rtc/rtctest.c @@ -61,9 +61,6 @@ TEST_F(rtc, date_read) { int rc; struct rtc_time rtc_tm; - if (!has_rtc()) - return; - /* Read the RTC time/date */ rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm); ASSERT_NE(-1, rc); @@ -260,5 +257,8 @@ int main(int argc, char **argv) return 1; } + if (!has_rtc()) + return 0; + return test_harness_run(argc, argv); } -- cgit v1.2.3 From 350ec5e167dbdbf2edf281a7dd9232e38af47a0c Mon Sep 17 00:00:00 2001 From: Gregory Montoir Date: Tue, 8 Sep 2020 13:01:06 +0800 Subject: VTS: kselftest rtctest Simplify RTC presence check Exempt-From-Owner-Approval: smuckle@ is OOO Bug: 166143014 Change-Id: I2bcbe6fa744889e4b698ea36c68ff98898455518 --- tools/testing/selftests/rtc/rtctest.c | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c index efc7bcfdbd46..77c574b42694 100644 --- a/tools/testing/selftests/rtc/rtctest.c +++ b/tools/testing/selftests/rtc/rtctest.c @@ -5,14 +5,13 @@ * Copyright (c) 2018 Alexandre Belloni */ -#include #include #include #include #include #include -#include #include +#include #include #include #include @@ -25,25 +24,6 @@ static char *rtc_file = "/dev/rtc0"; -/* Returns 1 if file matching /dev/rtc* is found, else 0. */ -static int has_rtc(void) -{ - DIR *dev_dir; - struct dirent *dir; - - dev_dir = opendir("/dev"); - if (!dev_dir) - return 0; - while ((dir = readdir(dev_dir))) { - if (!strncmp(dir->d_name, "rtc", 3)) { - closedir(dev_dir); - return 1; - } - } - closedir(dev_dir); - return 0; -} - FIXTURE(rtc) { int fd; }; @@ -246,6 +226,8 @@ __constructor_order_last(void) int main(int argc, char **argv) { + struct stat st; + switch (argc) { case 2: rtc_file = argv[1]; @@ -257,8 +239,10 @@ int main(int argc, char **argv) return 1; } - if (!has_rtc()) + if (stat(rtc_file, &st) < 0 || !S_ISCHR(st.st_mode)) { + printf("no RTC present\n"); return 0; + } return test_harness_run(argc, argv); } -- cgit v1.2.3 From a46dcf7af5b39fb7bd93252239959d803b66598e Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar Date: Mon, 13 Jan 2020 22:11:58 +0530 Subject: UPSTREAM: kselftest: Minimise dependency of get_size on C library interfaces It was observed[1] on arm64 that __builtin_strlen led to an infinite loop in the get_size selftest. This is because __builtin_strlen (and other builtins) may sometimes result in a call to the C library function. The C library implementation of strlen uses an IFUNC resolver to load the most efficient strlen implementation for the underlying machine and hence has a PLT indirection even for static binaries. Because this binary avoids the C library startup routines, the PLT initialization never happens and hence the program gets stuck in an infinite loop. On x86_64 the __builtin_strlen just happens to expand inline and avoid the call but that is not always guaranteed. Further, while testing on x86_64 (Fedora 31), it was observed that the test also failed with a segfault inside write() because the generated code for the write function in glibc seems to access TLS before the syscall (probably due to the cancellation point check) and fails because TLS is not initialised. To mitigate these problems, this patch reduces the interface with the C library to just the syscall function. The syscall function still sets errno on failure, which is undesirable but for now it only affects cases where syscalls fail. [1] https://bugs.linaro.org/show_bug.cgi?id=5479 Signed-off-by: Siddhesh Poyarekar Reported-by: Masami Hiramatsu Tested-by: Masami Hiramatsu Reviewed-by: Tim Bird Signed-off-by: Shuah Khan (cherry picked from commit 6b64a650f0b2ae3940698f401732988699eecf7a) Signed-off-by: Mark Salyzyn Bug: 174132180 Test: Passes compilation and execution on x86_64 Change-Id: I2b3edbfcfcbff410c41b38560e331e55e1e1f232 (cherry picked from commit 0d877deaa06b71ff9ea44844247128ed6d72deff) --- tools/testing/selftests/size/get_size.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/size/get_size.c b/tools/testing/selftests/size/get_size.c index 2ad45b944355..2980b1a63366 100644 --- a/tools/testing/selftests/size/get_size.c +++ b/tools/testing/selftests/size/get_size.c @@ -11,23 +11,35 @@ * own execution. It also attempts to have as few dependencies * on kernel features as possible. * - * It should be statically linked, with startup libs avoided. - * It uses no library calls, and only the following 3 syscalls: + * It should be statically linked, with startup libs avoided. It uses + * no library calls except the syscall() function for the following 3 + * syscalls: * sysinfo(), write(), and _exit() * * For output, it avoids printf (which in some C libraries * has large external dependencies) by implementing it's own * number output and print routines, and using __builtin_strlen() + * + * The test may crash if any of the above syscalls fails because in some + * libc implementations (e.g. the GNU C Library) errno is saved in + * thread-local storage, which does not get initialized due to avoiding + * startup libs. */ #include #include +#include #define STDOUT_FILENO 1 static int print(const char *s) { - return write(STDOUT_FILENO, s, __builtin_strlen(s)); + size_t len = 0; + + while (s[len] != '\0') + len++; + + return syscall(SYS_write, STDOUT_FILENO, s, len); } static inline char *num_to_str(unsigned long num, char *buf, int len) @@ -79,12 +91,12 @@ void _start(void) print("TAP version 13\n"); print("# Testing system size.\n"); - ccode = sysinfo(&info); + ccode = syscall(SYS_sysinfo, &info); if (ccode < 0) { print("not ok 1"); print(test_name); print(" ---\n reason: \"could not get sysinfo\"\n ...\n"); - _exit(ccode); + syscall(SYS_exit, ccode); } print("ok 1"); print(test_name); @@ -100,5 +112,5 @@ void _start(void) print(" ...\n"); print("1..1\n"); - _exit(0); + syscall(SYS_exit, 0); } -- cgit v1.2.3 From 54e6c71787c3164ed0b76717aa9f46eb6bbf98cc Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Thu, 14 Jan 2021 00:51:37 +0000 Subject: Add x86_64 support for x86 tests This makes sure that we compiled the x86 tests that support x86_64. Bug: 177254902 Test: vts-tradefed run vts-kernel -m vts_linux_kselftest_x86_64 Change-Id: I0c2b42b814e6f24dbe17e37b7bf24613b0aa8298 --- Android.bp | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/Android.bp b/Android.bp index 66b1f47a7bff..3b9e8aa053e4 100644 --- a/Android.bp +++ b/Android.bp @@ -573,6 +573,7 @@ cc_test { "tools/testing/selftests/x86/syscall_nt.c", "tools/testing/selftests/x86/test_mremap_vdso.c", "tools/testing/selftests/x86/ldt_gdt.c", + "tools/testing/selftests/x86/syscall_arg_fault.c", ], arch: { arm: { @@ -581,11 +582,15 @@ cc_test { arm64: { enabled: false, }, + x86_64: { + enabled: true, + static_libs: [ + "libdl", + ], + }, x86: { srcs: [ - "tools/testing/selftests/x86/sysret_ss_attrs.c", //"tools/testing/selftests/x86/entry_from_vm86.c", - "tools/testing/selftests/x86/syscall_arg_fault.c", "tools/testing/selftests/x86/unwind_vdso.c", "tools/testing/selftests/x86/test_FCMOV.c", "tools/testing/selftests/x86/test_FCOMI.c", @@ -620,6 +625,12 @@ cc_test { arm64: { enabled: false, }, + x86: { + enabled: true, + }, + x86_64: { + enabled: true, + }, }, cflags: [ "-O2", @@ -640,7 +651,6 @@ cc_test { relative_install_path: "linux-kselftest/x86", srcs: [ "tools/testing/selftests/x86/ptrace_syscall.c", - "tools/testing/selftests/x86/raw_syscall_helper_32.S", ], cflags: [ "-O2", @@ -653,6 +663,44 @@ cc_test { arch: { x86: { enabled: true, + srcs: [ + "tools/testing/selftests/x86/raw_syscall_helper_32.S", + ], + }, + x86_64: { + enabled: true, + }, + }, +} + +cc_test { + name: "kselftest_x86_test_sysret_ss_attrs", + stem: "sysret_ss_attrs", + relative_install_path: "linux-kselftest/x86", + srcs: [ + "tools/testing/selftests/x86/sysret_ss_attrs.c", + ], + cflags: [ + "-O2", + "-pthread", + ], + c_std: "gnu99", + static_executable: true, + test_per_src: false, + defaults: ["kselftest_defaults"], + enabled: false, + arch: { + x86: { + enabled: true, + srcs: [ + "tools/testing/selftests/x86/thunks_32.S", + ], + }, + x86_64: { + enabled: true, + srcs: [ + "tools/testing/selftests/x86/thunks.S", + ], }, }, } -- cgit v1.2.3 From 3b1d7511c4c232f6ea9224fe0d9fe15bcde34673 Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Tue, 19 Jan 2021 10:08:46 -0800 Subject: Fix sysret_ss_attrs test name The name needed to be updated when moved to a separate cc_test in Android.bp. The binary should be showing up in $OUT now. Fixes: 0b2c8f9705418 ("Add x86_64 support for x86 tests") Bug: 177254902 Test: make kselftest_x86_test_sysret_ss_attrs Change-Id: I9007322e96e6d3b0f1566e0b78efd12d373a5b7e (cherry picked from commit cbdb44ef8c0fc80035b2b5aac08d0dbe88bfa3a5) --- android/kselftest_test_list.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk index 57eee125623d..5445bd12d26f 100644 --- a/android/kselftest_test_list.mk +++ b/android/kselftest_test_list.mk @@ -59,11 +59,11 @@ kselftest_modules += \ kselftest_x86_tests_single_step_syscall \ kselftest_x86_tests_syscall_arg_fault \ kselftest_x86_tests_syscall_nt \ - kselftest_x86_tests_sysret_ss_attrs \ kselftest_x86_tests_test_FCMOV \ kselftest_x86_tests_test_FCOMI \ kselftest_x86_tests_test_FISTTP \ kselftest_x86_tests_test_mremap_vdso \ kselftest_x86_tests_unwind_vdso \ kselftest_x86_tests_vdso_restorer \ + kselftest_x86_test_sysret_ss_attrs \ kselftest_x86_test_syscall_vdso \ -- cgit v1.2.3 From 5ec32a4050b0c8b93a3294a15cc388f74fd3921f Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Thu, 14 Jan 2021 16:23:05 -0800 Subject: Update the OWNERS drosen@ as primary willmcvicker@ as backup Change-Id: Ib5adc5e74d42a3435cbcbf90a79a8c5ee82e19a4 (cherry picked from commit c340ef02fdb2c6d2c0795eeddfcd186529de2611) --- OWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OWNERS b/OWNERS index 66d3dd9849e6..64bf926733d4 100644 --- a/OWNERS +++ b/OWNERS @@ -1,2 +1,2 @@ -smuckle@google.com -trong@google.com +drosen@google.com +willmcvicker@google.com -- cgit v1.2.3 From 14cefb500985712be7cf870081fefa929ec46692 Mon Sep 17 00:00:00 2001 From: ahs Date: Fri, 9 Apr 2021 09:34:03 +0530 Subject: Fixing segfault crash in x86_64 get_size testcase getsize_x86_64 testcase is crashing with segfault when trying to access the stack pointer. Compile the testcase with -mstackrealign option to realign the runtime stack so that segfault is avoided when accessing the stack pointer. Bug: 184920505 Signed-off-by: ahs Test: run vts -m vts_linux_kselftest_x86_64 -t size_get_size_x86_64 Change-Id: I013a72cbe5311167bad0c278a1f23ff16327e83c (cherry picked from commit 11c00348214b9192bae7611dc68af2637d6ab38c) --- Android.bp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Android.bp b/Android.bp index 3b9e8aa053e4..c87b46d74edc 100644 --- a/Android.bp +++ b/Android.bp @@ -437,6 +437,11 @@ cc_test { name: "kselftest_size_test", relative_install_path: "linux-kselftest/size", srcs: ["tools/testing/selftests/size/get_size.c"], + arch: { + x86_64: { + cflags: ["-mstackrealign"], + }, + }, defaults: ["kselftest_defaults"], nocrt: true, // coverage runtime calls atexit, which is unavailable with nocrt. -- cgit v1.2.3 From 8e9b545cfb4ceedfeecf8f7465703a27bc9cc712 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Thu, 17 Feb 2022 19:34:27 +0000 Subject: ANDROID: kvm: Test that pVM memory is wiped during teardown In protected KVM mode, we expect the hypervisor to protect guest secrets when they are torn down. Add a test checking this property by running a minimal guest, and checking that the content of memory has been wiped by the hypervisor after teardown. Note: although some of the pKVM code has already landed upstream, the functionality tested here hasn't at the time of writing. Once it does, this test should be sent upstream for review to replace this ANDROID patch. Bug: 218934075 Change-Id: I8f4cc012a971fc84c1d31d55decede8bf41824e3 Signed-off-by: Quentin Perret --- Android.bp | 19 +++ android/kselftest_test_list.mk | 1 + tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c | 174 +++++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c diff --git a/Android.bp b/Android.bp index 0b9166c56315..0990d0af28d1 100644 --- a/Android.bp +++ b/Android.bp @@ -340,6 +340,25 @@ cc_test { defaults: ["kselftest_defaults"], } +// KVM test +cc_test { + name: "kselftest_kvm_arm64_tests", + relative_install_path: "linux-kselftest/kvm/aarch64", + local_include_dirs: [ "tools/testing/selftests"], + arch: { + arm: { + enabled: false, + }, + arm64: { + srcs: ["tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c"], + }, + x86: { + enabled: false, + }, + }, + defaults: ["kselftest_defaults"], +} + // Lib test sh_test { name: "kselftest_lib_printf", diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk index 07df6fc5d758..46b9b92c58fb 100644 --- a/android/kselftest_test_list.mk +++ b/android/kselftest_test_list.mk @@ -31,6 +31,7 @@ kselftest_modules += \ kselftest_intel_pstate_tests_aperf \ kselftest_intel_pstate_tests_msr \ kselftest_kcmp_tests_kcmp_test \ + kselftest_kvm_arm64_tests_pvm_wipe_mem \ kselftest_net_tests_psock_tpacket \ kselftest_net_tests_socket \ kselftest_net_tests_reuseaddr_conflict \ diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c new file mode 100644 index 000000000000..4af8ca3c4bad --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test checking that memory of protected guests is wiped after teardown. + * + * Copyright (C) 2022, Google LLC. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kselftest.h" + +#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31) + +#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL) +#define REG_PC 0x6030000000100040ULL + +static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val) +{ + uint64_t reg_data; + struct kvm_one_reg reg; + int ret; + + reg.addr = (__u64) ®_data; + reg_data = val; + reg.id = reg_id; + + ret = ioctl(vcpufd, KVM_SET_ONE_REG, ®); + if (ret < 0) + ksft_exit_fail_msg("Failed to set reg: %d\n", ret); +} + +static int get_kvm(void) +{ + size_t run_size; + int kvm, ret; + + kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC); + if (kvm < 0) + ksft_exit_skip("KVM not supported\n"); + + ret = ioctl(kvm, KVM_GET_API_VERSION, NULL); + if (ret != 12) + ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret); + + run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); + if (run_size < sizeof(struct kvm_run)) + ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n"); + + return kvm; +} + +static int create_protected_vm(int kvm) +{ + int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED); + + if (vmfd < 0) + ksft_exit_skip("Protected guests not supported: %d\n", vmfd); + + return vmfd; +} + +static int create_vcpu(int vmfd, struct kvm_run **run) +{ + struct kvm_vcpu_init vcpu_init; + int vcpufd, ret; + + ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init); + if (ret) + ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret); + + vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0); + if (vcpufd < 0) + ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd); + + *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); + if (!run) + ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n"); + + ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init); + if (ret) + ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret); + + return vcpufd; +} + +static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run) +{ + int ret = munmap(run, sizeof(*run)); + + if (ret) + ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret); + + ret = close(vcpufd); + if (ret) + ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret); + + ret = close(vmfd); + if (ret) + ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret); + + ret = close(kvm); + if (ret) + ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret); +} + +int main(void) +{ + struct kvm_userspace_memory_region region; + long page_size = sysconf(_SC_PAGESIZE); + int ret, kvm, vmfd, vcpufd; + uint32_t guest_code[2]; + struct kvm_run *run; + uint8_t *guest_mem; + size_t run_size; + + kvm = get_kvm(); + vmfd = create_protected_vm(kvm); + vcpufd = create_vcpu(vmfd, &run); + + /* Create a one-page memslot for the guest */ + guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (guest_mem == MAP_FAILED) + ksft_exit_fail_msg("Failed to mmap guest memory\n"); + region = (struct kvm_userspace_memory_region) { + .slot = 0, + .guest_phys_addr = 1UL << 30, + .memory_size = page_size, + .userspace_addr = (uint64_t)guest_mem, + }; + + /* Copy some code in guest memory. */ + guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */ + guest_code[1] = 0x17ffffff; /* b 1b */ + memcpy(guest_mem, guest_code, sizeof(guest_code)); + ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion); + if (ret) + ksft_exit_fail_msg("Failed to set memory region: %d\n", ret); + + /* + * Get the VCPU to run one instruction, to be sure the page containing + * the code has been faulted in. + */ + set_one_reg(vcpufd, REG_PC, region.guest_phys_addr); + set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size); + ret = ioctl(vcpufd, KVM_RUN, NULL); + if (ret) + ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret); + if (run->exit_reason != KVM_EXIT_MMIO) + ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason); + + /* + * Tear the guest down, and check that the donated memory has been + * wiped by the hypervisor. + */ + teardown(kvm, vmfd, vcpufd, run); + if (!memcmp(guest_mem, guest_code, sizeof(guest_code))) + ksft_exit_fail_msg("Protected guest memory has not been poisoned\n"); + + ksft_exit_pass(); +} -- cgit v1.2.3 From 95249f0873275e2c5090d48d897d57ebd3a3e2d7 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Mon, 21 Feb 2022 13:42:24 +0000 Subject: ANDROID: Add .patch version of pKVM test Bug: 218934075 Signed-off-by: Quentin Perret Change-Id: I897e18e10756165e6385b98102258740694cf96f --- ...-Test-that-pVM-memory-is-wiped-during-tea.patch | 250 +++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch diff --git a/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch b/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch new file mode 100644 index 000000000000..3bff0f5e91ea --- /dev/null +++ b/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch @@ -0,0 +1,250 @@ +From 8e9b545cfb4ceedfeecf8f7465703a27bc9cc712 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Thu, 17 Feb 2022 19:34:27 +0000 +Subject: [PATCH] ANDROID: kvm: Test that pVM memory is wiped during teardown + +In protected KVM mode, we expect the hypervisor to protect guest secrets +when they are torn down. Add a test checking this property by running a +minimal guest, and checking that the content of memory has been wiped by +the hypervisor after teardown. + +Note: although some of the pKVM code has already landed upstream, the +functionality tested here hasn't at the time of writing. Once it does, +this test should be sent upstream for review to replace this ANDROID +patch. + +Bug: 218934075 +Change-Id: I8f4cc012a971fc84c1d31d55decede8bf41824e3 +Signed-off-by: Quentin Perret +--- + Android.bp | 19 ++ + android/kselftest_test_list.mk | 1 + + .../selftests/kvm/aarch64/pvm_wipe_mem.c | 174 ++++++++++++++++++ + 3 files changed, 194 insertions(+) + create mode 100644 tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c + +diff --git a/Android.bp b/Android.bp +index 0b9166c56315..0990d0af28d1 100644 +--- a/Android.bp ++++ b/Android.bp +@@ -340,6 +340,25 @@ cc_test { + defaults: ["kselftest_defaults"], + } + ++// KVM test ++cc_test { ++ name: "kselftest_kvm_arm64_tests", ++ relative_install_path: "linux-kselftest/kvm/aarch64", ++ local_include_dirs: [ "tools/testing/selftests"], ++ arch: { ++ arm: { ++ enabled: false, ++ }, ++ arm64: { ++ srcs: ["tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c"], ++ }, ++ x86: { ++ enabled: false, ++ }, ++ }, ++ defaults: ["kselftest_defaults"], ++} ++ + // Lib test + sh_test { + name: "kselftest_lib_printf", +diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk +index 07df6fc5d758..46b9b92c58fb 100644 +--- a/android/kselftest_test_list.mk ++++ b/android/kselftest_test_list.mk +@@ -31,6 +31,7 @@ kselftest_modules += \ + kselftest_intel_pstate_tests_aperf \ + kselftest_intel_pstate_tests_msr \ + kselftest_kcmp_tests_kcmp_test \ ++ kselftest_kvm_arm64_tests_pvm_wipe_mem \ + kselftest_net_tests_psock_tpacket \ + kselftest_net_tests_socket \ + kselftest_net_tests_reuseaddr_conflict \ +diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c +new file mode 100644 +index 000000000000..4af8ca3c4bad +--- /dev/null ++++ b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Test checking that memory of protected guests is wiped after teardown. ++ * ++ * Copyright (C) 2022, Google LLC. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "kselftest.h" ++ ++#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31) ++ ++#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL) ++#define REG_PC 0x6030000000100040ULL ++ ++static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val) ++{ ++ uint64_t reg_data; ++ struct kvm_one_reg reg; ++ int ret; ++ ++ reg.addr = (__u64) ®_data; ++ reg_data = val; ++ reg.id = reg_id; ++ ++ ret = ioctl(vcpufd, KVM_SET_ONE_REG, ®); ++ if (ret < 0) ++ ksft_exit_fail_msg("Failed to set reg: %d\n", ret); ++} ++ ++static int get_kvm(void) ++{ ++ size_t run_size; ++ int kvm, ret; ++ ++ kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC); ++ if (kvm < 0) ++ ksft_exit_skip("KVM not supported\n"); ++ ++ ret = ioctl(kvm, KVM_GET_API_VERSION, NULL); ++ if (ret != 12) ++ ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret); ++ ++ run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); ++ if (run_size < sizeof(struct kvm_run)) ++ ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n"); ++ ++ return kvm; ++} ++ ++static int create_protected_vm(int kvm) ++{ ++ int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED); ++ ++ if (vmfd < 0) ++ ksft_exit_skip("Protected guests not supported: %d\n", vmfd); ++ ++ return vmfd; ++} ++ ++static int create_vcpu(int vmfd, struct kvm_run **run) ++{ ++ struct kvm_vcpu_init vcpu_init; ++ int vcpufd, ret; ++ ++ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init); ++ if (ret) ++ ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret); ++ ++ vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0); ++ if (vcpufd < 0) ++ ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd); ++ ++ *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); ++ if (!run) ++ ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n"); ++ ++ ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init); ++ if (ret) ++ ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret); ++ ++ return vcpufd; ++} ++ ++static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run) ++{ ++ int ret = munmap(run, sizeof(*run)); ++ ++ if (ret) ++ ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret); ++ ++ ret = close(vcpufd); ++ if (ret) ++ ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret); ++ ++ ret = close(vmfd); ++ if (ret) ++ ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret); ++ ++ ret = close(kvm); ++ if (ret) ++ ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret); ++} ++ ++int main(void) ++{ ++ struct kvm_userspace_memory_region region; ++ long page_size = sysconf(_SC_PAGESIZE); ++ int ret, kvm, vmfd, vcpufd; ++ uint32_t guest_code[2]; ++ struct kvm_run *run; ++ uint8_t *guest_mem; ++ size_t run_size; ++ ++ kvm = get_kvm(); ++ vmfd = create_protected_vm(kvm); ++ vcpufd = create_vcpu(vmfd, &run); ++ ++ /* Create a one-page memslot for the guest */ ++ guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_ANONYMOUS, -1, 0); ++ if (guest_mem == MAP_FAILED) ++ ksft_exit_fail_msg("Failed to mmap guest memory\n"); ++ region = (struct kvm_userspace_memory_region) { ++ .slot = 0, ++ .guest_phys_addr = 1UL << 30, ++ .memory_size = page_size, ++ .userspace_addr = (uint64_t)guest_mem, ++ }; ++ ++ /* Copy some code in guest memory. */ ++ guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */ ++ guest_code[1] = 0x17ffffff; /* b 1b */ ++ memcpy(guest_mem, guest_code, sizeof(guest_code)); ++ ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion); ++ if (ret) ++ ksft_exit_fail_msg("Failed to set memory region: %d\n", ret); ++ ++ /* ++ * Get the VCPU to run one instruction, to be sure the page containing ++ * the code has been faulted in. ++ */ ++ set_one_reg(vcpufd, REG_PC, region.guest_phys_addr); ++ set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size); ++ ret = ioctl(vcpufd, KVM_RUN, NULL); ++ if (ret) ++ ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret); ++ if (run->exit_reason != KVM_EXIT_MMIO) ++ ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason); ++ ++ /* ++ * Tear the guest down, and check that the donated memory has been ++ * wiped by the hypervisor. ++ */ ++ teardown(kvm, vmfd, vcpufd, run); ++ if (!memcmp(guest_mem, guest_code, sizeof(guest_code))) ++ ksft_exit_fail_msg("Protected guest memory has not been poisoned\n"); ++ ++ ksft_exit_pass(); ++} +-- +2.35.1.473.g83b2b277ed-goog + -- cgit v1.2.3 From 78d07f9002829d1a40c1dc74c878df09f5e78713 Mon Sep 17 00:00:00 2001 From: Rucha Katakwar Date: Tue, 22 Feb 2022 18:58:04 +0000 Subject: Revert "ANDROID: Add .patch version of pKVM test" Revert "vts: kselftest: Add pKVM memory test" Revert submission 1992915-pvm-wipe-mem-test Reason for revert: DroidMonitor: Potential culprit for Bug 220892298 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Reverted Changes: I897e18e10:ANDROID: Add .patch version of pKVM test Idb29f4624:vts: kselftest: Add pKVM memory test I8f4cc012a:ANDROID: kvm: Test that pVM memory is wiped during... Change-Id: I02527559c5848d23b78adb553ca6e345e91c1390 --- ...-Test-that-pVM-memory-is-wiped-during-tea.patch | 250 --------------------- 1 file changed, 250 deletions(-) delete mode 100644 android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch diff --git a/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch b/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch deleted file mode 100644 index 3bff0f5e91ea..000000000000 --- a/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch +++ /dev/null @@ -1,250 +0,0 @@ -From 8e9b545cfb4ceedfeecf8f7465703a27bc9cc712 Mon Sep 17 00:00:00 2001 -From: Quentin Perret -Date: Thu, 17 Feb 2022 19:34:27 +0000 -Subject: [PATCH] ANDROID: kvm: Test that pVM memory is wiped during teardown - -In protected KVM mode, we expect the hypervisor to protect guest secrets -when they are torn down. Add a test checking this property by running a -minimal guest, and checking that the content of memory has been wiped by -the hypervisor after teardown. - -Note: although some of the pKVM code has already landed upstream, the -functionality tested here hasn't at the time of writing. Once it does, -this test should be sent upstream for review to replace this ANDROID -patch. - -Bug: 218934075 -Change-Id: I8f4cc012a971fc84c1d31d55decede8bf41824e3 -Signed-off-by: Quentin Perret ---- - Android.bp | 19 ++ - android/kselftest_test_list.mk | 1 + - .../selftests/kvm/aarch64/pvm_wipe_mem.c | 174 ++++++++++++++++++ - 3 files changed, 194 insertions(+) - create mode 100644 tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c - -diff --git a/Android.bp b/Android.bp -index 0b9166c56315..0990d0af28d1 100644 ---- a/Android.bp -+++ b/Android.bp -@@ -340,6 +340,25 @@ cc_test { - defaults: ["kselftest_defaults"], - } - -+// KVM test -+cc_test { -+ name: "kselftest_kvm_arm64_tests", -+ relative_install_path: "linux-kselftest/kvm/aarch64", -+ local_include_dirs: [ "tools/testing/selftests"], -+ arch: { -+ arm: { -+ enabled: false, -+ }, -+ arm64: { -+ srcs: ["tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c"], -+ }, -+ x86: { -+ enabled: false, -+ }, -+ }, -+ defaults: ["kselftest_defaults"], -+} -+ - // Lib test - sh_test { - name: "kselftest_lib_printf", -diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk -index 07df6fc5d758..46b9b92c58fb 100644 ---- a/android/kselftest_test_list.mk -+++ b/android/kselftest_test_list.mk -@@ -31,6 +31,7 @@ kselftest_modules += \ - kselftest_intel_pstate_tests_aperf \ - kselftest_intel_pstate_tests_msr \ - kselftest_kcmp_tests_kcmp_test \ -+ kselftest_kvm_arm64_tests_pvm_wipe_mem \ - kselftest_net_tests_psock_tpacket \ - kselftest_net_tests_socket \ - kselftest_net_tests_reuseaddr_conflict \ -diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c -new file mode 100644 -index 000000000000..4af8ca3c4bad ---- /dev/null -+++ b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c -@@ -0,0 +1,174 @@ -+// SPDX-License-Identifier: GPL-2.0-only -+/* -+ * Test checking that memory of protected guests is wiped after teardown. -+ * -+ * Copyright (C) 2022, Google LLC. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "kselftest.h" -+ -+#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31) -+ -+#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL) -+#define REG_PC 0x6030000000100040ULL -+ -+static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val) -+{ -+ uint64_t reg_data; -+ struct kvm_one_reg reg; -+ int ret; -+ -+ reg.addr = (__u64) ®_data; -+ reg_data = val; -+ reg.id = reg_id; -+ -+ ret = ioctl(vcpufd, KVM_SET_ONE_REG, ®); -+ if (ret < 0) -+ ksft_exit_fail_msg("Failed to set reg: %d\n", ret); -+} -+ -+static int get_kvm(void) -+{ -+ size_t run_size; -+ int kvm, ret; -+ -+ kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC); -+ if (kvm < 0) -+ ksft_exit_skip("KVM not supported\n"); -+ -+ ret = ioctl(kvm, KVM_GET_API_VERSION, NULL); -+ if (ret != 12) -+ ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret); -+ -+ run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); -+ if (run_size < sizeof(struct kvm_run)) -+ ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n"); -+ -+ return kvm; -+} -+ -+static int create_protected_vm(int kvm) -+{ -+ int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED); -+ -+ if (vmfd < 0) -+ ksft_exit_skip("Protected guests not supported: %d\n", vmfd); -+ -+ return vmfd; -+} -+ -+static int create_vcpu(int vmfd, struct kvm_run **run) -+{ -+ struct kvm_vcpu_init vcpu_init; -+ int vcpufd, ret; -+ -+ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init); -+ if (ret) -+ ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret); -+ -+ vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0); -+ if (vcpufd < 0) -+ ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd); -+ -+ *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); -+ if (!run) -+ ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n"); -+ -+ ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init); -+ if (ret) -+ ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret); -+ -+ return vcpufd; -+} -+ -+static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run) -+{ -+ int ret = munmap(run, sizeof(*run)); -+ -+ if (ret) -+ ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret); -+ -+ ret = close(vcpufd); -+ if (ret) -+ ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret); -+ -+ ret = close(vmfd); -+ if (ret) -+ ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret); -+ -+ ret = close(kvm); -+ if (ret) -+ ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret); -+} -+ -+int main(void) -+{ -+ struct kvm_userspace_memory_region region; -+ long page_size = sysconf(_SC_PAGESIZE); -+ int ret, kvm, vmfd, vcpufd; -+ uint32_t guest_code[2]; -+ struct kvm_run *run; -+ uint8_t *guest_mem; -+ size_t run_size; -+ -+ kvm = get_kvm(); -+ vmfd = create_protected_vm(kvm); -+ vcpufd = create_vcpu(vmfd, &run); -+ -+ /* Create a one-page memslot for the guest */ -+ guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, -+ MAP_SHARED | MAP_ANONYMOUS, -1, 0); -+ if (guest_mem == MAP_FAILED) -+ ksft_exit_fail_msg("Failed to mmap guest memory\n"); -+ region = (struct kvm_userspace_memory_region) { -+ .slot = 0, -+ .guest_phys_addr = 1UL << 30, -+ .memory_size = page_size, -+ .userspace_addr = (uint64_t)guest_mem, -+ }; -+ -+ /* Copy some code in guest memory. */ -+ guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */ -+ guest_code[1] = 0x17ffffff; /* b 1b */ -+ memcpy(guest_mem, guest_code, sizeof(guest_code)); -+ ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion); -+ if (ret) -+ ksft_exit_fail_msg("Failed to set memory region: %d\n", ret); -+ -+ /* -+ * Get the VCPU to run one instruction, to be sure the page containing -+ * the code has been faulted in. -+ */ -+ set_one_reg(vcpufd, REG_PC, region.guest_phys_addr); -+ set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size); -+ ret = ioctl(vcpufd, KVM_RUN, NULL); -+ if (ret) -+ ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret); -+ if (run->exit_reason != KVM_EXIT_MMIO) -+ ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason); -+ -+ /* -+ * Tear the guest down, and check that the donated memory has been -+ * wiped by the hypervisor. -+ */ -+ teardown(kvm, vmfd, vcpufd, run); -+ if (!memcmp(guest_mem, guest_code, sizeof(guest_code))) -+ ksft_exit_fail_msg("Protected guest memory has not been poisoned\n"); -+ -+ ksft_exit_pass(); -+} --- -2.35.1.473.g83b2b277ed-goog - -- cgit v1.2.3 From a80f5057c756c82f6031f5eac00a63656ee915b9 Mon Sep 17 00:00:00 2001 From: Rucha Katakwar Date: Tue, 22 Feb 2022 18:58:04 +0000 Subject: Revert "ANDROID: kvm: Test that pVM memory is wiped during teardown" Revert "vts: kselftest: Add pKVM memory test" Revert submission 1992915-pvm-wipe-mem-test Reason for revert: DroidMonitor: Potential culprit for Bug 220892298 - verifying through ABTD before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted. Reverted Changes: I897e18e10:ANDROID: Add .patch version of pKVM test Idb29f4624:vts: kselftest: Add pKVM memory test I8f4cc012a:ANDROID: kvm: Test that pVM memory is wiped during... Change-Id: Ic7c5ccd0e602b066e1161ec8e4ddeaeeead93532 --- Android.bp | 19 --- android/kselftest_test_list.mk | 1 - tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c | 174 --------------------- 3 files changed, 194 deletions(-) delete mode 100644 tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c diff --git a/Android.bp b/Android.bp index 0990d0af28d1..0b9166c56315 100644 --- a/Android.bp +++ b/Android.bp @@ -340,25 +340,6 @@ cc_test { defaults: ["kselftest_defaults"], } -// KVM test -cc_test { - name: "kselftest_kvm_arm64_tests", - relative_install_path: "linux-kselftest/kvm/aarch64", - local_include_dirs: [ "tools/testing/selftests"], - arch: { - arm: { - enabled: false, - }, - arm64: { - srcs: ["tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c"], - }, - x86: { - enabled: false, - }, - }, - defaults: ["kselftest_defaults"], -} - // Lib test sh_test { name: "kselftest_lib_printf", diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk index 46b9b92c58fb..07df6fc5d758 100644 --- a/android/kselftest_test_list.mk +++ b/android/kselftest_test_list.mk @@ -31,7 +31,6 @@ kselftest_modules += \ kselftest_intel_pstate_tests_aperf \ kselftest_intel_pstate_tests_msr \ kselftest_kcmp_tests_kcmp_test \ - kselftest_kvm_arm64_tests_pvm_wipe_mem \ kselftest_net_tests_psock_tpacket \ kselftest_net_tests_socket \ kselftest_net_tests_reuseaddr_conflict \ diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c deleted file mode 100644 index 4af8ca3c4bad..000000000000 --- a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Test checking that memory of protected guests is wiped after teardown. - * - * Copyright (C) 2022, Google LLC. - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "kselftest.h" - -#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31) - -#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL) -#define REG_PC 0x6030000000100040ULL - -static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val) -{ - uint64_t reg_data; - struct kvm_one_reg reg; - int ret; - - reg.addr = (__u64) ®_data; - reg_data = val; - reg.id = reg_id; - - ret = ioctl(vcpufd, KVM_SET_ONE_REG, ®); - if (ret < 0) - ksft_exit_fail_msg("Failed to set reg: %d\n", ret); -} - -static int get_kvm(void) -{ - size_t run_size; - int kvm, ret; - - kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC); - if (kvm < 0) - ksft_exit_skip("KVM not supported\n"); - - ret = ioctl(kvm, KVM_GET_API_VERSION, NULL); - if (ret != 12) - ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret); - - run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); - if (run_size < sizeof(struct kvm_run)) - ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n"); - - return kvm; -} - -static int create_protected_vm(int kvm) -{ - int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED); - - if (vmfd < 0) - ksft_exit_skip("Protected guests not supported: %d\n", vmfd); - - return vmfd; -} - -static int create_vcpu(int vmfd, struct kvm_run **run) -{ - struct kvm_vcpu_init vcpu_init; - int vcpufd, ret; - - ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init); - if (ret) - ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret); - - vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0); - if (vcpufd < 0) - ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd); - - *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); - if (!run) - ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n"); - - ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init); - if (ret) - ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret); - - return vcpufd; -} - -static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run) -{ - int ret = munmap(run, sizeof(*run)); - - if (ret) - ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret); - - ret = close(vcpufd); - if (ret) - ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret); - - ret = close(vmfd); - if (ret) - ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret); - - ret = close(kvm); - if (ret) - ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret); -} - -int main(void) -{ - struct kvm_userspace_memory_region region; - long page_size = sysconf(_SC_PAGESIZE); - int ret, kvm, vmfd, vcpufd; - uint32_t guest_code[2]; - struct kvm_run *run; - uint8_t *guest_mem; - size_t run_size; - - kvm = get_kvm(); - vmfd = create_protected_vm(kvm); - vcpufd = create_vcpu(vmfd, &run); - - /* Create a one-page memslot for the guest */ - guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_ANONYMOUS, -1, 0); - if (guest_mem == MAP_FAILED) - ksft_exit_fail_msg("Failed to mmap guest memory\n"); - region = (struct kvm_userspace_memory_region) { - .slot = 0, - .guest_phys_addr = 1UL << 30, - .memory_size = page_size, - .userspace_addr = (uint64_t)guest_mem, - }; - - /* Copy some code in guest memory. */ - guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */ - guest_code[1] = 0x17ffffff; /* b 1b */ - memcpy(guest_mem, guest_code, sizeof(guest_code)); - ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion); - if (ret) - ksft_exit_fail_msg("Failed to set memory region: %d\n", ret); - - /* - * Get the VCPU to run one instruction, to be sure the page containing - * the code has been faulted in. - */ - set_one_reg(vcpufd, REG_PC, region.guest_phys_addr); - set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size); - ret = ioctl(vcpufd, KVM_RUN, NULL); - if (ret) - ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret); - if (run->exit_reason != KVM_EXIT_MMIO) - ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason); - - /* - * Tear the guest down, and check that the donated memory has been - * wiped by the hypervisor. - */ - teardown(kvm, vmfd, vcpufd, run); - if (!memcmp(guest_mem, guest_code, sizeof(guest_code))) - ksft_exit_fail_msg("Protected guest memory has not been poisoned\n"); - - ksft_exit_pass(); -} -- cgit v1.2.3 From a9dc703806031c8535c84c9905979f86dfaec1d3 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Thu, 17 Feb 2022 19:34:27 +0000 Subject: ANDROID: kvm: Test that pVM memory is wiped during teardown In protected KVM mode, we expect the hypervisor to protect guest secrets when they are torn down. Add a test checking this property by running a minimal guest, and checking that the content of memory has been wiped by the hypervisor after teardown. Note: although some of the pKVM code has already landed upstream, the functionality tested here hasn't at the time of writing. Once it does, this test should be sent upstream for review to replace this ANDROID patch. Bug: 218934075 Signed-off-by: Quentin Perret Change-Id: I4a347908d189f2c4835fd576b26fae7c10ec9b22 --- Android.bp | 15 ++ android/kselftest_test_list.mk | 1 + tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c | 174 +++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c diff --git a/Android.bp b/Android.bp index 0b9166c56315..08805a161450 100644 --- a/Android.bp +++ b/Android.bp @@ -340,6 +340,21 @@ cc_test { defaults: ["kselftest_defaults"], } +// KVM test +cc_test { + name: "kselftest_kvm_arm64_tests", + relative_install_path: "linux-kselftest/kvm/aarch64", + local_include_dirs: [ "tools/testing/selftests"], + enabled: false, + arch: { + arm64: { + enabled: true, + srcs: ["tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c"], + }, + }, + defaults: ["kselftest_defaults"], +} + // Lib test sh_test { name: "kselftest_lib_printf", diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk index 07df6fc5d758..46b9b92c58fb 100644 --- a/android/kselftest_test_list.mk +++ b/android/kselftest_test_list.mk @@ -31,6 +31,7 @@ kselftest_modules += \ kselftest_intel_pstate_tests_aperf \ kselftest_intel_pstate_tests_msr \ kselftest_kcmp_tests_kcmp_test \ + kselftest_kvm_arm64_tests_pvm_wipe_mem \ kselftest_net_tests_psock_tpacket \ kselftest_net_tests_socket \ kselftest_net_tests_reuseaddr_conflict \ diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c new file mode 100644 index 000000000000..4af8ca3c4bad --- /dev/null +++ b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test checking that memory of protected guests is wiped after teardown. + * + * Copyright (C) 2022, Google LLC. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "kselftest.h" + +#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31) + +#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL) +#define REG_PC 0x6030000000100040ULL + +static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val) +{ + uint64_t reg_data; + struct kvm_one_reg reg; + int ret; + + reg.addr = (__u64) ®_data; + reg_data = val; + reg.id = reg_id; + + ret = ioctl(vcpufd, KVM_SET_ONE_REG, ®); + if (ret < 0) + ksft_exit_fail_msg("Failed to set reg: %d\n", ret); +} + +static int get_kvm(void) +{ + size_t run_size; + int kvm, ret; + + kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC); + if (kvm < 0) + ksft_exit_skip("KVM not supported\n"); + + ret = ioctl(kvm, KVM_GET_API_VERSION, NULL); + if (ret != 12) + ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret); + + run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); + if (run_size < sizeof(struct kvm_run)) + ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n"); + + return kvm; +} + +static int create_protected_vm(int kvm) +{ + int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED); + + if (vmfd < 0) + ksft_exit_skip("Protected guests not supported: %d\n", vmfd); + + return vmfd; +} + +static int create_vcpu(int vmfd, struct kvm_run **run) +{ + struct kvm_vcpu_init vcpu_init; + int vcpufd, ret; + + ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init); + if (ret) + ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret); + + vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0); + if (vcpufd < 0) + ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd); + + *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); + if (!run) + ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n"); + + ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init); + if (ret) + ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret); + + return vcpufd; +} + +static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run) +{ + int ret = munmap(run, sizeof(*run)); + + if (ret) + ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret); + + ret = close(vcpufd); + if (ret) + ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret); + + ret = close(vmfd); + if (ret) + ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret); + + ret = close(kvm); + if (ret) + ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret); +} + +int main(void) +{ + struct kvm_userspace_memory_region region; + long page_size = sysconf(_SC_PAGESIZE); + int ret, kvm, vmfd, vcpufd; + uint32_t guest_code[2]; + struct kvm_run *run; + uint8_t *guest_mem; + size_t run_size; + + kvm = get_kvm(); + vmfd = create_protected_vm(kvm); + vcpufd = create_vcpu(vmfd, &run); + + /* Create a one-page memslot for the guest */ + guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (guest_mem == MAP_FAILED) + ksft_exit_fail_msg("Failed to mmap guest memory\n"); + region = (struct kvm_userspace_memory_region) { + .slot = 0, + .guest_phys_addr = 1UL << 30, + .memory_size = page_size, + .userspace_addr = (uint64_t)guest_mem, + }; + + /* Copy some code in guest memory. */ + guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */ + guest_code[1] = 0x17ffffff; /* b 1b */ + memcpy(guest_mem, guest_code, sizeof(guest_code)); + ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion); + if (ret) + ksft_exit_fail_msg("Failed to set memory region: %d\n", ret); + + /* + * Get the VCPU to run one instruction, to be sure the page containing + * the code has been faulted in. + */ + set_one_reg(vcpufd, REG_PC, region.guest_phys_addr); + set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size); + ret = ioctl(vcpufd, KVM_RUN, NULL); + if (ret) + ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret); + if (run->exit_reason != KVM_EXIT_MMIO) + ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason); + + /* + * Tear the guest down, and check that the donated memory has been + * wiped by the hypervisor. + */ + teardown(kvm, vmfd, vcpufd, run); + if (!memcmp(guest_mem, guest_code, sizeof(guest_code))) + ksft_exit_fail_msg("Protected guest memory has not been poisoned\n"); + + ksft_exit_pass(); +} -- cgit v1.2.3 From 08fbf115fa7faddc0b8e953ae74069c7d0ab6ab4 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Wed, 23 Feb 2022 13:20:54 +0000 Subject: ANDROID: Add .patch version of pKVM test Bug: 218934075 Signed-off-by: Quentin Perret Change-Id: Ic6bf26d675852221ca4f4512b0b710ed0d78938a --- ...-Test-that-pVM-memory-is-wiped-during-tea.patch | 246 +++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch diff --git a/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch b/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch new file mode 100644 index 000000000000..590ee72368dc --- /dev/null +++ b/android/patches/0023-ANDROID-kvm-Test-that-pVM-memory-is-wiped-during-tea.patch @@ -0,0 +1,246 @@ +From a9dc703806031c8535c84c9905979f86dfaec1d3 Mon Sep 17 00:00:00 2001 +From: Quentin Perret +Date: Thu, 17 Feb 2022 19:34:27 +0000 +Subject: [PATCH] ANDROID: kvm: Test that pVM memory is wiped during teardown + +In protected KVM mode, we expect the hypervisor to protect guest secrets +when they are torn down. Add a test checking this property by running a +minimal guest, and checking that the content of memory has been wiped by +the hypervisor after teardown. + +Note: although some of the pKVM code has already landed upstream, the +functionality tested here hasn't at the time of writing. Once it does, +this test should be sent upstream for review to replace this ANDROID +patch. + +Bug: 218934075 +Signed-off-by: Quentin Perret +Change-Id: I4a347908d189f2c4835fd576b26fae7c10ec9b22 +--- + Android.bp | 15 ++ + android/kselftest_test_list.mk | 1 + + .../selftests/kvm/aarch64/pvm_wipe_mem.c | 174 ++++++++++++++++++ + 3 files changed, 190 insertions(+) + create mode 100644 tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c + +diff --git a/Android.bp b/Android.bp +index 0b9166c56315..08805a161450 100644 +--- a/Android.bp ++++ b/Android.bp +@@ -340,6 +340,21 @@ cc_test { + defaults: ["kselftest_defaults"], + } + ++// KVM test ++cc_test { ++ name: "kselftest_kvm_arm64_tests", ++ relative_install_path: "linux-kselftest/kvm/aarch64", ++ local_include_dirs: [ "tools/testing/selftests"], ++ enabled: false, ++ arch: { ++ arm64: { ++ enabled: true, ++ srcs: ["tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c"], ++ }, ++ }, ++ defaults: ["kselftest_defaults"], ++} ++ + // Lib test + sh_test { + name: "kselftest_lib_printf", +diff --git a/android/kselftest_test_list.mk b/android/kselftest_test_list.mk +index 07df6fc5d758..46b9b92c58fb 100644 +--- a/android/kselftest_test_list.mk ++++ b/android/kselftest_test_list.mk +@@ -31,6 +31,7 @@ kselftest_modules += \ + kselftest_intel_pstate_tests_aperf \ + kselftest_intel_pstate_tests_msr \ + kselftest_kcmp_tests_kcmp_test \ ++ kselftest_kvm_arm64_tests_pvm_wipe_mem \ + kselftest_net_tests_psock_tpacket \ + kselftest_net_tests_socket \ + kselftest_net_tests_reuseaddr_conflict \ +diff --git a/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c +new file mode 100644 +index 000000000000..4af8ca3c4bad +--- /dev/null ++++ b/tools/testing/selftests/kvm/aarch64/pvm_wipe_mem.c +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0-only ++/* ++ * Test checking that memory of protected guests is wiped after teardown. ++ * ++ * Copyright (C) 2022, Google LLC. ++ */ ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "kselftest.h" ++ ++#define KVM_VM_TYPE_ARM_PROTECTED (1UL << 31) ++ ++#define REG_X(number) (0x6030000000100000ULL + (number) * 2UL) ++#define REG_PC 0x6030000000100040ULL ++ ++static void set_one_reg(int vcpufd, uint64_t reg_id, uint64_t val) ++{ ++ uint64_t reg_data; ++ struct kvm_one_reg reg; ++ int ret; ++ ++ reg.addr = (__u64) ®_data; ++ reg_data = val; ++ reg.id = reg_id; ++ ++ ret = ioctl(vcpufd, KVM_SET_ONE_REG, ®); ++ if (ret < 0) ++ ksft_exit_fail_msg("Failed to set reg: %d\n", ret); ++} ++ ++static int get_kvm(void) ++{ ++ size_t run_size; ++ int kvm, ret; ++ ++ kvm = open("/dev/kvm", O_RDWR | O_CLOEXEC); ++ if (kvm < 0) ++ ksft_exit_skip("KVM not supported\n"); ++ ++ ret = ioctl(kvm, KVM_GET_API_VERSION, NULL); ++ if (ret != 12) ++ ksft_exit_fail_msg("KVM_GET_API_VERSION %d, expected 12", ret); ++ ++ run_size = ioctl(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); ++ if (run_size < sizeof(struct kvm_run)) ++ ksft_exit_fail_msg("KVM_GET_VCPU_MMAP_SIZE unexpectedly small\n"); ++ ++ return kvm; ++} ++ ++static int create_protected_vm(int kvm) ++{ ++ int vmfd = ioctl(kvm, KVM_CREATE_VM, KVM_VM_TYPE_ARM_PROTECTED); ++ ++ if (vmfd < 0) ++ ksft_exit_skip("Protected guests not supported: %d\n", vmfd); ++ ++ return vmfd; ++} ++ ++static int create_vcpu(int vmfd, struct kvm_run **run) ++{ ++ struct kvm_vcpu_init vcpu_init; ++ int vcpufd, ret; ++ ++ ret = ioctl(vmfd, KVM_ARM_PREFERRED_TARGET, &vcpu_init); ++ if (ret) ++ ksft_exit_fail_msg("Failed to set kvm_vcpu_init %d\n", ret); ++ ++ vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, (unsigned long)0); ++ if (vcpufd < 0) ++ ksft_exit_fail_msg("Failed to create VCPU: %d\n", vcpufd); ++ ++ *run = mmap(NULL, sizeof(**run), PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); ++ if (!run) ++ ksft_exit_fail_msg("Failed to mmap vcpu_run struct\n"); ++ ++ ret = ioctl(vcpufd, KVM_ARM_VCPU_INIT, &vcpu_init); ++ if (ret) ++ ksft_exit_fail_msg("Failed to initialize VCPU %d\n", ret); ++ ++ return vcpufd; ++} ++ ++static void teardown(int kvm, int vmfd, int vcpufd, struct kvm_run *run) ++{ ++ int ret = munmap(run, sizeof(*run)); ++ ++ if (ret) ++ ksft_exit_fail_msg("Failed to unmap vCPU run: %d\n", ret); ++ ++ ret = close(vcpufd); ++ if (ret) ++ ksft_exit_fail_msg("Failed to destroy VCPU: %d\n", ret); ++ ++ ret = close(vmfd); ++ if (ret) ++ ksft_exit_fail_msg("Failed to destroy VM: %d\n", ret); ++ ++ ret = close(kvm); ++ if (ret) ++ ksft_exit_fail_msg("Failed to close KVM fd: %d\n", ret); ++} ++ ++int main(void) ++{ ++ struct kvm_userspace_memory_region region; ++ long page_size = sysconf(_SC_PAGESIZE); ++ int ret, kvm, vmfd, vcpufd; ++ uint32_t guest_code[2]; ++ struct kvm_run *run; ++ uint8_t *guest_mem; ++ size_t run_size; ++ ++ kvm = get_kvm(); ++ vmfd = create_protected_vm(kvm); ++ vcpufd = create_vcpu(vmfd, &run); ++ ++ /* Create a one-page memslot for the guest */ ++ guest_mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_ANONYMOUS, -1, 0); ++ if (guest_mem == MAP_FAILED) ++ ksft_exit_fail_msg("Failed to mmap guest memory\n"); ++ region = (struct kvm_userspace_memory_region) { ++ .slot = 0, ++ .guest_phys_addr = 1UL << 30, ++ .memory_size = page_size, ++ .userspace_addr = (uint64_t)guest_mem, ++ }; ++ ++ /* Copy some code in guest memory. */ ++ guest_code[0] = 0xf9400001; /* 1: ldr x1, [x0] */ ++ guest_code[1] = 0x17ffffff; /* b 1b */ ++ memcpy(guest_mem, guest_code, sizeof(guest_code)); ++ ret = ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, ®ion); ++ if (ret) ++ ksft_exit_fail_msg("Failed to set memory region: %d\n", ret); ++ ++ /* ++ * Get the VCPU to run one instruction, to be sure the page containing ++ * the code has been faulted in. ++ */ ++ set_one_reg(vcpufd, REG_PC, region.guest_phys_addr); ++ set_one_reg(vcpufd, REG_X(0), region.guest_phys_addr + region.memory_size); ++ ret = ioctl(vcpufd, KVM_RUN, NULL); ++ if (ret) ++ ksft_exit_fail_msg("Failed to run vcpu: %d\n", ret); ++ if (run->exit_reason != KVM_EXIT_MMIO) ++ ksft_exit_fail_msg("Unexpected KVM exit reason: %u\n", run->exit_reason); ++ ++ /* ++ * Tear the guest down, and check that the donated memory has been ++ * wiped by the hypervisor. ++ */ ++ teardown(kvm, vmfd, vcpufd, run); ++ if (!memcmp(guest_mem, guest_code, sizeof(guest_code))) ++ ksft_exit_fail_msg("Protected guest memory has not been poisoned\n"); ++ ++ ksft_exit_pass(); ++} +-- +2.35.1.473.g83b2b277ed-goog + -- cgit v1.2.3 From 10821c981b23d1018d5baac33cdffe0062969198 Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Wed, 23 Feb 2022 13:37:54 +0000 Subject: ANDROID: Re-enable breakpoint_test for x86_64 Commit 739c390a ("ANDROID: build breakpoint tests") accidentally disabled breakpoint_test.c for x86_64. Re-enable the test. Bug: 67016038 Change-Id: I8731ac9c5ef81af93d1090f76a3c1f476c8260fe --- Android.bp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Android.bp b/Android.bp index 0b9166c56315..c53642de8e1a 100644 --- a/Android.bp +++ b/Android.bp @@ -126,6 +126,11 @@ cc_test { "tools/testing/selftests/breakpoints/breakpoint_test.c", ], }, + x86_64: { + srcs: [ + "tools/testing/selftests/breakpoints/breakpoint_test.c", + ], + }, }, } -- cgit v1.2.3 From 3fd0471619ebc3b9ab1f5541d4d430076bb378d5 Mon Sep 17 00:00:00 2001 From: "T.J. Mercier" Date: Fri, 4 Mar 2022 20:09:57 +0000 Subject: Remove duplicate -Wno-unused-parameter from default cflags Change-Id: I553029eac3cd249b7fd7c6fff1195b26724189d8 --- Android.bp | 1 - 1 file changed, 1 deletion(-) diff --git a/Android.bp b/Android.bp index 0b9166c56315..955cbc062b2b 100644 --- a/Android.bp +++ b/Android.bp @@ -76,7 +76,6 @@ cc_defaults { "-Wno-parentheses-equality", "-Wno-pointer-arith", "-Wno-sign-compare", - "-Wno-unused-parameter", "-Wno-shift-negative-value", "-Wno-switch", "-Wno-absolute-value", -- cgit v1.2.3 From 37ebb766e9540e65c3dd2061d576158fb879c462 Mon Sep 17 00:00:00 2001 From: Edward Liaw Date: Wed, 23 Mar 2022 23:21:21 +0000 Subject: selftests: binderfs skip when syscall unavailable Change pass to skip when the binderfs syscall is not supported Bug: 207175332 Bug: 208276189 Test: atest vts_linux_kselftest_arm_64:binderfs_arm_64#binderfs_arm_64 Change-Id: If28637c69c65b28bc68e6660f1df004efc436eb8 Signed-off-by: Edward Liaw --- ...ts-binderfs-skip-when-syscall-unavailable.patch | 33 ++++++++++++++++++++++ .../selftests/filesystems/binderfs/binderfs_test.c | 3 +- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch diff --git a/android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch b/android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch new file mode 100644 index 000000000000..30e99b90cac3 --- /dev/null +++ b/android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch @@ -0,0 +1,33 @@ +From fb64f30a1f159fb3359baf547f1199f980abe5d0 Mon Sep 17 00:00:00 2001 +From: Edward Liaw +Date: Wed, 23 Mar 2022 23:21:21 +0000 +Subject: [PATCH] selftests: binderfs skip when syscall unavailable + +Change pass to skip when the binderfs syscall is not supported + +Bug: 207175332 +Bug: 208276189 +Test: atest vts_linux_kselftest_arm_64:binderfs_arm_64#binderfs_arm_64 +Change-Id: If28637c69c65b28bc68e6660f1df004efc436eb8 +Signed-off-by: Edward Liaw +--- + tools/testing/selftests/filesystems/binderfs/binderfs_test.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c +index 4465b4f..e10f237 100644 +--- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c ++++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c +@@ -299,8 +299,7 @@ int main(int argc, char *argv[]) + { + /* Force success exit for older kernels */ + if (!binderfs_supported()) { +- ksft_print_msg("Skipping tests - binderfs not supported\n"); +- ksft_exit_pass(); ++ ksft_exit_skip("binderfs syscall not supported in this kernel\n"); + } + + binderfs_test_privileged(); +-- +2.35.1.1021.g381101b075-goog + diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c index 4465b4f6a81a..e10f2371921a 100644 --- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c +++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c @@ -299,8 +299,7 @@ int main(int argc, char *argv[]) { /* Force success exit for older kernels */ if (!binderfs_supported()) { - ksft_print_msg("Skipping tests - binderfs not supported\n"); - ksft_exit_pass(); + ksft_exit_skip("binderfs syscall not supported in this kernel\n"); } binderfs_test_privileged(); -- cgit v1.2.3 From b63639e78f209c31822ec723fe66a918f03b311a Mon Sep 17 00:00:00 2001 From: Edward Liaw Date: Thu, 24 Mar 2022 00:29:56 +0000 Subject: selftests: userfaultfd skip if unavailable Skip userfaultfd selftest if the syscall is not available for this kernel. Bug: 207175332 Bug: 206503000 Test: atest vts_linux_kselftest_arm_64:vm_userfaultfd_shmem_arm_64 Change-Id: I60e4d6cc5b3886048ffa1995e4b090f6fbe26b3d Signed-off-by: Edward Liaw --- ...selftests-userfaultfd-skip-if-unavailable.patch | 33 ++++++++++++++++++++++ tools/testing/selftests/vm/userfaultfd.c | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 android/patches/0025-selftests-userfaultfd-skip-if-unavailable.patch diff --git a/android/patches/0025-selftests-userfaultfd-skip-if-unavailable.patch b/android/patches/0025-selftests-userfaultfd-skip-if-unavailable.patch new file mode 100644 index 000000000000..0920fb307ed0 --- /dev/null +++ b/android/patches/0025-selftests-userfaultfd-skip-if-unavailable.patch @@ -0,0 +1,33 @@ +From 30c060a86f0e56c19e18ade48c0ee7592edfc317 Mon Sep 17 00:00:00 2001 +From: Edward Liaw +Date: Thu, 24 Mar 2022 00:29:56 +0000 +Subject: [PATCH] selftests: userfaultfd skip if unavailable + +Skip userfaultfd selftest if the syscall is not available for this +kernel. + +Bug: 207175332 +Bug: 206503000 +Test: atest vts_linux_kselftest_arm_64:vm_userfaultfd_shmem_arm_64 +Change-Id: I60e4d6cc5b3886048ffa1995e4b090f6fbe26b3d +Signed-off-by: Edward Liaw +--- + tools/testing/selftests/vm/userfaultfd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c +index ffc78f3..17947fe 100644 +--- a/tools/testing/selftests/vm/userfaultfd.c ++++ b/tools/testing/selftests/vm/userfaultfd.c +@@ -665,7 +665,7 @@ static int userfaultfd_open(int features) + if (errno == ENOSYS) { + fprintf(stderr, + "userfaultfd syscall not available in this kernel\n"); +- exit(KSFT_PASS); ++ exit(KSFT_SKIP); + } + fprintf(stderr, + "userfaultfd syscall failed with errno: %d\n", errno); +-- +2.35.1.1021.g381101b075-goog + diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index ffc78f3e4444..17947feb6d8e 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -665,7 +665,7 @@ static int userfaultfd_open(int features) if (errno == ENOSYS) { fprintf(stderr, "userfaultfd syscall not available in this kernel\n"); - exit(KSFT_PASS); + exit(KSFT_SKIP); } fprintf(stderr, "userfaultfd syscall failed with errno: %d\n", errno); -- cgit v1.2.3 From 105609e01d780fb78af0937557a11ebe5c6736bb Mon Sep 17 00:00:00 2001 From: Edward Liaw Date: Fri, 25 Mar 2022 23:03:22 +0000 Subject: Revert "selftests: binderfs skip when syscall unavailable" This reverts commit 37ebb766e9540e65c3dd2061d576158fb879c462. Reason for revert: Just need to revert aosp/1922582 instead of committing this change. Change-Id: I41ad84b9fe5bf437ad47d0f69e2c5c1227c0930f --- ...ts-binderfs-skip-when-syscall-unavailable.patch | 33 ---------------------- .../selftests/filesystems/binderfs/binderfs_test.c | 3 +- 2 files changed, 2 insertions(+), 34 deletions(-) delete mode 100644 android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch diff --git a/android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch b/android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch deleted file mode 100644 index 30e99b90cac3..000000000000 --- a/android/patches/0024-selftests-binderfs-skip-when-syscall-unavailable.patch +++ /dev/null @@ -1,33 +0,0 @@ -From fb64f30a1f159fb3359baf547f1199f980abe5d0 Mon Sep 17 00:00:00 2001 -From: Edward Liaw -Date: Wed, 23 Mar 2022 23:21:21 +0000 -Subject: [PATCH] selftests: binderfs skip when syscall unavailable - -Change pass to skip when the binderfs syscall is not supported - -Bug: 207175332 -Bug: 208276189 -Test: atest vts_linux_kselftest_arm_64:binderfs_arm_64#binderfs_arm_64 -Change-Id: If28637c69c65b28bc68e6660f1df004efc436eb8 -Signed-off-by: Edward Liaw ---- - tools/testing/selftests/filesystems/binderfs/binderfs_test.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c -index 4465b4f..e10f237 100644 ---- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c -+++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c -@@ -299,8 +299,7 @@ int main(int argc, char *argv[]) - { - /* Force success exit for older kernels */ - if (!binderfs_supported()) { -- ksft_print_msg("Skipping tests - binderfs not supported\n"); -- ksft_exit_pass(); -+ ksft_exit_skip("binderfs syscall not supported in this kernel\n"); - } - - binderfs_test_privileged(); --- -2.35.1.1021.g381101b075-goog - diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c index e10f2371921a..4465b4f6a81a 100644 --- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c +++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c @@ -299,7 +299,8 @@ int main(int argc, char *argv[]) { /* Force success exit for older kernels */ if (!binderfs_supported()) { - ksft_exit_skip("binderfs syscall not supported in this kernel\n"); + ksft_print_msg("Skipping tests - binderfs not supported\n"); + ksft_exit_pass(); } binderfs_test_privileged(); -- cgit v1.2.3 From 038daea820f66e757fc19655a0c02ea2db979941 Mon Sep 17 00:00:00 2001 From: Edward Liaw Date: Fri, 25 Mar 2022 23:06:03 +0000 Subject: Revert "Skip binderfs tests for kernels without support" This reverts commit 5cfe552d5b9ceee8db09822cb345c4dae2133561. Reason for revert: The framework now supports the KSFT_SKIP return code. Change-Id: I315e505689810a93b26a376f9df6794902706982 --- ...inderfs-skip-tests-for-unsupported-kernel.patch | 65 ---------------------- .../selftests/filesystems/binderfs/binderfs_test.c | 28 ---------- 2 files changed, 93 deletions(-) delete mode 100644 android/patches/0022-selftests-binderfs-skip-tests-for-unsupported-kernel.patch diff --git a/android/patches/0022-selftests-binderfs-skip-tests-for-unsupported-kernel.patch b/android/patches/0022-selftests-binderfs-skip-tests-for-unsupported-kernel.patch deleted file mode 100644 index 7b1e1a1c32bc..000000000000 --- a/android/patches/0022-selftests-binderfs-skip-tests-for-unsupported-kernel.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 57b74c1b318625057398ccbe479a157507488d8c Mon Sep 17 00:00:00 2001 -From: Carlos Llamas -Date: Tue, 14 Dec 2021 05:58:48 +0000 -Subject: [PATCH] selftests/binderfs: skip tests for unsupported kernels - -Binderfs was first introduced in Linux 5.0 release, so we need to skip -these tests for older kernels. Also, we force a successful exit as the -current framework doesn't handle KSFT_SKIP return codes. - -Signed-off-by: Carlos Llamas ---- - .../filesystems/binderfs/binderfs_test.c | 28 +++++++++++++++++++ - 1 file changed, 28 insertions(+) - -diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c -index 8c2ed962e1c7..be5a8f446066 100644 ---- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c -+++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c -@@ -12,6 +12,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -267,8 +268,35 @@ static void binderfs_test_unprivileged() - __do_binderfs_test(); - } - -+/* binderfs first introduced in Linux 5.0 */ -+bool binderfs_supported(void) -+{ -+ const int min_kernel_version = 5; -+ struct utsname utsname; -+ int ret, version; -+ -+ ret = uname(&utsname); -+ if (ret) -+ ksft_exit_fail_msg("%s - Failed to get kernel version\n", -+ strerror(errno)); -+ -+ ret = sscanf(utsname.release, "%d.", &version); -+ if (ret != 1) -+ ksft_exit_fail_msg("%s - Failed to parse uname: %s\n", -+ strerror(errno), utsname.release); -+ -+ return version >= min_kernel_version? true: false; -+} -+ -+ - int main(int argc, char *argv[]) - { -+ /* Force success exit for older kernels */ -+ if (!binderfs_supported()) { -+ ksft_print_msg("Skipping tests - binderfs not supported\n"); -+ ksft_exit_pass(); -+ } -+ - binderfs_test_privileged(); - binderfs_test_unprivileged(); - ksft_exit_pass(); --- -2.34.1.173.g76aa8bc2d0-goog - diff --git a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c index 4465b4f6a81a..397bf265ba97 100644 --- a/tools/testing/selftests/filesystems/binderfs/binderfs_test.c +++ b/tools/testing/selftests/filesystems/binderfs/binderfs_test.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -274,35 +273,8 @@ static void binderfs_test_unprivileged() __do_binderfs_test(); } -/* binderfs first introduced in Linux 5.0 */ -bool binderfs_supported(void) -{ - const int min_kernel_version = 5; - struct utsname utsname; - int ret, version; - - ret = uname(&utsname); - if (ret) - ksft_exit_fail_msg("%s - Failed to get kernel version\n", - strerror(errno)); - - ret = sscanf(utsname.release, "%d.", &version); - if (ret != 1) - ksft_exit_fail_msg("%s - Failed to parse uname: %s\n", - strerror(errno), utsname.release); - - return version >= min_kernel_version? true: false; -} - - int main(int argc, char *argv[]) { - /* Force success exit for older kernels */ - if (!binderfs_supported()) { - ksft_print_msg("Skipping tests - binderfs not supported\n"); - ksft_exit_pass(); - } - binderfs_test_privileged(); binderfs_test_unprivileged(); ksft_exit_pass(); -- cgit v1.2.3