From patchwork Wed Jul 10 23:42:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Houghton X-Patchwork-Id: 13729887 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B5F8AC3DA42 for ; Wed, 10 Jul 2024 23:48:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:Cc:To:From: Subject:Message-ID:References:Mime-Version:In-Reply-To:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=23lW1dYHwRXqrRIzh0tt4ShqtRWFD2EoChbCYcPjw+M=; b=LR348izzv6qM081rqf33TTzzyZ 71AtLye6IMsjjOMwhuGxlD1Beox8sjnbcs98CIqwqZy6COIi3MQFGW35RaMaj0A+1soLUgvCJWCUu d8eb6DTviaBO/X6NVHbWLoO5BrkUGfOO8rDO1XWpsRgZNpKamLIQrasYq6bWIltev4n11xQqyc3bf GklunhCeyi0xX3iYAqb/pfJEeDleRIR20Z94O3nVWMUxoOO1p3Fx7JDfIDoDrEe+jwUlYiQpMNDrz x447x8WXDtlF8eB0UZEwv9fWAa8JXpEZzKPed85MERF2zbpkCYVBcoRmoDz5lX9+9PVsPqe0c/8mw /9wlFR9w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sRh2P-0000000CA02-1oz1; Wed, 10 Jul 2024 23:47:53 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sRgxb-0000000C7KJ-402c for linux-arm-kernel@lists.infradead.org; Wed, 10 Jul 2024 23:42:59 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id 3f1490d57ef6-e035949cc4eso539166276.1 for ; Wed, 10 Jul 2024 16:42:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1720654975; x=1721259775; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=23lW1dYHwRXqrRIzh0tt4ShqtRWFD2EoChbCYcPjw+M=; b=udtYkoF5pyJ5jsWcVt/tus//LPDp1ZWKbGAQwk/sauuWhl63zMnFEtbRVjLUZ04aOA U0HmhNAuBi5RyBIjbISdC2fbYogYfxSZaMvAg3xxwDoRj0lSKoWGwhKAEz9nyaeQZmcH 1bvzs5Rw/P8kDy6ANJrC9D0kRJiW9EwHmP+u2zopPBb42t7unVUa7n2Zl9LTQAL0EMqr gERgi7IoYqr9K5U5EcNPmMsFQA+VZBLMWNxYb3N4oKHsVX0mXrA47VIaeJayl3l2BdC1 /imPhPRZd0Ac3W8ShdOfpEg8ewT7AAC1w0/tcRRyJ1Wq2NvzzvKNax3hjghdj+hiLbSN Lzgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720654975; x=1721259775; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=23lW1dYHwRXqrRIzh0tt4ShqtRWFD2EoChbCYcPjw+M=; b=C08IOjYMITIGClehkhFcob4FXHxPXBmUY+ZAoc3v/ShXk+QHBlrEU5FS/17X1TIcg2 GpWG7vVL7Rrwq0g58rS7b+vgE2jp9MvwSDhQSxd2RA87RRMHh0Jd/a1CtHA4o7ssJPVl CyxYEUYikKVI/R7BFF5M+9QpNcoM2yYnPNJLMbhniev0ry9tLKPNbENeOpkrNkDQWkXp SaVgTOFidam49WILmi/c/6Z9+VTiM06xPLCYmZLQKq02OLwKu76MD6a+NFt5bFwTSy4P mdB02MaaN4HNFe0reVJs4a5GpW9G1Na5zrVrL9bAQX5DWKFqFdvo3aMRca14gEohl/SJ AdjA== X-Forwarded-Encrypted: i=1; AJvYcCXxss3yB6oC0eWFns71gMjt5/7OouEPyYArlWcJCYydZhEor/gN5ApZgdhMR8t0z/k12WE69AQwvcCras3s5/S4KAfUbxKjq8jQM2gqbUpBArduYMc= X-Gm-Message-State: AOJu0Yzj3HlXews7/HWEsam5L9kuIwFZ54M9vtGMHB8KKdF35++DNXqM 7G0nipAC3QgqJUVAejPptNbV3Elp/vM70vF2kxcrCxM4DQA/pOOP9e5r59lv3yluuNengAcL1Gz x4QJz/eS8UN+Mhd0/og== X-Google-Smtp-Source: AGHT+IH2x5mDHjhnJd4Mu/PM7RGmCTtDANjq+WihoofI52RvaYh1X5nH2Cnmm44GTYY+PggisrUn2Jo0WRfC2acE X-Received: from jthoughton.c.googlers.com ([fda3:e722:ac3:cc00:14:4d90:c0a8:2a4f]) (user=jthoughton job=sendgmr) by 2002:a05:6902:1ac1:b0:e03:62dc:63de with SMTP id 3f1490d57ef6-e041b0593efmr582356276.6.1720654974739; Wed, 10 Jul 2024 16:42:54 -0700 (PDT) Date: Wed, 10 Jul 2024 23:42:21 +0000 In-Reply-To: <20240710234222.2333120-1-jthoughton@google.com> Mime-Version: 1.0 References: <20240710234222.2333120-1-jthoughton@google.com> X-Mailer: git-send-email 2.45.2.993.g49e7a77208-goog Message-ID: <20240710234222.2333120-18-jthoughton@google.com> Subject: [RFC PATCH 17/18] KVM: selftests: Add KVM Userfault mode to demand_paging_test From: James Houghton To: Paolo Bonzini Cc: Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Zenghui Yu , Sean Christopherson , Shuah Khan , Peter Xu , Axel Rasmussen , David Matlack , James Houghton , kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240710_164256_124994_CAD24B76 X-CRM114-Status: GOOD ( 16.49 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The KVM Userfault mode checks that we are able to resolve KVM Userfaults and the vCPUs will continue to make progress. It initially sets all of guest memory as KVM_MEMORY_ATTRIBUTE_USERFAULT, then, as the test runs, clears the attribute from pages as they are faulted on. This test does not currently check for asynchronous page faults. Signed-off-by: James Houghton --- .../selftests/kvm/demand_paging_test.c | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index 0202b78f8680..8654b58091b2 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -28,6 +28,13 @@ static uint64_t guest_percpu_mem_size = DEFAULT_PER_VCPU_MEM_SIZE; static size_t demand_paging_size; static char *guest_data_prototype; +bool userfault_enabled = false; + +static void resolve_kvm_userfault(u64 gpa, u64 size) +{ + /* Toggle KVM_MEMORY_ATTRIBUTE_USERFAULT off */ + vm_set_memory_attributes(memstress_args.vm, gpa, size, 0); +} static void vcpu_worker(struct memstress_vcpu_args *vcpu_args) { @@ -41,8 +48,22 @@ static void vcpu_worker(struct memstress_vcpu_args *vcpu_args) clock_gettime(CLOCK_MONOTONIC, &start); /* Let the guest access its memory */ +restart: ret = _vcpu_run(vcpu); - TEST_ASSERT(ret == 0, "vcpu_run failed: %d", ret); + if (ret < 0 && errno == EFAULT && userfault_enabled) { + /* Check for userfault. */ + TEST_ASSERT(run->exit_reason == KVM_EXIT_MEMORY_FAULT, + "Got invalid exit reason: %llx", run->exit_reason); + TEST_ASSERT(run->memory_fault.flags == + KVM_MEMORY_EXIT_FLAG_USERFAULT, + "Got invalid memory fault exit: %llx", + run->memory_fault.flags); + resolve_kvm_userfault(run->memory_fault.gpa, + run->memory_fault.size); + goto restart; + } else + TEST_ASSERT(ret == 0, "vcpu_run failed: %d", ret); + if (get_ucall(vcpu, NULL) != UCALL_SYNC) { TEST_ASSERT(false, "Invalid guest sync status: exit_reason=%s", @@ -136,6 +157,7 @@ struct test_params { int readers_per_uffd; enum vm_mem_backing_src_type src_type; bool partition_vcpu_memory_access; + bool kvm_userfault; }; static void prefault_mem(void *alias, uint64_t len) @@ -206,6 +228,17 @@ static void run_test(enum vm_guest_mode mode, void *arg) } } + if (p->kvm_userfault) { + TEST_REQUIRE(kvm_has_cap(KVM_CAP_USERFAULT)); + vm_enable_cap(vm, KVM_CAP_USERFAULT, KVM_USERFAULT_ENABLE); + TEST_REQUIRE(kvm_check_cap(KVM_CAP_MEMORY_ATTRIBUTES) & + KVM_MEMORY_ATTRIBUTE_USERFAULT); + vm_set_memory_attributes(vm, memstress_args.gpa, + memstress_args.size, + KVM_MEMORY_ATTRIBUTE_USERFAULT); + userfault_enabled = true; + } + pr_info("Finished creating vCPUs and starting uffd threads\n"); clock_gettime(CLOCK_MONOTONIC, &start); @@ -232,6 +265,11 @@ static void run_test(enum vm_guest_mode mode, void *arg) pr_info("Overall demand paging rate:\t%f pgs/sec\n", vcpu_paging_rate * nr_vcpus); + if (p->kvm_userfault) { + vm_enable_cap(vm, KVM_CAP_USERFAULT, KVM_USERFAULT_DISABLE); + userfault_enabled = false; + } + memstress_destroy_vm(vm); free(guest_data_prototype); @@ -263,6 +301,7 @@ static void help(char *name) printf(" -v: specify the number of vCPUs to run.\n"); printf(" -o: Overlap guest memory accesses instead of partitioning\n" " them into a separate region of memory for each vCPU.\n"); + printf(" -k: Use KVM Userfault\n"); puts(""); exit(0); } @@ -281,7 +320,7 @@ int main(int argc, char *argv[]) guest_modes_append_default(); - while ((opt = getopt(argc, argv, "ahom:u:d:b:s:v:c:r:")) != -1) { + while ((opt = getopt(argc, argv, "ahokm:u:d:b:s:v:c:r:")) != -1) { switch (opt) { case 'm': guest_modes_cmdline(optarg); @@ -324,6 +363,9 @@ int main(int argc, char *argv[]) "Invalid number of readers per uffd %d: must be >=1", p.readers_per_uffd); break; + case 'k': + p.kvm_userfault = true; + break; case 'h': default: help(argv[0]);