From patchwork Fri Sep 27 16:18:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164795 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3A17F112B for ; Fri, 27 Sep 2019 16:18:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0331B217D9 for ; Fri, 27 Sep 2019 16:18:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ULK6gXR8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728031AbfI0QSo (ORCPT ); Fri, 27 Sep 2019 12:18:44 -0400 Received: from mail-pl1-f202.google.com ([209.85.214.202]:36684 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727472AbfI0QSn (ORCPT ); Fri, 27 Sep 2019 12:18:43 -0400 Received: by mail-pl1-f202.google.com with SMTP id z7so1930745plo.3 for ; Fri, 27 Sep 2019 09:18:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=qJ+LEDwdF8ZWMIEms9IYF0Bd8vnOKy8mjBBE8Ycu9gw=; b=ULK6gXR8q5rgcooUN6wDCQ/pTf8NwdYYNiCy6cjbhuIS2ezT7GYhy4/vgE6FmnUTT1 5MKcEh7fxqwQTWAXTn6Tb3by3YE7WT6BqXILzo8gUcn7Gq/gi98/7rCkJ1xA3eT0BkBl F0p+s2CJRCH+Wjvwe0/neMzuCKEU/y5TGLfXTu3jHInGwvMO64M9kcWVjDfgtY/+PtfW 9w0R1qYc4ptK58lSQDf1kswZnH2JSKge/V05b52rbzv+8mmt5kYbQ8byAUAXH1TNS4qj CVJdLKin//zcp3c0Q7jJP9k2yKtproIqzwidaWKR+cEgsN3/vZNULxQluLmjU1Cld6k8 ekXw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qJ+LEDwdF8ZWMIEms9IYF0Bd8vnOKy8mjBBE8Ycu9gw=; b=Y4E+FUrOHwtdHTvjmASijCwl6cPC1IEKvxX6tvTh9rZy74MMyh7fxrNiiBSx0IoJIj qmvFE+emyEN3UtbwCRshUvOSxrHVVJlwV4AzyHsl2w547ScaKf8M3CQJV6+vUfsrD75r h7KkbAMCMP0gisQ5TYhHcfJBmhvo1+15TJcceeUkmFMg+jzj8mT1aR3mXdIb56ryG2KW NsFs8ouAFBjDcr3/GVnt4PCbFtl5ZEaOLGAYBDLuiWJRS9SBpHZKJT3A2RRwSgDqPqNj ms1KXOlmEsUfizXPRtOuNR7mYZhVGi6LQ0o7v9q95YNz5ksmWFYmPgWWVybzM8WWHDyR zqqg== X-Gm-Message-State: APjAAAUxXCHIArDTV4DaLvrXvZpY2ZksTTyYC4db87Vb+4El4JE9cmcc Vq+NhzfsGmhRIoqjr38EgdpTFCyd4VYzTSjlFn+VpmO5Q0PKKkOxfW/Ump8fT/iuDXNeQbTrrvk xa7/pvXm82HjuePwYqYI8XO/A3m5OVBN8oDjDkrmd9qJsaRVGMXZYQe3a9mU2 X-Google-Smtp-Source: APXvYqxds/SzjvGjI/EquH8fe9HqsqZXZoJ2mRqpd9OwXaJvs5LhfB82U2/4JSofrqKajWDxvoPV2iM2gfIn X-Received: by 2002:a63:d343:: with SMTP id u3mr10192159pgi.313.1569601122074; Fri, 27 Sep 2019 09:18:42 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:29 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-2-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 1/9] KVM: selftests: Create a demand paging test From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org While userfaultfd, KVM's demand paging implementation, is not specific to KVM, having a benchmark for its performance will be useful for guiding performance improvements to KVM. As a first step towards creating a userfaultfd demand paging test, create a simple memory access test, based on dirty_log_test. Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/.gitignore | 1 + tools/testing/selftests/kvm/Makefile | 2 + .../selftests/kvm/demand_paging_test.c | 286 ++++++++++++++++++ 3 files changed, 289 insertions(+) create mode 100644 tools/testing/selftests/kvm/demand_paging_test.c diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index b35da375530af..29da0cdd98579 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -14,3 +14,4 @@ /clear_dirty_log_test /dirty_log_test /kvm_create_max_vcpus +/demand_paging_test diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 62c591f87dabb..31f2b8afa7461 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -26,10 +26,12 @@ TEST_GEN_PROGS_x86_64 += x86_64/vmx_set_nested_state_test TEST_GEN_PROGS_x86_64 += x86_64/vmx_tsc_adjust_test TEST_GEN_PROGS_x86_64 += clear_dirty_log_test TEST_GEN_PROGS_x86_64 += dirty_log_test +TEST_GEN_PROGS_x86_64 += demand_paging_test TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus TEST_GEN_PROGS_aarch64 += clear_dirty_log_test TEST_GEN_PROGS_aarch64 += dirty_log_test +TEST_GEN_PROGS_aarch64 += demand_paging_test TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus TEST_GEN_PROGS_s390x = s390x/memop diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c new file mode 100644 index 0000000000000..5f214517ba1de --- /dev/null +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KVM demand paging test + * Adapted from dirty_log_test.c + * + * Copyright (C) 2018, Red Hat, Inc. + * Copyright (C) 2019, Google, Inc. + */ + +#define _GNU_SOURCE /* for program_invocation_name */ + +#include +#include +#include +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "processor.h" + +#define VCPU_ID 1 + +/* The memory slot index demand page */ +#define TEST_MEM_SLOT_INDEX 1 + +/* Default guest test virtual memory offset */ +#define DEFAULT_GUEST_TEST_MEM 0xc0000000 + +/* + * Guest/Host shared variables. Ensure addr_gva2hva() and/or + * sync_global_to/from_guest() are used when accessing from + * the host. READ/WRITE_ONCE() should also be used with anything + * that may change. + */ +static uint64_t host_page_size; +static uint64_t guest_page_size; +static uint64_t guest_num_pages; + +/* + * Guest physical memory offset of the testing memory slot. + * This will be set to the topmost valid physical address minus + * the test memory size. + */ +static uint64_t guest_test_phys_mem; + +/* + * Guest virtual memory offset of the testing memory slot. + * Must not conflict with identity mapped test code. + */ +static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM; + +/* + * Continuously write to the first 8 bytes of each page in the demand paging + * memory region. + */ +static void guest_code(void) +{ + int i; + + for (i = 0; i < guest_num_pages; i++) { + uint64_t addr = guest_test_virt_mem; + + addr += i * guest_page_size; + addr &= ~(host_page_size - 1); + *(uint64_t *)addr = 0x0123456789ABCDEF; + } + + GUEST_SYNC(1); +} + +/* Points to the test VM memory region on which we are doing demand paging */ +static void *host_test_mem; +static uint64_t host_num_pages; + +static void *vcpu_worker(void *data) +{ + int ret; + struct kvm_vm *vm = data; + struct kvm_run *run; + + run = vcpu_state(vm, VCPU_ID); + + /* Let the guest access its memory */ + ret = _vcpu_run(vm, VCPU_ID); + TEST_ASSERT(ret == 0, "vcpu_run failed: %d\n", ret); + if (get_ucall(vm, VCPU_ID, NULL) != UCALL_SYNC) { + TEST_ASSERT(false, + "Invalid guest sync status: exit_reason=%s\n", + exit_reason_str(run->exit_reason)); + } + + return NULL; +} + +static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, + uint64_t extra_mem_pages, void *guest_code) +{ + struct kvm_vm *vm; + uint64_t extra_pg_pages = extra_mem_pages / 512 * 2; + + vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR); + kvm_vm_elf_load(vm, program_invocation_name, 0, 0); +#ifdef __x86_64__ + vm_create_irqchip(vm); +#endif + vm_vcpu_add_default(vm, vcpuid, guest_code); + return vm; +} + +#define GUEST_MEM_SHIFT 30 /* 1G */ +#define PAGE_SHIFT_4K 12 + +static void run_test(enum vm_guest_mode mode) +{ + pthread_t vcpu_thread; + struct kvm_vm *vm; + + /* + * We reserve page table for 2 times of extra dirty mem which + * will definitely cover the original (1G+) test range. Here + * we do the calculation with 4K page size which is the + * smallest so the page number will be enough for all archs + * (e.g., 64K page size guest will need even less memory for + * page tables). + */ + vm = create_vm(mode, VCPU_ID, + 2ul << (GUEST_MEM_SHIFT - PAGE_SHIFT_4K), + guest_code); + + guest_page_size = vm_get_page_size(vm); + /* + * A little more than 1G of guest page sized pages. Cover the + * case where the size is not aligned to 64 pages. + */ + guest_num_pages = (1ul << (GUEST_MEM_SHIFT - + vm_get_page_shift(vm))) + 16; +#ifdef __s390x__ + /* Round up to multiple of 1M (segment size) */ + guest_num_pages = (guest_num_pages + 0xff) & ~0xffUL; +#endif + + host_page_size = getpagesize(); + host_num_pages = (guest_num_pages * guest_page_size) / host_page_size + + !!((guest_num_pages * guest_page_size) % + host_page_size); + + guest_test_phys_mem = (vm_get_max_gfn(vm) - guest_num_pages) * + guest_page_size; + guest_test_phys_mem &= ~(host_page_size - 1); + +#ifdef __s390x__ + /* Align to 1M (segment size) */ + guest_test_phys_mem &= ~((1 << 20) - 1); +#endif + + DEBUG("guest physical test memory offset: 0x%lx\n", + guest_test_phys_mem); + + + /* Add an extra memory slot for testing demand paging */ + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, + guest_test_phys_mem, + TEST_MEM_SLOT_INDEX, + guest_num_pages, 0); + + /* Do mapping for the demand paging memory slot */ + virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, + guest_num_pages * guest_page_size, 0); + + /* Cache the HVA pointer of the region */ + host_test_mem = addr_gpa2hva(vm, (vm_paddr_t)guest_test_phys_mem); + +#ifdef __x86_64__ + vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); +#endif +#ifdef __aarch64__ + ucall_init(vm, NULL); +#endif + + /* Export the shared variables to the guest */ + sync_global_to_guest(vm, host_page_size); + sync_global_to_guest(vm, guest_page_size); + sync_global_to_guest(vm, guest_test_virt_mem); + sync_global_to_guest(vm, guest_num_pages); + + pthread_create(&vcpu_thread, NULL, vcpu_worker, vm); + + /* Wait for the vcpu thread to quit */ + pthread_join(vcpu_thread, NULL); + + ucall_uninit(vm); + kvm_vm_free(vm); +} + +struct vm_guest_mode_params { + bool supported; + bool enabled; +}; +struct vm_guest_mode_params vm_guest_mode_params[NUM_VM_MODES]; + +#define vm_guest_mode_params_init(mode, supported, enabled) \ +({ \ + vm_guest_mode_params[mode] = \ + (struct vm_guest_mode_params){ supported, enabled }; \ +}) + +static void help(char *name) +{ + int i; + + puts(""); + printf("usage: %s [-h] [-m mode]\n", name); + printf(" -m: specify the guest mode ID to test\n" + " (default: test all supported modes)\n" + " This option may be used multiple times.\n" + " Guest mode IDs:\n"); + for (i = 0; i < NUM_VM_MODES; ++i) { + printf(" %d: %s%s\n", i, vm_guest_mode_string(i), + vm_guest_mode_params[i].supported ? " (supported)" : ""); + } + puts(""); + exit(0); +} + +int main(int argc, char *argv[]) +{ + bool mode_selected = false; + unsigned int mode; + int opt, i; +#ifdef __aarch64__ + unsigned int host_ipa_limit; +#endif + +#ifdef __x86_64__ + vm_guest_mode_params_init(VM_MODE_PXXV48_4K, true, true); +#endif +#ifdef __aarch64__ + vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true); + vm_guest_mode_params_init(VM_MODE_P40V48_64K, true, true); + + host_ipa_limit = kvm_check_cap(KVM_CAP_ARM_VM_IPA_SIZE); + if (host_ipa_limit >= 52) + vm_guest_mode_params_init(VM_MODE_P52V48_64K, true, true); + if (host_ipa_limit >= 48) { + vm_guest_mode_params_init(VM_MODE_P48V48_4K, true, true); + vm_guest_mode_params_init(VM_MODE_P48V48_64K, true, true); + } +#endif +#ifdef __s390x__ + vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true); +#endif + + while ((opt = getopt(argc, argv, "hm:")) != -1) { + switch (opt) { + case 'm': + if (!mode_selected) { + for (i = 0; i < NUM_VM_MODES; ++i) + vm_guest_mode_params[i].enabled = false; + mode_selected = true; + } + mode = strtoul(optarg, NULL, 10); + TEST_ASSERT(mode < NUM_VM_MODES, + "Guest mode ID %d too big", mode); + vm_guest_mode_params[mode].enabled = true; + break; + case 'h': + default: + help(argv[0]); + break; + } + } + + for (i = 0; i < NUM_VM_MODES; ++i) { + if (!vm_guest_mode_params[i].enabled) + continue; + TEST_ASSERT(vm_guest_mode_params[i].supported, + "Guest mode ID %d (%s) not supported.", + i, vm_guest_mode_string(i)); + run_test(i); + } + + return 0; +} From patchwork Fri Sep 27 16:18:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164801 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF7851747 for ; Fri, 27 Sep 2019 16:18:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BE48521850 for ; Fri, 27 Sep 2019 16:18:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BoQSFogs" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728042AbfI0QSp (ORCPT ); Fri, 27 Sep 2019 12:18:45 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:36878 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728036AbfI0QSp (ORCPT ); Fri, 27 Sep 2019 12:18:45 -0400 Received: by mail-pg1-f201.google.com with SMTP id h189so3877084pgc.4 for ; Fri, 27 Sep 2019 09:18:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=KRRNMBZSZfudRxMD3ki/8HmxF4NewIGO5CQovFCGAFw=; b=BoQSFogswf4NHK3zeC4wzHD1xjedFY2kKmVET1Qe9/OpxdZyp3SQR2fSEuDfJuj6FE rMIVUJqLyPbEn2kaQZe9RVR7a1sW8vU8k+7pz4qHXe0s1jWs6QYXHl0Y+RteFHFJh9Vv kPYhXFqcqC8LbthxGWN1LGfYbUnYTp4rGbFs2+APTGmlRc/mam7daLtMlyhsg03QX7kh umlNCLdFEkNjtTwj/1L1XEXwyrB9Devnp+GVvcw1XAGjiv/aXt9JuKHhE/EmH5TprwQA rxTavAuIgt1yCPWj4gxX78XP8roXbzpq+/mkcXeRHj7Y0duhiHczqCNB1Kr3xTfPcldp CwGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=KRRNMBZSZfudRxMD3ki/8HmxF4NewIGO5CQovFCGAFw=; b=bQ7E5Ry4/eaIF3fPlDacDENapuuO2JQwZ5/KZfWP0C8dHWfPnHn+Aq8jI2Gfc57fdv XwfX/8BKSo8qo5pLUAc0WRCxqSuEiRlODuFWqrZ2iWmrbB1WB6PZxZgj4GEIFvA3MG1V 3RkvoqNzwOR2wXDzBX1hjbivVJOfhTgYZXZ9BLNgMvWD/ZrgknhP5mQ/rJSP8wYhNWbo raKXJ4ts0m17OU2yHftJ2UiEePT3JSOjODto3rLKU1t9UX2JX0M8OfnTB75Pgep/WiDt lWZmTB6+f7IgFnHxMUgB2rNSrTNueblvv/PqXfVDNKHP2TK8Z699Bj9IOZC/m9UV7j8x bNTg== X-Gm-Message-State: APjAAAUz88+5GDew7Z9g6jv7ZQgYqOr4RiVAvgb6v1tiGF6bMJrK69aT EEPYHFCwgxZnx6snCyxfuTmpMeNVanrl9cJgZrIJ6vfXFUly6go9FSSY+dSU8+LoZe+Er2juq/R ARaP4sfZghF79X4rXTy/S74n5kCcxrvMXeR6nMO5YKtV0/WtwhKRozVFeuzPF X-Google-Smtp-Source: APXvYqxKYn9C55/O+SOEWKGe2kH9Q2HGNjbYtu8yk2cDDGBnwvXYYPTteTUN3QOV4XUOY/xyHtWiQsn2htck X-Received: by 2002:a63:31c6:: with SMTP id x189mr10097980pgx.240.1569601124201; Fri, 27 Sep 2019 09:18:44 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:30 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-3-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 2/9] KVM: selftests: Add demand paging content to the demand paging test From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The demand paging test is currently a simple page access test which, while potentially useful, doesn't add much versus the existing dirty logging test. To improve the demand paging test, add a basic userfaultfd demand paging implementation. Signed-off-by: Ben Gardon --- .../selftests/kvm/demand_paging_test.c | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index 5f214517ba1de..61ba4e6a8214a 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -11,11 +11,14 @@ #include #include +#include #include #include +#include #include #include #include +#include #include "test_util.h" #include "kvm_util.h" @@ -29,6 +32,8 @@ /* Default guest test virtual memory offset */ #define DEFAULT_GUEST_TEST_MEM 0xc0000000 +#define __NR_userfaultfd 323 + /* * Guest/Host shared variables. Ensure addr_gva2hva() and/or * sync_global_to/from_guest() are used when accessing from @@ -39,6 +44,8 @@ static uint64_t host_page_size; static uint64_t guest_page_size; static uint64_t guest_num_pages; +static char *guest_data_prototype; + /* * Guest physical memory offset of the testing memory slot. * This will be set to the topmost valid physical address minus @@ -110,13 +117,153 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, return vm; } +static int handle_uffd_page_request(int uffd, uint64_t addr) +{ + pid_t tid; + struct uffdio_copy copy; + int r; + + tid = syscall(__NR_gettid); + + copy.src = (uint64_t)guest_data_prototype; + copy.dst = addr; + copy.len = host_page_size; + copy.mode = 0; + + r = ioctl(uffd, UFFDIO_COPY, ©); + if (r == -1) { + DEBUG("Failed Paged in 0x%lx from thread %d with errno: %d\n", + addr, tid, errno); + return r; + } + + return 0; +} + +bool quit_uffd_thread; + +struct uffd_handler_args { + int uffd; +}; + +static void *uffd_handler_thread_fn(void *arg) +{ + struct uffd_handler_args *uffd_args = (struct uffd_handler_args *)arg; + int uffd = uffd_args->uffd; + int64_t pages = 0; + + while (!quit_uffd_thread) { + struct uffd_msg msg; + struct pollfd pollfd[1]; + int r; + uint64_t addr; + + pollfd[0].fd = uffd; + pollfd[0].events = POLLIN; + + r = poll(pollfd, 1, 2000); + switch (r) { + case -1: + DEBUG("poll err"); + continue; + case 0: + continue; + case 1: + break; + default: + DEBUG("Polling uffd returned %d", r); + return NULL; + } + + if (pollfd[0].revents & POLLERR) { + DEBUG("uffd revents has POLLERR"); + return NULL; + } + + if (!pollfd[0].revents & POLLIN) + continue; + + r = read(uffd, &msg, sizeof(msg)); + if (r == -1) { + if (errno == EAGAIN) + continue; + DEBUG("Read of uffd gor errno %d", errno); + return NULL; + } + + if (r != sizeof(msg)) { + DEBUG("Read on uffd returned unexpected size: %d bytes", + r); + return NULL; + } + + if (!(msg.event & UFFD_EVENT_PAGEFAULT)) + continue; + + addr = msg.arg.pagefault.address; + r = handle_uffd_page_request(uffd, addr); + if (r < 0) + return NULL; + pages++; + } + + return NULL; +} + +static int setup_demand_paging(struct kvm_vm *vm, + pthread_t *uffd_handler_thread) +{ + int uffd; + struct uffdio_api uffdio_api; + struct uffdio_register uffdio_register; + struct uffd_handler_args uffd_args; + + guest_data_prototype = malloc(host_page_size); + memset(guest_data_prototype, 0xAB, host_page_size); + + uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); + if (uffd == -1) { + DEBUG("uffd creation failed\n"); + return -1; + } + + uffdio_api.api = UFFD_API; + uffdio_api.features = 0; + if (ioctl(uffd, UFFDIO_API, &uffdio_api) == -1) { + DEBUG("ioctl uffdio_api failed\n"); + return -1; + } + + uffdio_register.range.start = (uint64_t)host_test_mem; + uffdio_register.range.len = host_num_pages * host_page_size; + uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING; + if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register) == -1) { + DEBUG("ioctl uffdio_register failed\n"); + return -1; + } + + if ((uffdio_register.ioctls & UFFD_API_RANGE_IOCTLS) != + UFFD_API_RANGE_IOCTLS) { + DEBUG("unexpected userfaultfd ioctl set\n"); + return -1; + } + + uffd_args.uffd = uffd; + pthread_create(uffd_handler_thread, NULL, uffd_handler_thread_fn, + &uffd_args); + + return 0; +} + #define GUEST_MEM_SHIFT 30 /* 1G */ #define PAGE_SHIFT_4K 12 static void run_test(enum vm_guest_mode mode) { pthread_t vcpu_thread; + pthread_t uffd_handler_thread; struct kvm_vm *vm; + int r; /* * We reserve page table for 2 times of extra dirty mem which @@ -173,6 +320,12 @@ static void run_test(enum vm_guest_mode mode) /* Cache the HVA pointer of the region */ host_test_mem = addr_gpa2hva(vm, (vm_paddr_t)guest_test_phys_mem); + /* Set up user fault fd to handle demand paging requests. */ + quit_uffd_thread = false; + r = setup_demand_paging(vm, &uffd_handler_thread); + if (r < 0) + exit(-r); + #ifdef __x86_64__ vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); #endif @@ -191,6 +344,10 @@ static void run_test(enum vm_guest_mode mode) /* Wait for the vcpu thread to quit */ pthread_join(vcpu_thread, NULL); + /* Tell the user fault fd handler thread to quit */ + quit_uffd_thread = true; + pthread_join(uffd_handler_thread, NULL); + ucall_uninit(vm); kvm_vm_free(vm); } From patchwork Fri Sep 27 16:18:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164805 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 14C521747 for ; Fri, 27 Sep 2019 16:18:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DC1B8217D9 for ; Fri, 27 Sep 2019 16:18:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Zs3Zy66/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728045AbfI0QSr (ORCPT ); Fri, 27 Sep 2019 12:18:47 -0400 Received: from mail-pg1-f201.google.com ([209.85.215.201]:51830 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728064AbfI0QSr (ORCPT ); Fri, 27 Sep 2019 12:18:47 -0400 Received: by mail-pg1-f201.google.com with SMTP id o32so3855521pgm.18 for ; Fri, 27 Sep 2019 09:18:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=z1+6YnORORJpDPx0AFYn1dOo56cI4E/TWHsOcAHEr2k=; b=Zs3Zy66/fdR+77P3vb+NTQbTKVD1qPyOQpKRHebdpq9Z3GeBZThrfZC4N7Y+yF0Pox 3rajRELdEoIX5lt6E2eO1iS4GHPmvR/Q+vQUXy9gZxtanwxiVjpb+lIimnwvae14U/uU 0ridh0WqTAliLNwLv5RGqALKbzt3fwqz6/hA63lejNPuvDaWxGsjrBrtO3EYzMaDyWfj Qy6qt8DDgBkkjcCksWpIyF80AWUsuBeolM+8is+1buqmlA+N0ml+DgWk72VtvUM/4xJX bs+Cqg0rEX6fRuVKK0Ai/zbMgwpOLM6fg++CytIq1lz5g+AtKslt5UM/YBR0GHnTUAa5 HZCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=z1+6YnORORJpDPx0AFYn1dOo56cI4E/TWHsOcAHEr2k=; b=c7hrzRc1aCLdw94yQzQ+KRAFRwUoWoyL2nSPnTVPxVAxaMrs89u0SxkPVr/MO19VTe yCvBj3ddZc6EofgFFAbiQMS+RShRVHA45NFQVzdlUxi3i82OsVtD7WhSL+Y6sp531sWh 5huPX3G5iDItvKrg489/9mK3+HNtavz7G6kNby3FCFLoAPAqhJJXlvQkUd41jZbol/s6 e6efWjU4oJRZQCijfJbf/PtgxobsDT8k9plA4jRQNdpKe7OvFGZdKOc2ijwtaToWDJX5 ndcF893o30tIhYVNENRnUP1VPtb7LCMnqxwukMn3NaETkOxQBGB0O8y79xjY5eAXXR1V i3UQ== X-Gm-Message-State: APjAAAVkjIse+JvRFcuY4f/cZJGqaDzrgddJ5Zh3Fv9zoNVwm6sJizFs 1kCV6A7Y5FzdbGNSmVUP5mO/lO/DrOtajs/G20MowGuzjbOPFt6nsNm78q6Kp1mjEbI79UrszVQ GqqAMo/rFj/jgqRPAM7YPSRdu7Bn93J+oGx/YHu0f2A0Zn/fyoxVeiNx8WKPf X-Google-Smtp-Source: APXvYqyFAximtgaKY3v89h1XKCJQ7ZZYPYzW9ka3x3G3HMJM7o0TUI3U8IinsO+VCYmtgqFWAwQSvN9sUR7L X-Received: by 2002:a63:c645:: with SMTP id x5mr10199467pgg.425.1569601126534; Fri, 27 Sep 2019 09:18:46 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:31 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-4-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 3/9] KVM: selftests: Add memory size parameter to the demand paging test From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Add an argument to allow the demand paging test to work on larger and smaller guest sizes. Signed-off-by: Ben Gardon --- .../selftests/kvm/demand_paging_test.c | 55 ++++++++++++------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index 61ba4e6a8214a..19982a33a0ca2 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -32,6 +32,8 @@ /* Default guest test virtual memory offset */ #define DEFAULT_GUEST_TEST_MEM 0xc0000000 +#define DEFAULT_GUEST_TEST_MEM_SIZE (1 << 30) /* 1G */ + #define __NR_userfaultfd 323 /* @@ -255,10 +257,9 @@ static int setup_demand_paging(struct kvm_vm *vm, return 0; } -#define GUEST_MEM_SHIFT 30 /* 1G */ #define PAGE_SHIFT_4K 12 -static void run_test(enum vm_guest_mode mode) +static void run_test(enum vm_guest_mode mode, uint64_t guest_memory_bytes) { pthread_t vcpu_thread; pthread_t uffd_handler_thread; @@ -266,33 +267,40 @@ static void run_test(enum vm_guest_mode mode) int r; /* - * We reserve page table for 2 times of extra dirty mem which - * will definitely cover the original (1G+) test range. Here - * we do the calculation with 4K page size which is the - * smallest so the page number will be enough for all archs - * (e.g., 64K page size guest will need even less memory for - * page tables). + * We reserve page table for twice the ammount of memory we intend + * to use in the test region for demand paging. Here we do the + * calculation with 4K page size which is the smallest so the page + * number will be enough for all archs. (e.g., 64K page size guest + * will need even less memory for page tables). */ vm = create_vm(mode, VCPU_ID, - 2ul << (GUEST_MEM_SHIFT - PAGE_SHIFT_4K), + (2 * guest_memory_bytes) >> PAGE_SHIFT_4K, guest_code); guest_page_size = vm_get_page_size(vm); - /* - * A little more than 1G of guest page sized pages. Cover the - * case where the size is not aligned to 64 pages. - */ - guest_num_pages = (1ul << (GUEST_MEM_SHIFT - - vm_get_page_shift(vm))) + 16; + + TEST_ASSERT(guest_memory_bytes % guest_page_size == 0, + "Guest memory size is not guest page size aligned."); + + guest_num_pages = guest_memory_bytes / guest_page_size; + #ifdef __s390x__ /* Round up to multiple of 1M (segment size) */ guest_num_pages = (guest_num_pages + 0xff) & ~0xffUL; #endif + /* + * If there should be more memory in the guest test region than there + * can be pages in the guest, it will definitely cause problems. + */ + TEST_ASSERT(guest_num_pages < vm_get_max_gfn(vm), + "Requested more guest memory than address space allows.\n" + " guest pages: %lx max gfn: %lx\n", + guest_num_pages, vm_get_max_gfn(vm)); host_page_size = getpagesize(); - host_num_pages = (guest_num_pages * guest_page_size) / host_page_size + - !!((guest_num_pages * guest_page_size) % - host_page_size); + TEST_ASSERT(guest_memory_bytes % host_page_size == 0, + "Guest memory size is not host page size aligned."); + host_num_pages = guest_memory_bytes / host_page_size; guest_test_phys_mem = (vm_get_max_gfn(vm) - guest_num_pages) * guest_page_size; @@ -369,7 +377,7 @@ static void help(char *name) int i; puts(""); - printf("usage: %s [-h] [-m mode]\n", name); + printf("usage: %s [-h] [-m mode] [-b bytes test memory]\n", name); printf(" -m: specify the guest mode ID to test\n" " (default: test all supported modes)\n" " This option may be used multiple times.\n" @@ -378,6 +386,8 @@ static void help(char *name) printf(" %d: %s%s\n", i, vm_guest_mode_string(i), vm_guest_mode_params[i].supported ? " (supported)" : ""); } + printf(" -b: specify the number of bytes of memory which should be\n" + " allocated to the guest.\n"); puts(""); exit(0); } @@ -385,6 +395,7 @@ static void help(char *name) int main(int argc, char *argv[]) { bool mode_selected = false; + uint64_t guest_memory_bytes = DEFAULT_GUEST_TEST_MEM_SIZE; unsigned int mode; int opt, i; #ifdef __aarch64__ @@ -410,7 +421,7 @@ int main(int argc, char *argv[]) vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true); #endif - while ((opt = getopt(argc, argv, "hm:")) != -1) { + while ((opt = getopt(argc, argv, "hm:b:")) != -1) { switch (opt) { case 'm': if (!mode_selected) { @@ -423,6 +434,8 @@ int main(int argc, char *argv[]) "Guest mode ID %d too big", mode); vm_guest_mode_params[mode].enabled = true; break; + case 'b': + guest_memory_bytes = strtoull(optarg, NULL, 0); case 'h': default: help(argv[0]); @@ -436,7 +449,7 @@ int main(int argc, char *argv[]) TEST_ASSERT(vm_guest_mode_params[i].supported, "Guest mode ID %d (%s) not supported.", i, vm_guest_mode_string(i)); - run_test(i); + run_test(i, guest_memory_bytes); } return 0; From patchwork Fri Sep 27 16:18:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164809 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3ED571747 for ; Fri, 27 Sep 2019 16:18:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1C7FD21841 for ; Fri, 27 Sep 2019 16:18:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wC4kHt5p" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728057AbfI0QSu (ORCPT ); Fri, 27 Sep 2019 12:18:50 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:45012 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728076AbfI0QSt (ORCPT ); Fri, 27 Sep 2019 12:18:49 -0400 Received: by mail-pf1-f201.google.com with SMTP id b204so2229693pfb.11 for ; Fri, 27 Sep 2019 09:18:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=IlvPPwGnMWD1NTIiC8jnPE4YM8+nW7ykOi0JgL0Q+GQ=; b=wC4kHt5p9cIRSDgrTzzM9HAVj1PwdCZMdzNGWJmdJ7INFpMh8yjJkuHNR9idmSUYMV jpuQyXHtZMCvqJa/pNatma/+SG5BcDFIzBowHoCvUFjsMsx9pknBBbBZhYPQF3V7qB/q sh2ISmela0hcmFM0CafxdAldCHJY97pVx634/8jm4u8+MDcS/jweaKJl2Ylx6FwFTPM0 Fg47eTm1N1A4hFF88rg+J56HSP9PwFn7gst3u4Z8bedKJbnp5E07JZTH9N+gDN8Y7txG FRUeuRMcXBED6pDhFMheQeWWo8SddmNJYldmvTEOQl2Iru9jw1Ih57R717YP0ExsV48o 6MoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=IlvPPwGnMWD1NTIiC8jnPE4YM8+nW7ykOi0JgL0Q+GQ=; b=CEHas7h+lLtaH/EIkwDSKmVxJWcvw1btrBshbETLPY1OAtAKsbObKqHU8D6XoL0cua qtJjEoL9uzb9F1JY08yPmc7abZhdBhBtZ06JHoQK8A03QIkaRjcLbbpdnWAem5cPEVYx eM8kk8XSFOsfhRqRylBaHt+aV+RMm7zLorkxGCzluJOj/IH7NL9AocRKk38bE8RU0gzT ok7gwWx9D6v7/lHCFdd2aMI7yAwPTNDkxw8j6n2Qu6pzliSMWvGGs8iA94aCF43UpTf1 IW7LR7H3j/8PJao0FIkoVS8Zp2WbITMwVXnz+jz+J1xAP2CQ2GaGW0W9vp+hdFSsgahp TwHQ== X-Gm-Message-State: APjAAAXGXtzWqpu7K5sPyfG37bqvYuRlRsMeGn8+31KfilhSIQlWA65+ eaOgTvkg8AXUnTAnHUXmCHPAa5/iIoCh9n5wopYpynWr7JGXfBQ81A6UiV1WMwEQriqYeRdtCfo YOLOjvwE3G2OAOS4vNATOcM2qJ8nh2j89nUjlvsVeF6cetAgAhN1hISVaJkUf X-Google-Smtp-Source: APXvYqwCKt4vsu5/A+gyozazO8stNHyGzzddSTGHVfrUWy9VaTguzUhV/cd2QSe0wCXp9obT++vRs4KU0UCx X-Received: by 2002:a63:ff4a:: with SMTP id s10mr10045451pgk.166.1569601128664; Fri, 27 Sep 2019 09:18:48 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:32 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-5-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 4/9] KVM: selftests: Pass args to vCPU instead of using globals From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org In preparation for supporting multiple vCPUs in the demand paging test, pass arguments to the vCPU instead of syncing globals to it. Signed-off-by: Ben Gardon --- .../selftests/kvm/demand_paging_test.c | 61 +++++++++++-------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index 19982a33a0ca2..8fd46e99d9e30 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -44,7 +44,6 @@ */ static uint64_t host_page_size; static uint64_t guest_page_size; -static uint64_t guest_num_pages; static char *guest_data_prototype; @@ -65,14 +64,13 @@ static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM; * Continuously write to the first 8 bytes of each page in the demand paging * memory region. */ -static void guest_code(void) +static void guest_code(uint64_t gva, uint64_t pages) { int i; - for (i = 0; i < guest_num_pages; i++) { - uint64_t addr = guest_test_virt_mem; + for (i = 0; i < pages; i++) { + uint64_t addr = gva + (i * guest_page_size); - addr += i * guest_page_size; addr &= ~(host_page_size - 1); *(uint64_t *)addr = 0x0123456789ABCDEF; } @@ -84,18 +82,31 @@ static void guest_code(void) static void *host_test_mem; static uint64_t host_num_pages; +struct vcpu_thread_args { + uint64_t gva; + uint64_t pages; + struct kvm_vm *vm; + int vcpu_id; +}; + static void *vcpu_worker(void *data) { int ret; - struct kvm_vm *vm = data; + struct vcpu_thread_args *args = (struct vcpu_thread_args *)data; + struct kvm_vm *vm = args->vm; + int vcpu_id = args->vcpu_id; + uint64_t gva = args->gva; + uint64_t pages = args->pages; struct kvm_run *run; - run = vcpu_state(vm, VCPU_ID); + vcpu_args_set(vm, vcpu_id, 2, gva, pages); + + run = vcpu_state(vm, vcpu_id); /* Let the guest access its memory */ - ret = _vcpu_run(vm, VCPU_ID); + ret = _vcpu_run(vm, vcpu_id); TEST_ASSERT(ret == 0, "vcpu_run failed: %d\n", ret); - if (get_ucall(vm, VCPU_ID, NULL) != UCALL_SYNC) { + if (get_ucall(vm, vcpu_id, NULL) != UCALL_SYNC) { TEST_ASSERT(false, "Invalid guest sync status: exit_reason=%s\n", exit_reason_str(run->exit_reason)); @@ -259,11 +270,13 @@ static int setup_demand_paging(struct kvm_vm *vm, #define PAGE_SHIFT_4K 12 -static void run_test(enum vm_guest_mode mode, uint64_t guest_memory_bytes) +static void run_test(enum vm_guest_mode mode, uint64_t vcpu_wss) { pthread_t vcpu_thread; pthread_t uffd_handler_thread; struct kvm_vm *vm; + struct vcpu_thread_args vcpu_args; + uint64_t guest_num_pages; int r; /* @@ -273,16 +286,15 @@ static void run_test(enum vm_guest_mode mode, uint64_t guest_memory_bytes) * number will be enough for all archs. (e.g., 64K page size guest * will need even less memory for page tables). */ - vm = create_vm(mode, VCPU_ID, - (2 * guest_memory_bytes) >> PAGE_SHIFT_4K, + vm = create_vm(mode, VCPU_ID, (2 * vcpu_wss) >> PAGE_SHIFT_4K, guest_code); guest_page_size = vm_get_page_size(vm); - TEST_ASSERT(guest_memory_bytes % guest_page_size == 0, + TEST_ASSERT(vcpu_wss % guest_page_size == 0, "Guest memory size is not guest page size aligned."); - guest_num_pages = guest_memory_bytes / guest_page_size; + guest_num_pages = vcpu_wss / guest_page_size; #ifdef __s390x__ /* Round up to multiple of 1M (segment size) */ @@ -298,9 +310,9 @@ static void run_test(enum vm_guest_mode mode, uint64_t guest_memory_bytes) guest_num_pages, vm_get_max_gfn(vm)); host_page_size = getpagesize(); - TEST_ASSERT(guest_memory_bytes % host_page_size == 0, + TEST_ASSERT(vcpu_wss % host_page_size == 0, "Guest memory size is not host page size aligned."); - host_num_pages = guest_memory_bytes / host_page_size; + host_num_pages = vcpu_wss / host_page_size; guest_test_phys_mem = (vm_get_max_gfn(vm) - guest_num_pages) * guest_page_size; @@ -344,10 +356,12 @@ static void run_test(enum vm_guest_mode mode, uint64_t guest_memory_bytes) /* Export the shared variables to the guest */ sync_global_to_guest(vm, host_page_size); sync_global_to_guest(vm, guest_page_size); - sync_global_to_guest(vm, guest_test_virt_mem); - sync_global_to_guest(vm, guest_num_pages); - pthread_create(&vcpu_thread, NULL, vcpu_worker, vm); + vcpu_args.vm = vm; + vcpu_args.vcpu_id = VCPU_ID; + vcpu_args.gva = guest_test_virt_mem; + vcpu_args.pages = guest_num_pages; + pthread_create(&vcpu_thread, NULL, vcpu_worker, &vcpu_args); /* Wait for the vcpu thread to quit */ pthread_join(vcpu_thread, NULL); @@ -386,8 +400,7 @@ static void help(char *name) printf(" %d: %s%s\n", i, vm_guest_mode_string(i), vm_guest_mode_params[i].supported ? " (supported)" : ""); } - printf(" -b: specify the number of bytes of memory which should be\n" - " allocated to the guest.\n"); + printf(" -b: specify the working set size, in bytes for each vCPU.\n"); puts(""); exit(0); } @@ -395,7 +408,7 @@ static void help(char *name) int main(int argc, char *argv[]) { bool mode_selected = false; - uint64_t guest_memory_bytes = DEFAULT_GUEST_TEST_MEM_SIZE; + uint64_t vcpu_wss = DEFAULT_GUEST_TEST_MEM_SIZE; unsigned int mode; int opt, i; #ifdef __aarch64__ @@ -435,7 +448,7 @@ int main(int argc, char *argv[]) vm_guest_mode_params[mode].enabled = true; break; case 'b': - guest_memory_bytes = strtoull(optarg, NULL, 0); + vcpu_wss = strtoull(optarg, NULL, 0); case 'h': default: help(argv[0]); @@ -449,7 +462,7 @@ int main(int argc, char *argv[]) TEST_ASSERT(vm_guest_mode_params[i].supported, "Guest mode ID %d (%s) not supported.", i, vm_guest_mode_string(i)); - run_test(i, guest_memory_bytes); + run_test(i, vcpu_wss); } return 0; From patchwork Fri Sep 27 16:18:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164813 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E2C981747 for ; Fri, 27 Sep 2019 16:18:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B618021841 for ; Fri, 27 Sep 2019 16:18:54 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TUPfvv8M" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728089AbfI0QSx (ORCPT ); Fri, 27 Sep 2019 12:18:53 -0400 Received: from mail-pl1-f202.google.com ([209.85.214.202]:46428 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728059AbfI0QSx (ORCPT ); Fri, 27 Sep 2019 12:18:53 -0400 Received: by mail-pl1-f202.google.com with SMTP id k9so1921461pls.13 for ; Fri, 27 Sep 2019 09:18:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=RDEOME0HkMVm35YDBbnA3ZZmp2Mp6TR34BdZt6nPsk4=; b=TUPfvv8M26lefvWoohvQ46VGO9C62xGBla/ulIDB4nAA4wiffJPHqVybp6S30NQL/j 3zbdNfvKZu8LOC4sae++zbKDLRSgeEjSpAShgC8/cLRyiE3HaButKBVTiGPfnCY615I8 zxVwEV5vXdO0VumgZIGN35ubG4RfArVtFUZQW6SckKEUqrASzSehxpOJYefVWX074Abl jcbBbagtlCO39Q4qSN/9lwDXO8WQWUpejYgPyhW5cd7N0J4552cGh9qPRLejHj0LihBC ZPNbf1sBiS5skAy3kYbUolrzHYDOx5bPImQ3TECfGc4kqVwsASYd7tpw9KLEWR686L4c oENA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=RDEOME0HkMVm35YDBbnA3ZZmp2Mp6TR34BdZt6nPsk4=; b=LTeTsgmhHyWFOf4KpKTUkGtxL70n16Nzfgpm4E8xnrreqJV3syyttI42Sgcw8rLb5v EUIpA4/kOHFtH4IVGmTmQnjpdjgEcLvaI6Ukwb41qbf//GOv25UxRN3ljSLPpldy9CYz Y8dLZqZFdLyfozJr6BvP3MjkhAANrBMq1Gy5UZUN+GHIhtXvVYqU01BllKwX6UiG86Te KCfraGAyTKsQmVvIgjxiKm4VvkRHWHa87OWDYobp4glZCSG7gJh7B+CvvEbjnKxeQTHx Y5PwJoK2JfAbbj1S0LzTg2FJKiPWdJsQFOWuZONMHszUKp8kOCaLUdN5jzt69em/jSqN ds3Q== X-Gm-Message-State: APjAAAVRDYwufoV1dn/3KchqFRRAM1Y4HVj+2r+KP8OmkXC9afhWqvIB DHerdEDND33lakiixHocCZ4UaakCkfvok6FU8PSgbJY61HEqRbrLuV78suWMnSgGx5TQpMzZj6v 3qBsZov6H3AVM8KHZLS6x0tvzn7yrelIaJ+mbrHnXWunBFCvH+97pP9bQvdEr X-Google-Smtp-Source: APXvYqw077VeGUvXFBlvVApV0JyCYU7V/zcPeQREB2zceyG5bru5IWPzuvdXIkOE4/9OLMLqwqgDX2eYwi4+ X-Received: by 2002:a63:1d02:: with SMTP id d2mr10186367pgd.190.1569601130783; Fri, 27 Sep 2019 09:18:50 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:33 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-6-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 5/9] KVM: selftests: Support multiple vCPUs in demand paging test From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Most VMs have multiple vCPUs, the concurrent execution of which has a substantial impact on demand paging performance. Add an option to create multiple vCPUs to each access disjoint regions of memory. Signed-off-by: Ben Gardon --- .../selftests/kvm/demand_paging_test.c | 187 ++++++++++++------ 1 file changed, 127 insertions(+), 60 deletions(-) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index 8fd46e99d9e30..f8afc0683c346 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -24,8 +24,6 @@ #include "kvm_util.h" #include "processor.h" -#define VCPU_ID 1 - /* The memory slot index demand page */ #define TEST_MEM_SLOT_INDEX 1 @@ -36,6 +34,12 @@ #define __NR_userfaultfd 323 +#ifdef PRINT_PER_VCPU_UPDATES +#define PER_VCPU_DEBUG(...) DEBUG(__VA_ARGS__) +#else +#define PER_VCPU_DEBUG(...) +#endif + /* * Guest/Host shared variables. Ensure addr_gva2hva() and/or * sync_global_to/from_guest() are used when accessing from @@ -78,10 +82,6 @@ static void guest_code(uint64_t gva, uint64_t pages) GUEST_SYNC(1); } -/* Points to the test VM memory region on which we are doing demand paging */ -static void *host_test_mem; -static uint64_t host_num_pages; - struct vcpu_thread_args { uint64_t gva; uint64_t pages; @@ -115,18 +115,32 @@ static void *vcpu_worker(void *data) return NULL; } -static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, - uint64_t extra_mem_pages, void *guest_code) +#define PAGE_SHIFT_4K 12 +#define PTES_PER_PT 512 + +static struct kvm_vm *create_vm(enum vm_guest_mode mode, int vcpus, + uint64_t vcpu_wss) { struct kvm_vm *vm; - uint64_t extra_pg_pages = extra_mem_pages / 512 * 2; + uint64_t pages = DEFAULT_GUEST_PHY_PAGES; - vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR); + /* Account for a few pages per-vCPU for stacks */ + pages += DEFAULT_STACK_PGS * vcpus; + + /* + * Reserve twice the ammount of memory needed to map the test region and + * the page table / stacks region, at 4k, for page tables. Do the + * calculation with 4K page size: the smallest of all archs. (e.g., 64K + * page size guest will need even less memory for page tables). + */ + pages += (2 * pages) / PTES_PER_PT; + pages += ((2 * vcpus * vcpu_wss) >> PAGE_SHIFT_4K) / PTES_PER_PT; + + vm = _vm_create(mode, pages, O_RDWR); kvm_vm_elf_load(vm, program_invocation_name, 0, 0); #ifdef __x86_64__ vm_create_irqchip(vm); #endif - vm_vcpu_add_default(vm, vcpuid, guest_code); return vm; } @@ -224,15 +238,13 @@ static void *uffd_handler_thread_fn(void *arg) } static int setup_demand_paging(struct kvm_vm *vm, - pthread_t *uffd_handler_thread) + pthread_t *uffd_handler_thread, + struct uffd_handler_args *uffd_args, + void *hva, uint64_t len) { int uffd; struct uffdio_api uffdio_api; struct uffdio_register uffdio_register; - struct uffd_handler_args uffd_args; - - guest_data_prototype = malloc(host_page_size); - memset(guest_data_prototype, 0xAB, host_page_size); uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); if (uffd == -1) { @@ -247,8 +259,8 @@ static int setup_demand_paging(struct kvm_vm *vm, return -1; } - uffdio_register.range.start = (uint64_t)host_test_mem; - uffdio_register.range.len = host_num_pages * host_page_size; + uffdio_register.range.start = (uint64_t)hva; + uffdio_register.range.len = len; uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING; if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register) == -1) { DEBUG("ioctl uffdio_register failed\n"); @@ -261,40 +273,35 @@ static int setup_demand_paging(struct kvm_vm *vm, return -1; } - uffd_args.uffd = uffd; + uffd_args->uffd = uffd; pthread_create(uffd_handler_thread, NULL, uffd_handler_thread_fn, - &uffd_args); + uffd_args); + + PER_VCPU_DEBUG("Created uffd thread for HVA range [%p, %p)\n", + hva, hva + len); return 0; } -#define PAGE_SHIFT_4K 12 - -static void run_test(enum vm_guest_mode mode, uint64_t vcpu_wss) +static void run_test(enum vm_guest_mode mode, int vcpus, uint64_t vcpu_wss) { - pthread_t vcpu_thread; - pthread_t uffd_handler_thread; + pthread_t *vcpu_threads; + pthread_t *uffd_handler_threads; + struct uffd_handler_args *uffd_args; struct kvm_vm *vm; - struct vcpu_thread_args vcpu_args; + struct vcpu_thread_args *vcpu_args; uint64_t guest_num_pages; + int vcpu_id; int r; - /* - * We reserve page table for twice the ammount of memory we intend - * to use in the test region for demand paging. Here we do the - * calculation with 4K page size which is the smallest so the page - * number will be enough for all archs. (e.g., 64K page size guest - * will need even less memory for page tables). - */ - vm = create_vm(mode, VCPU_ID, (2 * vcpu_wss) >> PAGE_SHIFT_4K, - guest_code); + vm = create_vm(mode, vcpus, vcpu_wss); guest_page_size = vm_get_page_size(vm); TEST_ASSERT(vcpu_wss % guest_page_size == 0, "Guest memory size is not guest page size aligned."); - guest_num_pages = vcpu_wss / guest_page_size; + guest_num_pages = (vcpus * vcpu_wss) / guest_page_size; #ifdef __s390x__ /* Round up to multiple of 1M (segment size) */ @@ -306,13 +313,12 @@ static void run_test(enum vm_guest_mode mode, uint64_t vcpu_wss) */ TEST_ASSERT(guest_num_pages < vm_get_max_gfn(vm), "Requested more guest memory than address space allows.\n" - " guest pages: %lx max gfn: %lx\n", - guest_num_pages, vm_get_max_gfn(vm)); + " guest pages: %lx max gfn: %lx vcpus: %d wss: %lx]\n", + guest_num_pages, vm_get_max_gfn(vm), vcpus, vcpu_wss); host_page_size = getpagesize(); TEST_ASSERT(vcpu_wss % host_page_size == 0, "Guest memory size is not host page size aligned."); - host_num_pages = vcpu_wss / host_page_size; guest_test_phys_mem = (vm_get_max_gfn(vm) - guest_num_pages) * guest_page_size; @@ -337,18 +343,8 @@ static void run_test(enum vm_guest_mode mode, uint64_t vcpu_wss) virt_map(vm, guest_test_virt_mem, guest_test_phys_mem, guest_num_pages * guest_page_size, 0); - /* Cache the HVA pointer of the region */ - host_test_mem = addr_gpa2hva(vm, (vm_paddr_t)guest_test_phys_mem); - - /* Set up user fault fd to handle demand paging requests. */ quit_uffd_thread = false; - r = setup_demand_paging(vm, &uffd_handler_thread); - if (r < 0) - exit(-r); -#ifdef __x86_64__ - vcpu_set_cpuid(vm, VCPU_ID, kvm_get_supported_cpuid()); -#endif #ifdef __aarch64__ ucall_init(vm, NULL); #endif @@ -357,21 +353,83 @@ static void run_test(enum vm_guest_mode mode, uint64_t vcpu_wss) sync_global_to_guest(vm, host_page_size); sync_global_to_guest(vm, guest_page_size); - vcpu_args.vm = vm; - vcpu_args.vcpu_id = VCPU_ID; - vcpu_args.gva = guest_test_virt_mem; - vcpu_args.pages = guest_num_pages; - pthread_create(&vcpu_thread, NULL, vcpu_worker, &vcpu_args); + guest_data_prototype = malloc(host_page_size); + TEST_ASSERT(guest_data_prototype, "Memory allocation failed"); + memset(guest_data_prototype, 0xAB, host_page_size); + + vcpu_threads = malloc(vcpus * sizeof(*vcpu_threads)); + TEST_ASSERT(vcpu_threads, "Memory allocation failed"); + + uffd_handler_threads = malloc(vcpus * sizeof(*uffd_handler_threads)); + TEST_ASSERT(uffd_handler_threads, "Memory allocation failed"); + + uffd_args = malloc(vcpus * sizeof(*uffd_args)); + TEST_ASSERT(uffd_args, "Memory allocation failed"); + + vcpu_args = malloc(vcpus * sizeof(*vcpu_args)); + TEST_ASSERT(vcpu_args, "Memory allocation failed"); + + for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) { + vm_paddr_t vcpu_gpa; + void *vcpu_hva; + + vm_vcpu_add_default(vm, vcpu_id, guest_code); + + vcpu_gpa = guest_test_phys_mem + (vcpu_id * vcpu_wss); + PER_VCPU_DEBUG("Added VCPU %d with test mem gpa [%lx, %lx)\n", + vcpu_id, vcpu_gpa, vcpu_gpa + vcpu_wss); + + /* Cache the HVA pointer of the region */ + vcpu_hva = addr_gpa2hva(vm, vcpu_gpa); + + /* Set up user fault fd to handle demand paging requests. */ + r = setup_demand_paging(vm, &uffd_handler_threads[vcpu_id], + &uffd_args[vcpu_id], vcpu_hva, + vcpu_wss); + if (r < 0) + exit(-r); + +#ifdef __x86_64__ + vcpu_set_cpuid(vm, vcpu_id, kvm_get_supported_cpuid()); +#endif + + vcpu_args[vcpu_id].vm = vm; + vcpu_args[vcpu_id].vcpu_id = vcpu_id; + vcpu_args[vcpu_id].gva = guest_test_virt_mem + + (vcpu_id * vcpu_wss); + vcpu_args[vcpu_id].pages = vcpu_wss / guest_page_size; + } + + DEBUG("Finished creating vCPUs and starting uffd threads\n"); + + for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) { + pthread_create(&vcpu_threads[vcpu_id], NULL, vcpu_worker, + &vcpu_args[vcpu_id]); + } + + DEBUG("Started all vCPUs\n"); + + /* Wait for the vcpu threads to quit */ + for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) { + pthread_join(vcpu_threads[vcpu_id], NULL); + PER_VCPU_DEBUG("Joined thread for vCPU %d\n", vcpu_id); + } - /* Wait for the vcpu thread to quit */ - pthread_join(vcpu_thread, NULL); + DEBUG("All vCPU threads joined\n"); /* Tell the user fault fd handler thread to quit */ quit_uffd_thread = true; - pthread_join(uffd_handler_thread, NULL); + for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) + pthread_join(uffd_handler_threads[vcpu_id], NULL); ucall_uninit(vm); kvm_vm_free(vm); + + free(guest_data_prototype); + free(vcpu_threads); + free(uffd_handler_threads); + free(uffd_args); + free(vcpu_args); } struct vm_guest_mode_params { @@ -391,7 +449,8 @@ static void help(char *name) int i; puts(""); - printf("usage: %s [-h] [-m mode] [-b bytes test memory]\n", name); + printf("usage: %s [-h] [-m mode] [-b bytes test memory] [-v vcpus]\n", + name); printf(" -m: specify the guest mode ID to test\n" " (default: test all supported modes)\n" " This option may be used multiple times.\n" @@ -401,6 +460,7 @@ static void help(char *name) vm_guest_mode_params[i].supported ? " (supported)" : ""); } printf(" -b: specify the working set size, in bytes for each vCPU.\n"); + printf(" -v: specify the number of vCPUs to run.\n"); puts(""); exit(0); } @@ -409,6 +469,7 @@ int main(int argc, char *argv[]) { bool mode_selected = false; uint64_t vcpu_wss = DEFAULT_GUEST_TEST_MEM_SIZE; + int vcpus = 1; unsigned int mode; int opt, i; #ifdef __aarch64__ @@ -434,7 +495,7 @@ int main(int argc, char *argv[]) vm_guest_mode_params_init(VM_MODE_P40V48_4K, true, true); #endif - while ((opt = getopt(argc, argv, "hm:b:")) != -1) { + while ((opt = getopt(argc, argv, "hm:b:v:")) != -1) { switch (opt) { case 'm': if (!mode_selected) { @@ -449,6 +510,12 @@ int main(int argc, char *argv[]) break; case 'b': vcpu_wss = strtoull(optarg, NULL, 0); + break; + case 'v': + vcpus = atoi(optarg); + TEST_ASSERT(vcpus > 0, + "Must have a positive number of vCPUs"); + break; case 'h': default: help(argv[0]); @@ -462,7 +529,7 @@ int main(int argc, char *argv[]) TEST_ASSERT(vm_guest_mode_params[i].supported, "Guest mode ID %d (%s) not supported.", i, vm_guest_mode_string(i)); - run_test(i, vcpu_wss); + run_test(i, vcpus, vcpu_wss); } return 0; From patchwork Fri Sep 27 16:18:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164817 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD1991747 for ; Fri, 27 Sep 2019 16:18:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BB99621850 for ; Fri, 27 Sep 2019 16:18:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ChscLEp6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728063AbfI0QS4 (ORCPT ); Fri, 27 Sep 2019 12:18:56 -0400 Received: from mail-pl1-f202.google.com ([209.85.214.202]:34375 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728076AbfI0QSz (ORCPT ); Fri, 27 Sep 2019 12:18:55 -0400 Received: by mail-pl1-f202.google.com with SMTP id 70so1931624ple.1 for ; Fri, 27 Sep 2019 09:18:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=C/rLQ2oLxQZ983DbhcEAy72g3EkcETZ71g/BHgzPdAU=; b=ChscLEp6Cu0mCQ2/3RDNDu6iH98Sw0MtOVYiFyVU4EJx+qZ9PpyXUq6XBSWfHuu9e4 Ad0cjMFGKM1faTZpcM5azpZIHA9Ss04p//bfGegrKJ+Rvg1bL7unYnuvFT0l68x0oRZD O4zNHl0B/boPaKQpawVm88YGaZ1hQLAJBsK0TLCjEPIk/nHOnAgG8B154EGt/Evyu/rB wHYcQOcPfRZV8pYBrty83vrnm4y4XgKn2ICHBs7i+XyxxkAKPdxMGWNasVaogJ9STIz+ UtnY2qAewarn6dYBY/wtY8wT8dkVRu/9xFZxDRB/MpSPHVQxmmBj0XGlefHbtHQ5rmIV Oy5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=C/rLQ2oLxQZ983DbhcEAy72g3EkcETZ71g/BHgzPdAU=; b=eZdvaIv4GzS2iTlfZpkAk4IAnJRizp2/gTLm5r1GXcA4RE9yRzYSdbLTxZ1VhoPKUl 6bhRB0H0jS6Hug1Z756BhIj4WNi8LdUV1Ea7Tg4dC6vyHRjtlrCtcMt08v4PmoZT8Pou ywrhvVo202E9LDA0PDkAvZLUOVyKIDKcgfOuugcKVQBZjw0xGux7ErytqURCrUEGFqvu eYgCyoilJ7cUkK0/+AIcNK/85Oc/s+0veHcz7u+QTBwL3NXlYrcgvLoa2jdrcQ67vw2H ELVbngYMjIkDXmmOXu9wsZzvlnbH7i2BcrhpCxBbEFZbYJiioO8cztneSSEuoKOjnVVR C8GA== X-Gm-Message-State: APjAAAUVTxJRGe4PHV1GNtHwrSfTM8rFlqHegWNm3MrW3KSP7FkZ2Hkd zyZ6I5T3SS5rk3vN7KPv3TWWTk6dBB3N8lVOPY9tDFyADGvg2/Vl3mr5R6jv0v/WSGdqo2Yk1yM 6oH10E/hXgk3alAbwh9n5wfNN1hgAlZM/hS0RcKBnyNVhFb2oHrNvqdNBfTPa X-Google-Smtp-Source: APXvYqymTqH8N/cLnvS3L6AraOtT0i46rIrImcA3aoerq63TlsU+tzJKMz8xFImPcxs4ac1jk6EguCqqUkhz X-Received: by 2002:a63:dd05:: with SMTP id t5mr9961353pgg.16.1569601132992; Fri, 27 Sep 2019 09:18:52 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:34 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-7-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 6/9] KVM: selftests: Time guest demand paging From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org In order to quantify demand paging performance, time guest execution during demand paging. Signed-off-by: Ben Gardon --- .../selftests/kvm/demand_paging_test.c | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index f8afc0683c346..fe6c5a4f8b8c2 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -34,6 +34,12 @@ #define __NR_userfaultfd 323 +#ifdef PRINT_PER_PAGE_UPDATES +#define PER_PAGE_DEBUG(...) DEBUG(__VA_ARGS__) +#else +#define PER_PAGE_DEBUG(...) +#endif + #ifdef PRINT_PER_VCPU_UPDATES #define PER_VCPU_DEBUG(...) DEBUG(__VA_ARGS__) #else @@ -64,6 +70,26 @@ static uint64_t guest_test_phys_mem; */ static uint64_t guest_test_virt_mem = DEFAULT_GUEST_TEST_MEM; +int64_t to_ns(struct timespec ts) +{ + return (int64_t)ts.tv_nsec + 1000000000LL * (int64_t)ts.tv_sec; +} + +struct timespec diff(struct timespec start, struct timespec end) +{ + struct timespec temp; + + if ((end.tv_nsec-start.tv_nsec) < 0) { + temp.tv_sec = end.tv_sec - start.tv_sec - 1; + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + + return temp; +} + /* * Continuously write to the first 8 bytes of each page in the demand paging * memory region. @@ -98,11 +124,15 @@ static void *vcpu_worker(void *data) uint64_t gva = args->gva; uint64_t pages = args->pages; struct kvm_run *run; + struct timespec start; + struct timespec end; vcpu_args_set(vm, vcpu_id, 2, gva, pages); run = vcpu_state(vm, vcpu_id); + clock_gettime(CLOCK_MONOTONIC, &start); + /* Let the guest access its memory */ ret = _vcpu_run(vm, vcpu_id); TEST_ASSERT(ret == 0, "vcpu_run failed: %d\n", ret); @@ -112,6 +142,11 @@ static void *vcpu_worker(void *data) exit_reason_str(run->exit_reason)); } + clock_gettime(CLOCK_MONOTONIC, &end); + PER_VCPU_DEBUG("vCPU %d execution time: %lld.%.9lds\n", vcpu_id, + (long long)(diff(start, end).tv_sec), + diff(start, end).tv_nsec); + return NULL; } @@ -147,6 +182,8 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, int vcpus, static int handle_uffd_page_request(int uffd, uint64_t addr) { pid_t tid; + struct timespec start; + struct timespec end; struct uffdio_copy copy; int r; @@ -157,6 +194,8 @@ static int handle_uffd_page_request(int uffd, uint64_t addr) copy.len = host_page_size; copy.mode = 0; + clock_gettime(CLOCK_MONOTONIC, &start); + r = ioctl(uffd, UFFDIO_COPY, ©); if (r == -1) { DEBUG("Failed Paged in 0x%lx from thread %d with errno: %d\n", @@ -164,6 +203,13 @@ static int handle_uffd_page_request(int uffd, uint64_t addr) return r; } + clock_gettime(CLOCK_MONOTONIC, &end); + + PER_PAGE_DEBUG("UFFDIO_COPY %d \t%lld ns\n", tid, + (long long)to_ns(diff(start, end))); + PER_PAGE_DEBUG("Paged in %ld bytes at 0x%lx from thread %d\n", + host_page_size, addr, tid); + return 0; } @@ -178,7 +224,10 @@ static void *uffd_handler_thread_fn(void *arg) struct uffd_handler_args *uffd_args = (struct uffd_handler_args *)arg; int uffd = uffd_args->uffd; int64_t pages = 0; + struct timespec start; + struct timespec end; + clock_gettime(CLOCK_MONOTONIC, &start); while (!quit_uffd_thread) { struct uffd_msg msg; struct pollfd pollfd[1]; @@ -234,6 +283,13 @@ static void *uffd_handler_thread_fn(void *arg) pages++; } + clock_gettime(CLOCK_MONOTONIC, &end); + PER_VCPU_DEBUG("userfaulted %ld pages over %lld.%.9lds. (%f/sec)\n", + pages, (long long)(diff(start, end).tv_sec), + diff(start, end).tv_nsec, pages / + ((double)diff(start, end).tv_sec + + (double)diff(start, end).tv_nsec / 100000000.0)); + return NULL; } @@ -293,6 +349,8 @@ static void run_test(enum vm_guest_mode mode, int vcpus, uint64_t vcpu_wss) uint64_t guest_num_pages; int vcpu_id; int r; + struct timespec start; + struct timespec end; vm = create_vm(mode, vcpus, vcpu_wss); @@ -402,6 +460,8 @@ static void run_test(enum vm_guest_mode mode, int vcpus, uint64_t vcpu_wss) DEBUG("Finished creating vCPUs and starting uffd threads\n"); + clock_gettime(CLOCK_MONOTONIC, &start); + for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) { pthread_create(&vcpu_threads[vcpu_id], NULL, vcpu_worker, &vcpu_args[vcpu_id]); @@ -417,11 +477,19 @@ static void run_test(enum vm_guest_mode mode, int vcpus, uint64_t vcpu_wss) DEBUG("All vCPU threads joined\n"); + clock_gettime(CLOCK_MONOTONIC, &end); + /* Tell the user fault fd handler thread to quit */ quit_uffd_thread = true; for (vcpu_id = 0; vcpu_id < vcpus; vcpu_id++) pthread_join(uffd_handler_threads[vcpu_id], NULL); + DEBUG("Total guest execution time: %lld.%.9lds\n", + (long long)(diff(start, end).tv_sec), diff(start, end).tv_nsec); + DEBUG("Overall demand paging rate: %f pgs/sec\n", + guest_num_pages / ((double)diff(start, end).tv_sec + + (double)diff(start, end).tv_nsec / 100000000.0)); + ucall_uninit(vm); kvm_vm_free(vm); From patchwork Fri Sep 27 16:18:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164821 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 41EF1112B for ; Fri, 27 Sep 2019 16:18:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1F87F21841 for ; Fri, 27 Sep 2019 16:18:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="mVYC3AcL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728116AbfI0QS6 (ORCPT ); Fri, 27 Sep 2019 12:18:58 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:34749 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728079AbfI0QS5 (ORCPT ); Fri, 27 Sep 2019 12:18:57 -0400 Received: by mail-pf1-f201.google.com with SMTP id a1so2248851pfn.1 for ; Fri, 27 Sep 2019 09:18:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=xPCv3uXlazWlSRskqsdKaxPZp5dQ/Fe6mwXEmAcpuP8=; b=mVYC3AcLqq7lpR19qrtmXwTpN1QH5NUWNrU1PmCycH095IpjGR1B0fdArc9tx04NQy pGMWOIsWinFLN73640zmBst/Id7FoEv26Q8/tyxEqSUXrvRVgapQSX/u9ZP6a+xJB2Qd 7o+FPsaJ9JJheZHknu1tFk+FmM5xdX1i2CaW5CM0hqGjmNtIG6bWnidceMQXfke7I4eW h1qou1FaE/RUPacwmhPydQYy9YSbuHDy1Y3P8dyUnB4wqVRm8ZdfsKlixyF7R+N6ysgm w11ApIWQflqXvq8cwvkANRaBP+m8x3oe8ljkZcwyIfu+VAn/5B06iBZlYeg4TTHF3Yka 0ojw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=xPCv3uXlazWlSRskqsdKaxPZp5dQ/Fe6mwXEmAcpuP8=; b=HpDIR4oXQuUNCgDvOZmbora0YcqX8/d1Wi8ILfzPbVmWRpqNdzcVzWNmEAhqfp7ihH zMZ+oKqbWgvkn/cq2G5/G7taTow2npKAUo3YY93VlWlR+YRF44JGCRG0egH/AArKx31l oM+9p2VwgL5Yumt2SXapTHyyVoppJh0qLocrWjvOsYwgUHGji0CIjosj74LxR0A2rbpZ QIbC733uAlf+Dg2HCIu5Yxpqs7wRPcCFb1LzWPL286uP35kO9pGURKC9uWHr6GTCEcBl cd07nkvcnvLUVi1M+ueQLQcbW9Mw2bHVPRQy7cZK5KfWh7eoezqgkBtwoz75/DknWukz 4U5Q== X-Gm-Message-State: APjAAAXkMURobo1twa1ha+o4mMhpv3y0IFD4nyKReNXoZN7UL2j7oH4i hGoWbIaHSBd6ZrLhIjQsUjO0hZMEklE6B4/hqlyzbLo307sjqJ8It0oWORUxm3QPkzOn0JuB3sT ownGpsyI6CPHSeueH1K46kYcPZPNIaRT3youj8AMCtg66s/DR0WWeFvZrf4A7 X-Google-Smtp-Source: APXvYqx+BBzjvqkkOTkRQKWs+KPSIBz5jwmJqyJwsaFtM9cKE3ONTWQHR9MkRYt9CTyeguTQ/0drBIVepuuK X-Received: by 2002:a63:4754:: with SMTP id w20mr10340734pgk.134.1569601135246; Fri, 27 Sep 2019 09:18:55 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:35 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-8-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 7/9] KVM: selftests: Add parameter to _vm_create for memslot 0 base paddr From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org KVM creates internal memslots between 3 and 4 GiB paddrs on the first vCPU creation. If memslot 0 is large enough it collides with these memslots an causes vCPU creation to fail. Add a paddr parameter for memslot 0 so that tests which support large VMs can relocate memslot 0 above 4 GiB. Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/demand_paging_test.c | 2 +- tools/testing/selftests/kvm/dirty_log_test.c | 2 +- tools/testing/selftests/kvm/include/kvm_util.h | 3 ++- tools/testing/selftests/kvm/lib/kvm_util.c | 7 ++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index fe6c5a4f8b8c2..eb1f7e4b83de3 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -171,7 +171,7 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, int vcpus, pages += (2 * pages) / PTES_PER_PT; pages += ((2 * vcpus * vcpu_wss) >> PAGE_SHIFT_4K) / PTES_PER_PT; - vm = _vm_create(mode, pages, O_RDWR); + vm = vm_create(mode, pages, O_RDWR); kvm_vm_elf_load(vm, program_invocation_name, 0, 0); #ifdef __x86_64__ vm_create_irqchip(vm); diff --git a/tools/testing/selftests/kvm/dirty_log_test.c b/tools/testing/selftests/kvm/dirty_log_test.c index 5614222a66285..181eac3a12b66 100644 --- a/tools/testing/selftests/kvm/dirty_log_test.c +++ b/tools/testing/selftests/kvm/dirty_log_test.c @@ -252,7 +252,7 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, uint32_t vcpuid, struct kvm_vm *vm; uint64_t extra_pg_pages = extra_mem_pages / 512 * 2; - vm = _vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR); + vm = vm_create(mode, DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, O_RDWR); kvm_vm_elf_load(vm, program_invocation_name, 0, 0); #ifdef __x86_64__ vm_create_irqchip(vm); diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 29cccaf96baf6..4f672c00c9e9b 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -69,7 +69,8 @@ int kvm_check_cap(long cap); int vm_enable_cap(struct kvm_vm *vm, struct kvm_enable_cap *cap); struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm); -struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm); +struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t guest_paddr, + uint64_t phy_pages, int perm); void kvm_vm_free(struct kvm_vm *vmp); void kvm_vm_restart(struct kvm_vm *vmp, int perm); void kvm_vm_release(struct kvm_vm *vmp); diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 80a338b5403c3..7ec2bbdaba875 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -132,7 +132,8 @@ _Static_assert(sizeof(vm_guest_mode_string)/sizeof(char *) == NUM_VM_MODES, * descriptor to control the created VM is created with the permissions * given by perm (e.g. O_RDWR). */ -struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) +struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t guest_paddr, + uint64_t phy_pages, int perm) { struct kvm_vm *vm; @@ -229,14 +230,14 @@ struct kvm_vm *_vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) vm->vpages_mapped = sparsebit_alloc(); if (phy_pages != 0) vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, - 0, 0, phy_pages, 0); + guest_paddr, 0, phy_pages, 0); return vm; } struct kvm_vm *vm_create(enum vm_guest_mode mode, uint64_t phy_pages, int perm) { - return _vm_create(mode, phy_pages, perm); + return _vm_create(mode, 0, phy_pages, perm); } /* From patchwork Fri Sep 27 16:18:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardon X-Patchwork-Id: 11164823 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id ABA09924 for ; Fri, 27 Sep 2019 16:18:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8AC2421850 for ; Fri, 27 Sep 2019 16:18:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="DJzZh8XT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728119AbfI0QS6 (ORCPT ); Fri, 27 Sep 2019 12:18:58 -0400 Received: from mail-qt1-f202.google.com ([209.85.160.202]:50811 "EHLO mail-qt1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728112AbfI0QS6 (ORCPT ); Fri, 27 Sep 2019 12:18:58 -0400 Received: by mail-qt1-f202.google.com with SMTP id d24so5354893qtn.17 for ; Fri, 27 Sep 2019 09:18:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=5ZuP6sW4dc0DGUSf3S28WoHPVkPfdDixP8+uQWXCCWg=; b=DJzZh8XTngCnOX722VLXiZpGVBQ+CixPkF3c9/7dJYq5WCrSS7SJBrDrW9qrnjlgPh 79EROoulIkMBCFHpni/DcJSvW1txDB6NNZEjsZ2aDbOPBsCBqbpNosN/j5dYGV2OC5dc DYTiPNMc7yb70LTzXzB4/2BB3nAgZRIKkE7m0p5vAAGzzT1XgRjHfkAHq4IIy3gPa27x 1z3su1JRBwN/dBQkMb++y9MhmxylaKtLkhY2vpEFS73bhq9gpO/lJadL6+VzKK1RjmZL QWDuqG4db7jwrFXPG1T2mj9KeM0OR38D6CIcbqixc2IWBfXviTBPET16AGVF1WNnT/6B v1bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=5ZuP6sW4dc0DGUSf3S28WoHPVkPfdDixP8+uQWXCCWg=; b=XpchbQr5a17rlMBU69tbL71nA0P7HokX79+9vHVJ03cI0/tarJwKPbgyQAn6LhDXhY Bh0l9gJRAc76suJi6lggSuKcqN/tp3aNh8VeNIhJ11J02ldCmfLrepCmweY1C2kj50V6 Dv+OSArXDGMDcYBZd2UoNzYUeRtEj/kkHBankvqBgF44ZNX9rqG0FD7pF/9p58WPMAhL H18JjKkGEvOEOf3TPnJy8/GS8j9J7BrU/o38IpvN80OoHyZBfu9aa33/6v5d98IdQ1DK cTAYk6hjGhm/j/SdX7I79evRe3FO0/uzy+RDh3T7qgq+hGmNAORNtbQouS6ve/lEVDHR PTrw== X-Gm-Message-State: APjAAAWkP0fNu6hTJApxd5bf5oU6CCZQQ6F4vZrri9lr44451BCO3Pmj qXY9wRGYg4BBk5VLithMblf2AoBKr4ubEcQwtGEDCusGekMnDlJ3LwnJqTl27ZWis3Jj11vysND Oylqa3F6Q35U55Eo2rwxFJ593LJsqoBt1sfnbNmuWxvL9scHmv5obXu/tEykS X-Google-Smtp-Source: APXvYqyYcBDWAtVNPkG6ko9XIDhB6+oAP2NJ/q9ndUoK8ODyWHTX/wYJkzR7aE2qb7y3gz37yWHYRiNkOefW X-Received: by 2002:ac8:329d:: with SMTP id z29mr11063636qta.112.1569601137543; Fri, 27 Sep 2019 09:18:57 -0700 (PDT) Date: Fri, 27 Sep 2019 09:18:36 -0700 In-Reply-To: <20190927161836.57978-1-bgardon@google.com> Message-Id: <20190927161836.57978-9-bgardon@google.com> Mime-Version: 1.0 References: <20190927161836.57978-1-bgardon@google.com> X-Mailer: git-send-email 2.23.0.444.g18eeb5a265-goog Subject: [PATCH 8/9] KVM: selftests: Support large VMs in demand paging test From: Ben Gardon To: kvm@vger.kernel.org, linux-kselftest@vger.kernel.org Cc: Paolo Bonzini , Cannon Matthews , Peter Xu , Andrew Jones , Ben Gardon Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move memslot 0 past 4 GiB to support the large page tables required to map several TiB of memory. Signed-off-by: Ben Gardon --- tools/testing/selftests/kvm/demand_paging_test.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/demand_paging_test.c b/tools/testing/selftests/kvm/demand_paging_test.c index eb1f7e4b83de3..a733bb3c91fd4 100644 --- a/tools/testing/selftests/kvm/demand_paging_test.c +++ b/tools/testing/selftests/kvm/demand_paging_test.c @@ -24,6 +24,12 @@ #include "kvm_util.h" #include "processor.h" +/* + * Put slot 0 past the first 4G of guest physical address to avoid collision + * with KVM-internal memslots. + */ +#define SLOT_0_GPA (4UL << 30) + /* The memory slot index demand page */ #define TEST_MEM_SLOT_INDEX 1 @@ -171,7 +177,7 @@ static struct kvm_vm *create_vm(enum vm_guest_mode mode, int vcpus, pages += (2 * pages) / PTES_PER_PT; pages += ((2 * vcpus * vcpu_wss) >> PAGE_SHIFT_4K) / PTES_PER_PT; - vm = vm_create(mode, pages, O_RDWR); + vm = _vm_create(mode, SLOT_0_GPA, pages, O_RDWR); kvm_vm_elf_load(vm, program_invocation_name, 0, 0); #ifdef __x86_64__ vm_create_irqchip(vm);