Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp861485iog; Mon, 13 Jun 2022 14:44:39 -0700 (PDT) X-Google-Smtp-Source: AGRyM1slt8jDDmuTAAHxoJidPm1VyyHz2lkatMAQuCmZU9qhH2zLXCB7aumPQabvQVA/F2yVENUV X-Received: by 2002:a17:902:f710:b0:167:7a06:b2ce with SMTP id h16-20020a170902f71000b001677a06b2cemr1170290plo.104.1655156679165; Mon, 13 Jun 2022 14:44:39 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655156679; cv=none; d=google.com; s=arc-20160816; b=eO1bffZOSMropqirFXEQpHg1cjs8RfcbgqGCdRgVCiDtQ7mVTUE1+tekASztjR9q8P S/o67vaYSdNHP3VSs0AiLb9mxv1RP/Gzl1abUlAuC28SRejLbMV0M0HDtSrOW4gtXEkM 0vLPme3h/wZRg9HobLR2a60ncz/Px83ggJoIT8IzEqOXMvkG6kAf4W4Ogf5DQEGr/k1Q 1Aw9UWVH9aDHVum+T8GNJm36XBkUEjo+BlI1EgJWOM0eF+f39NcyeSak2PS852lAFgsM 9FUUtN9uttT/u6N75GqqA1QnBnS91RpfFPZ2dcttkBBbpBl0dloIggydGO1WxU24vraE 64wQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=ff4fVSapUxUvxB9n2Zl0T+CskRaCkgl+6PL+fmMltA8=; b=GnBY7OLtC6Glgt/DBSYmAVGZxmk4YoyN2M/iyHBQhHftNJI9OpytGxP/Pgs+A4itsm S66kb8KFFGBL1gvCv4McUJxjAZ2nQr22DNJKB90aTRcUN4Lh42NWvEn0CK5Qb9BTRy6l ibAJ7JuuPKvd4Nnyw62gSQYbllKV0N7RHfFVHgNkmVfqiy3Dy892Jz91k9NTINDO7gnA mzd8LrLjdYpbSR23NOn+b7V3Is3LCGfxy/Ynt3R7a1VjQVCVLLE1YgR/Wz+TZintFkkM te1OI2Z+TemDev7/G2dVbeZ6+1bQtY4LXkEvXXVAM3VqadmmifL98kPTIyICJeUZkC0z rUpA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=ViU1g4IX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s126-20020a625e84000000b004fae70007c5si9279146pfb.78.2022.06.13.14.44.27; Mon, 13 Jun 2022 14:44:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=ViU1g4IX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240682AbiFMVbA (ORCPT + 99 others); Mon, 13 Jun 2022 17:31:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60452 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1353189AbiFMV3Z (ORCPT ); Mon, 13 Jun 2022 17:29:25 -0400 Received: from mail-pl1-x64a.google.com (mail-pl1-x64a.google.com [IPv6:2607:f8b0:4864:20::64a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B6202C62 for ; Mon, 13 Jun 2022 14:25:41 -0700 (PDT) Received: by mail-pl1-x64a.google.com with SMTP id s10-20020a170902a50a00b00162359521c9so3634058plq.23 for ; Mon, 13 Jun 2022 14:25:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ff4fVSapUxUvxB9n2Zl0T+CskRaCkgl+6PL+fmMltA8=; b=ViU1g4IXRwdIhNofi8BH7fqSlsEv32y03c03Y02Vk+QIDq1vArSJfsn201yYUkUbKU W3wDGy7regdl6SSjmTlUtL/0MFrnZ2IRaUNkIhYCgtkhWjpK8MrVkbXRM4Eb8MDkWugK 0lI0IiD+26eyChVxDUVkVRAkcq2Vl4RoWM2d3NAH12Ghc5c6J2AmU1t2rl0vEEMQ5AZe 6zdP/Q8wKiY4QjpSFP+4ff37r2dHTqSe/FrRLG7AWzOfhzcMX+pTN749wHNbdLSveyk6 My1v8Hy/fMfpucWLbFm1eX5AVIOvif7SuHa5wVg0G1IWQDTWfruof1pjyqRjVfu3Ni+7 rQ8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ff4fVSapUxUvxB9n2Zl0T+CskRaCkgl+6PL+fmMltA8=; b=I3u+kq47fwIGzHL/VB0UK0u9altplnA2cSw80QFFBaw6cR0TPuex1PJV/wGakiOuPe nFo3TYHLki/9hivPwR1t5xPiAT2ILGzY3qoKqUJpbn2CJv1LLVeCGCFeclQRz9tBJDp7 VPPjbNgeEareSsdwE2RbNzSbbeZLp/2y41zm1d9c5N1jEroA5niHBDtxq3KDNMlDGLeJ mD8Lj22xy6N40vseJNpDd80hz29qIwSmDcKfkc/Ut55wFb6lQhso09Oj3o8NVeWV/kjw eWP3ipMSUvKR9Zm25aAPTnMDNgSvLH2E5Aw+jBPTDhT3/xVuJnpGa6d1guUwHPkH28wE 97/g== X-Gm-Message-State: AOAM533tbj0clHfuE/PQpv+UDwsukwv7BCgzQj+eebQMj74xfdl9NnDm 1xMRhNEM8AezprEZbsfiVUL3rKwwhItP X-Received: from sweer.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:e45]) (user=bgardon job=sendgmr) by 2002:aa7:92d2:0:b0:51b:4d60:6475 with SMTP id k18-20020aa792d2000000b0051b4d606475mr1251862pfa.73.1655155541209; Mon, 13 Jun 2022 14:25:41 -0700 (PDT) Date: Mon, 13 Jun 2022 21:25:22 +0000 In-Reply-To: <20220613212523.3436117-1-bgardon@google.com> Message-Id: <20220613212523.3436117-10-bgardon@google.com> Mime-Version: 1.0 References: <20220613212523.3436117-1-bgardon@google.com> X-Mailer: git-send-email 2.36.1.476.g0c4daa206d-goog Subject: [PATCH v9 09/10] KVM: selftests: Test disabling NX hugepages on a VM From: Ben Gardon To: kvm@vger.kernel.org, Paolo Bonzini Cc: linux-kernel@vger.kernel.org, Peter Xu , Sean Christopherson , David Matlack , Jim Mattson , David Dunn , Jing Zhang , Junaid Shahid , Ben Gardon Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add an argument to the NX huge pages test to test disabling the feature on a VM using the new capability. Reviewed-by: David Matlack Signed-off-by: Ben Gardon --- .../selftests/kvm/include/kvm_util_base.h | 6 + .../selftests/kvm/x86_64/nx_huge_pages_test.c | 134 ++++++++++++------ .../kvm/x86_64/nx_huge_pages_test.sh | 14 +- 3 files changed, 106 insertions(+), 48 deletions(-) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 81ab7adfbef5..537b8a047d6e 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -804,4 +804,10 @@ static inline void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent) virt_arch_dump(stream, vm, indent); } + +static inline int __vm_disable_nx_huge_pages(struct kvm_vm *vm) +{ + return __vm_enable_cap(vm, KVM_CAP_VM_DISABLE_NX_HUGE_PAGES, 0); +} + #endif /* SELFTEST_KVM_UTIL_BASE_H */ 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 5fa61d225787..cc6421716400 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 @@ -107,53 +107,34 @@ static void wait_for_reclaim(int reclaim_period_ms) nanosleep(&ts, NULL); } -static void help(char *name) -{ - puts(""); - printf("usage: %s [-h] [-p period_ms] [-t token]\n", name); - puts(""); - printf(" -p: The NX reclaim period in miliseconds.\n"); - printf(" -t: The magic token to indicate environment setup is done.\n"); - puts(""); - exit(0); -} - -int main(int argc, char **argv) +void run_test(int reclaim_period_ms, bool disable_nx_huge_pages, + bool reboot_permissions) { - int reclaim_period_ms = 0, token = 0, opt; struct kvm_vcpu *vcpu; struct kvm_vm *vm; void *hva; + int r; - while ((opt = getopt(argc, argv, "hp:t:")) != -1) { - switch (opt) { - case 'p': - reclaim_period_ms = atoi(optarg); - break; - case 't': - token = atoi(optarg); - break; - case 'h': - default: - help(argv[0]); - break; - } - } - - if (token != MAGIC_TOKEN) { - print_skip("This test must be run with the magic token %d.\n" - "This is done by nx_huge_pages_test.sh, which\n" - "also handles environment setup for the test.", - MAGIC_TOKEN); - exit(KSFT_SKIP); - } + vm = vm_create(1); - if (!reclaim_period_ms) { - print_skip("The NX reclaim period must be specified and non-zero"); - exit(KSFT_SKIP); + if (disable_nx_huge_pages) { + /* + * Cannot run the test without NX huge pages if the kernel + * does not support it. + */ + if (!kvm_check_cap(KVM_CAP_VM_DISABLE_NX_HUGE_PAGES)) + return; + + r = __vm_disable_nx_huge_pages(vm); + if (reboot_permissions) { + TEST_ASSERT(!r, "Disabling NX huge pages should succeed if process has reboot permissions"); + } else { + TEST_ASSERT(r == -1 && errno == EPERM, + "This process should not have permission to disable NX huge pages"); + return; + } } - vm = vm_create(1); vcpu = vm_vcpu_add(vm, 0, guest_code); vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS_HUGETLB, @@ -187,31 +168,38 @@ int main(int argc, char **argv) /* * Next, the guest will execute from the first huge page, causing it * to be remapped at 4k. + * + * If NX huge pages are disabled, this should have no effect. */ vcpu_run(vcpu); - check_2m_page_count(vm, 1); - check_split_count(vm, 1); + check_2m_page_count(vm, disable_nx_huge_pages ? 2 : 1); + check_split_count(vm, disable_nx_huge_pages ? 0 : 1); /* * Executing from the third huge page (previously unaccessed) will * cause part to be mapped at 4k. + * + * If NX huge pages are disabled, it should be mapped at 2M. */ vcpu_run(vcpu); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 1); + check_split_count(vm, disable_nx_huge_pages ? 0 : 2); /* Reading from the first huge page again should have no effect. */ vcpu_run(vcpu); - check_2m_page_count(vm, 1); - check_split_count(vm, 2); + check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 1); + check_split_count(vm, disable_nx_huge_pages ? 0 : 2); /* Give recovery thread time to run. */ wait_for_reclaim(reclaim_period_ms); /* * Now that the reclaimer has run, all the split pages should be gone. + * + * If NX huge pages are disabled, the relaimer will not run, so + * nothing should change from here on. */ - check_2m_page_count(vm, 1); + check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 1); check_split_count(vm, 0); /* @@ -219,10 +207,62 @@ int main(int argc, char **argv) * reading from it causes a huge page mapping to be installed. */ vcpu_run(vcpu); - check_2m_page_count(vm, 2); + check_2m_page_count(vm, disable_nx_huge_pages ? 3 : 2); check_split_count(vm, 0); kvm_vm_free(vm); +} + +static void help(char *name) +{ + puts(""); + printf("usage: %s [-h] [-p period_ms] [-t token]\n", name); + puts(""); + printf(" -p: The NX reclaim period in miliseconds.\n"); + printf(" -t: The magic token to indicate environment setup is done.\n"); + printf(" -r: The test has reboot permissions and can disable NX huge pages.\n"); + puts(""); + exit(0); +} + +int main(int argc, char **argv) +{ + int reclaim_period_ms = 0, token = 0, opt; + bool reboot_permissions = false; + + while ((opt = getopt(argc, argv, "hp:t:r")) != -1) { + switch (opt) { + case 'p': + reclaim_period_ms = atoi(optarg); + break; + case 't': + token = atoi(optarg); + break; + case 'r': + reboot_permissions = true; + break; + case 'h': + default: + help(argv[0]); + break; + } + } + + if (token != MAGIC_TOKEN) { + print_skip("This test must be run with the magic token %d.\n" + "This is done by nx_huge_pages_test.sh, which\n" + "also handles environment setup for the test.", + MAGIC_TOKEN); + exit(KSFT_SKIP); + } + + if (!reclaim_period_ms) { + print_skip("The NX reclaim period must be specified and non-zero"); + exit(KSFT_SKIP); + } + + run_test(reclaim_period_ms, false, reboot_permissions); + run_test(reclaim_period_ms, true, reboot_permissions); return 0; } 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 4e090a84f5f3..6bd8e026ee61 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 @@ -20,6 +20,8 @@ function sudo_echo () { echo "$1" | sudo tee -a "$2" > /dev/null } +NXECUTABLE="$(dirname $0)/nx_huge_pages_test" + ( set -e @@ -28,7 +30,17 @@ function sudo_echo () { sudo_echo 100 /sys/module/kvm/parameters/nx_huge_pages_recovery_period_ms sudo_echo "$(( $HUGE_PAGES + 3 ))" /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages - "$(dirname $0)"/nx_huge_pages_test -t 887563923 -p 100 + # Test with reboot permissions + if [ $(whoami) != "root" ] ; then + sudo setcap cap_sys_boot+ep $NXECUTABLE + fi + $NXECUTABLE -t 887563923 -p 100 -r + + # Test without reboot permissions + if [ $(whoami) != "root" ] ; then + sudo setcap cap_sys_boot-ep $NXECUTABLE + $NXECUTABLE -t 887563923 -p 100 + fi ) RET=$? -- 2.36.1.476.g0c4daa206d-goog