Add an argument to the NX huge pages test to test disabling the feature on a VM using the new capability. Signed-off-by: Ben Gardon <bgardon@xxxxxxxxxx> --- .../selftests/kvm/include/kvm_util_base.h | 2 + tools/testing/selftests/kvm/lib/kvm_util.c | 7 +++ .../selftests/kvm/x86_64/nx_huge_pages_test.c | 49 ++++++++++++++----- .../kvm/x86_64/nx_huge_pages_test.sh | 2 +- 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 530b5272fae2..8302cf9b1e1d 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -420,4 +420,6 @@ uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name); uint32_t guest_get_vcpuid(void); +void vm_disable_nx_huge_pages(struct kvm_vm *vm); + #endif /* SELFTEST_KVM_UTIL_BASE_H */ diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index f9591dad1010..880786fe9fac 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -2760,3 +2760,10 @@ uint64_t vm_get_single_stat(struct kvm_vm *vm, const char *stat_name) return value; } +void vm_disable_nx_huge_pages(struct kvm_vm *vm) +{ + struct kvm_enable_cap cap = { 0 }; + + cap.cap = KVM_CAP_VM_DISABLE_NX_HUGE_PAGES; + vm_enable_cap(vm, &cap); +} diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c index 5cbcc777d0ab..1020a4758664 100644 --- a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.c @@ -56,12 +56,39 @@ static void check_split_count(struct kvm_vm *vm, int expected_splits) expected_splits, actual_splits); } +static void help(void) +{ + puts(""); + printf("usage: nx_huge_pages_test.sh [-x]\n"); + puts(""); + printf(" -x: Allow executable huge pages on the VM.\n"); + puts(""); + exit(0); +} + int main(int argc, char **argv) { struct kvm_vm *vm; + bool disable_nx = false; + int opt; + + while ((opt = getopt(argc, argv, "x")) != -1) { + switch (opt) { + case 'x': + disable_nx = true; + break; + case 'h': + default: + help(); + break; + } + } vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR); + if (disable_nx) + vm_disable_nx_huge_pages(vm); + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_HUGETLB, HPAGE_PADDR_START, HPAGE_SLOT, HPAGE_SLOT_NPAGES, 0); @@ -81,25 +108,25 @@ int main(int argc, char **argv) * at 2M. */ run_guest_code(vm, guest_code0); - check_2m_page_count(vm, 2); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 4 : 2); + check_split_count(vm, disable_nx ? 0 : 2); /* * guest_code1 is in the same huge page as data1, so it will cause * that huge page to be remapped at 4k. */ run_guest_code(vm, guest_code1); - check_2m_page_count(vm, 1); - check_split_count(vm, 3); + check_2m_page_count(vm, disable_nx ? 4 : 1); + check_split_count(vm, disable_nx ? 0 : 3); /* Run guest_code0 again to check that is has no effect. */ run_guest_code(vm, guest_code0); - check_2m_page_count(vm, 1); - check_split_count(vm, 3); + check_2m_page_count(vm, disable_nx ? 4 : 1); + check_split_count(vm, disable_nx ? 0 : 3); /* Give recovery thread time to run */ sleep(3); - check_2m_page_count(vm, 1); + check_2m_page_count(vm, disable_nx ? 4 : 1); check_split_count(vm, 0); /* @@ -107,13 +134,13 @@ int main(int argc, char **argv) * again to check that pages are mapped at 2M again. */ run_guest_code(vm, guest_code0); - check_2m_page_count(vm, 2); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx ? 4 : 2); + check_split_count(vm, disable_nx ? 0 : 2); /* Pages are once again split from running guest_code1. */ run_guest_code(vm, guest_code1); - check_2m_page_count(vm, 1); - check_split_count(vm, 3); + check_2m_page_count(vm, disable_nx ? 4 : 1); + check_split_count(vm, disable_nx ? 0 : 3); kvm_vm_free(vm); diff --git a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh index a5f946fb0626..205d8c9fd750 100755 --- a/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh +++ b/tools/testing/selftests/kvm/x86_64/nx_huge_pages_test.sh @@ -14,7 +14,7 @@ echo 1 > /sys/module/kvm/parameters/nx_huge_pages_recovery_ratio echo 2 > /sys/module/kvm/parameters/nx_huge_pages_recovery_period_ms echo 200 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages -./nx_huge_pages_test +./nx_huge_pages_test "${@}" RET=$? echo $NX_HUGE_PAGES > /sys/module/kvm/parameters/nx_huge_pages -- 2.35.1.616.g0bdcbb4464-goog