From patchwork Tue Sep 10 23:44:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ackerley Tng X-Patchwork-Id: 13799506 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 853AFEE01F1 for ; Tue, 10 Sep 2024 23:46:15 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 4BB778D00EC; Tue, 10 Sep 2024 19:45:34 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 445D58D00E2; Tue, 10 Sep 2024 19:45:34 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 249818D00EC; Tue, 10 Sep 2024 19:45:34 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 02CAA8D00E2 for ; Tue, 10 Sep 2024 19:45:33 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id BAFD2C04E9 for ; Tue, 10 Sep 2024 23:45:32 +0000 (UTC) X-FDA: 82550462904.19.2AFA436 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) by imf13.hostedemail.com (Postfix) with ESMTP id 0140E20006 for ; Tue, 10 Sep 2024 23:45:30 +0000 (UTC) Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=oLCWlCx+; spf=pass (imf13.hostedemail.com: domain of 3GdrgZgsKCI4su2w93wGB5yy66y3w.u64305CF-442Dsu2.69y@flex--ackerleytng.bounces.google.com designates 209.85.128.201 as permitted sender) smtp.mailfrom=3GdrgZgsKCI4su2w93wGB5yy66y3w.u64305CF-442Dsu2.69y@flex--ackerleytng.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1726011793; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=afFoS57EFj7PA7MrTOtXA3rUEPuyIQGDyAEgOLUqk8M=; b=R2SU7obHKp6y9YqhzO7tEfal1nNR3vbxhTyvcDkh1xHe63k3sdJ7BogbVlz8v/DqTucoDq dsJ8eCgJqjK5n6PuepM0SKwQCFMJtjxeQCAEabFLGMYqfdG3Ybb8nY/MKzXQ6mtoAwcvfj HWXNpm6VKBh1O/B+/RoZrm2bVSuxKhg= ARC-Authentication-Results: i=1; imf13.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=oLCWlCx+; spf=pass (imf13.hostedemail.com: domain of 3GdrgZgsKCI4su2w93wGB5yy66y3w.u64305CF-442Dsu2.69y@flex--ackerleytng.bounces.google.com designates 209.85.128.201 as permitted sender) smtp.mailfrom=3GdrgZgsKCI4su2w93wGB5yy66y3w.u64305CF-442Dsu2.69y@flex--ackerleytng.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1726011793; a=rsa-sha256; cv=none; b=Y7HEAwhCX9lUKhUvo9krl3TOM1HGeQvicySnb61U3SYGPD4ZDySku9ydQqLn18Bc1Q5bqu pmRwKeYtaclQZ7uNoAWcFsqWl8e++AtPULmeosWcP6UYZMVEBzbcDj+OiVqGbNYwmDY2cy 3lO9lzJhn38br75JE+zTAURR/cPsr94= Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6d475205628so186142497b3.0 for ; Tue, 10 Sep 2024 16:45:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1726011930; x=1726616730; darn=kvack.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=afFoS57EFj7PA7MrTOtXA3rUEPuyIQGDyAEgOLUqk8M=; b=oLCWlCx+ktMEDQTJYcAcGLrmttUcFAhuluQ0Iaxg4UwC7LA8TSj0dDy9a6vKpku+0E 5Sdn1YNVhZifo1AImEOm7/6wCCXSrzvoi2nprpis0DOuvhv1kNk0p+EmsRAMk4kP2UvW vDY2616NwSz3mjCgpnAGFWOu7BSJ0i7g2Ifg8atTJizKhODkHKe8mHEGvnKVX6RoFMry GUHevUduFxdVBChuJQ01n7lz5al62n4sgwUYkJkA/gzo52+nMbXtDPTyx4wTnW9trg8i 6becC5hwXzG0pPafGMHhdKYFrxnuBr5T+bkglt2W65sqqjYMx/xYWBCexj6p7M3FRxXj AqRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726011930; x=1726616730; 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=afFoS57EFj7PA7MrTOtXA3rUEPuyIQGDyAEgOLUqk8M=; b=UUlcWINSD/y0gyCC695XfvaBj9/kGW/+mo3u3LeE5hvQcXDf3osfhQytHAnWA9yBWr H0xq3UA9gwtez8MYkI4tXlL1KtXCvJMmqqejOgh+btRGD7KNXqm1F6cOln2WFfqHnZ9E /Ta3AQCuYn/0qVUs39LjtT39+ee38C+cx27YBM2c/yil7HykGUHKp8Z8gzYUQzwfFqMp lDyCBYh+FSCXCUiDjyNQNzMOOSwWzhHzXT2YYtERQAqQFFto2g6gf6cbq9FneauVpJhS PiXN5YFdMZk23Bl4Alx0ltvB7AFPTQPS00fH/Na2Z5XN/UcLOnayF8U23awYoRQPpFqm xJWg== X-Forwarded-Encrypted: i=1; AJvYcCUWLD06YFhNw9NwmtOX+S9VuTZgOS6TENlbuW+azKcqnIYzUYDHBGzo+wT8MMSXQLLxnMI5CBvDjg==@kvack.org X-Gm-Message-State: AOJu0YyRoS/vzKHE7v++ZLJ9ogZ0/x2Jjz7e4I+LaMiWU6Dka07qwoVu Fs6f+9mzhy4BseFIR9n+3uvdX2j/3hvhrrMirkSPLh1YP7d3SqzClbmIKhZSaGcygfwlagjbFlE FOYyyDmGIi4eFS8GTYyPo5Q== X-Google-Smtp-Source: AGHT+IFM7zwKBbA2/Jy7tyIWzTxWbF+45RbnY6QrI6xQ5u7bHZg40qPkgO7/Rd+Sibot2kYeLv7TVh8XJXwwFOEoiw== X-Received: from ackerleytng-ctop.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:13f8]) (user=ackerleytng job=sendgmr) by 2002:a25:ef46:0:b0:e1a:8735:8390 with SMTP id 3f1490d57ef6-e1d3489c673mr70623276.4.1726011929867; Tue, 10 Sep 2024 16:45:29 -0700 (PDT) Date: Tue, 10 Sep 2024 23:44:04 +0000 In-Reply-To: Mime-Version: 1.0 References: X-Mailer: git-send-email 2.46.0.598.g6f2099f65c-goog Message-ID: <19a16094c3e99d83c53931ff5f3147079d03c810.1726009989.git.ackerleytng@google.com> Subject: [RFC PATCH 33/39] KVM: selftests: Test guest_memfd memory sharing between guest and host From: Ackerley Tng To: tabba@google.com, quic_eberman@quicinc.com, roypat@amazon.co.uk, jgg@nvidia.com, peterx@redhat.com, david@redhat.com, rientjes@google.com, fvdl@google.com, jthoughton@google.com, seanjc@google.com, pbonzini@redhat.com, zhiquan1.li@intel.com, fan.du@intel.com, jun.miao@intel.com, isaku.yamahata@intel.com, muchun.song@linux.dev, mike.kravetz@oracle.com Cc: erdemaktas@google.com, vannapurve@google.com, ackerleytng@google.com, qperret@google.com, jhubbard@nvidia.com, willy@infradead.org, shuah@kernel.org, brauner@kernel.org, bfoster@redhat.com, kent.overstreet@linux.dev, pvorel@suse.cz, rppt@kernel.org, richard.weiyang@gmail.com, anup@brainfault.org, haibo1.xu@intel.com, ajones@ventanamicro.com, vkuznets@redhat.com, maciej.wieczor-retman@intel.com, pgonda@google.com, oliver.upton@linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org, kvm@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-fsdevel@kvack.org X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 0140E20006 X-Stat-Signature: 1fraj5uk8owqmmzzd9cd57jkzfiezhwn X-Rspam-User: X-HE-Tag: 1726011930-940024 X-HE-Meta: U2FsdGVkX1/DGlm5kMeP2+ysM5RlwOZokkYw4ugyFBacI2r1eKXvsh0SwctdDcB128HtlvwWpLEeM+W4TagrN9QhqYwBm+Jwjuq4H5yWE8f+NAbnYBkGSu4/uwNqUkSYQocAkPlLCwDEj6MnySA1R1VQl0d7DDu8HUKBfr327xNW2hjHgkCtT81ffsV0KiWq3fZAXd/TPkm0fDpyomPWqIiWCq8HV05Bhs8Sh24lICfl8xlItZKY7v/W8esjnHyggfSAw6bKXfQxK8lsRSv+LdrW31wKNI+hj4/S4ylX4py8FUFAchIoX6gsIKYsdWr5ev3JeiD5qkGLMM7v/yhkojGYUgLhlPK+xXnbFVQRn+wI0f9cYN7PvauEixf4ry8sQOSrjDsLQcrDriX1hMl6NxEKAvO3yFpCRTOEL3uIbEX7gPbcDO+raarlZHMQgdq7kkJqjxx7v/XXEJwzJ7VgeroNrhJtTbTAHILe9VSTuETqWkNTOK4xMIUxZc3MM1cR2BkZQ+5n3w2Toavm6u3fK876rfqY0li6QBCSr0Kr2eoEts+jZKNu95v7ttLKItyCSl/b8AxQhi/W+sbYoCpWshekareBRZwyGPF1NOf3T3F3OCjEVAf8wehYBZOHvK9LdICuvfaPUolkLsTO1qoW8O6YFYkX+AW9hIJ5JwCjWUxn0tczB1M96+drd/jPTPgWjTg7rb7EyPpIVwna2CJYuxtn2rnqTnSqNLWcEAdzGDiJzKdUIRjxr4/Hdwl3+SIjQImjlnW0QsSRCVvtmJ+otNRlEkAU02RU12xPe+p69Ekswr/T4rS26nu1+lqQr95pxmSJxDRVD9aPM/ZUn/DHJopiqR1DSqtST7C8QfKxBHdKk7FY4w5/8e05xJ77bY4Dmx4OLOZS2GnaIBrTPdwnnvUo8JGlbvC+56WVQ2yGyVPrsZSlCh7Mq1jU9NxfDEeuuCLz8M91pmMx0SFejbY wOZggPWr EejweWF0bJROpsV/a3aoXzm90xEGds9WzHEOK68z0Bbo8KnJK3dad4g1o/ef8P58nVFwCtxsP3oZH8bnMt3wsh6bFC4vbKOjIMSWbgrSmcDtMdUdXXecEOmQRM8wbTUtAGG5ZJ0jCl9QCbvI2Bd+OgpD9YRMDJGh/mkQ09MVVc+FXY9UnaFOhTJlGcT8hc14RZ1HG5JGwpjgZA26QAV7kSqioteVa1RHFSNVipBNvbZf7Scghpy70xQZL5mRG9lFJDw/2CJVNBkTyyd/t6OltggPcnW9LRGuZIuBjGQIESm5Vm+f409el+ORK7ejRKEjuxIbHmxrDdCuXFaOOh/bV2bHCYusQmkCB3eY+uyP3N5ODvxrfu8Xdplrxhhce7ZfeFYnBTZ29cy6ld4MTgoClGwhm7r07uTM1EoUv5sayHK+KJ/SDhPLPGRzluhUNHFRM3aOVgCdGniHYg96XeI4eLnCZxSoJvb2KrDL7nYuH6Xslw+pPULdeI3y2ky2C76WSn4meQWRV+cAdLUUqU8FEcf6FKHgrX9SWAWeOQJlNwYLX/ssBg8Ys6AIJiOj4BlX5OTjJGtnkPt12KOLZ7rZkyokgAf4HdI2mnAqABiiEJDF+NNj4rHVt/EVsE1tDFyBa8pJ7VPCV0Oo/c0z5YFpZwtJu/Wf1+ze6PWOYsg+DoBS6DcDu72Ko9yr4t1Mg62Qdov+MoyzLjalnvo0= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000002, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Minimal test for guest_memfd to test that when memory is marked shared in a VM, the host can read and write to it via an mmap()ed address, and the guest can also read and write to it. Signed-off-by: Ackerley Tng --- tools/testing/selftests/kvm/Makefile | 1 + .../selftests/kvm/guest_memfd_sharing_test.c | 160 ++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 tools/testing/selftests/kvm/guest_memfd_sharing_test.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index b3b7e83f39fc..3c1f35456bfc 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -135,6 +135,7 @@ TEST_GEN_PROGS_x86_64 += dirty_log_test TEST_GEN_PROGS_x86_64 += dirty_log_perf_test TEST_GEN_PROGS_x86_64 += guest_memfd_test TEST_GEN_PROGS_x86_64 += guest_memfd_hugetlb_reporting_test +TEST_GEN_PROGS_x86_64 += guest_memfd_sharing_test TEST_GEN_PROGS_x86_64 += guest_print_test TEST_GEN_PROGS_x86_64 += hardware_disable_test TEST_GEN_PROGS_x86_64 += kvm_create_max_vcpus diff --git a/tools/testing/selftests/kvm/guest_memfd_sharing_test.c b/tools/testing/selftests/kvm/guest_memfd_sharing_test.c new file mode 100644 index 000000000000..fef5a73e5053 --- /dev/null +++ b/tools/testing/selftests/kvm/guest_memfd_sharing_test.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Minimal test for guest_memfd to test that when memory is marked shared in a + * VM, the host can read and write to it via an mmap()ed address, and the guest + * can also read and write to it. + * + * Copyright (c) 2024, Google LLC. + */ +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "ucall_common.h" + +#define GUEST_MEMFD_SHARING_TEST_SLOT 10 +#define GUEST_MEMFD_SHARING_TEST_GPA 0x50000000ULL +#define GUEST_MEMFD_SHARING_TEST_GVA 0x90000000ULL +#define GUEST_MEMFD_SHARING_TEST_OFFSET 0 +#define GUEST_MEMFD_SHARING_TEST_GUEST_TO_HOST_VALUE 0x11 +#define GUEST_MEMFD_SHARING_TEST_HOST_TO_GUEST_VALUE 0x22 + +static void guest_code(int page_size) +{ + char *mem; + int i; + + mem = (char *)GUEST_MEMFD_SHARING_TEST_GVA; + + for (i = 0; i < page_size; ++i) { + GUEST_ASSERT_EQ(mem[i], GUEST_MEMFD_SHARING_TEST_HOST_TO_GUEST_VALUE); + } + + memset(mem, GUEST_MEMFD_SHARING_TEST_GUEST_TO_HOST_VALUE, page_size); + + GUEST_DONE(); +} + +int run_test(struct kvm_vcpu *vcpu, void *hva, int page_size) +{ + struct ucall uc; + uint64_t uc_cmd; + + memset(hva, GUEST_MEMFD_SHARING_TEST_HOST_TO_GUEST_VALUE, page_size); + vcpu_args_set(vcpu, 1, page_size); + + /* Reset vCPU to guest_code every time run_test is called. */ + vcpu_arch_set_entry_point(vcpu, guest_code); + + vcpu_run(vcpu); + uc_cmd = get_ucall(vcpu, &uc); + + if (uc_cmd == UCALL_ABORT) { + REPORT_GUEST_ASSERT(uc); + return 1; + } else if (uc_cmd == UCALL_DONE) { + char *mem; + int i; + + mem = hva; + for (i = 0; i < page_size; ++i) + TEST_ASSERT_EQ(mem[i], GUEST_MEMFD_SHARING_TEST_GUEST_TO_HOST_VALUE); + + return 0; + } else { + TEST_FAIL("Unknown ucall 0x%lx.", uc.cmd); + return 1; + } +} + +void *add_memslot(struct kvm_vm *vm, int guest_memfd, size_t page_size, + bool back_shared_memory_with_guest_memfd) +{ + void *mem; + + if (back_shared_memory_with_guest_memfd) { + mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_SHARED, + guest_memfd, GUEST_MEMFD_SHARING_TEST_OFFSET); + } else { + mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + } + TEST_ASSERT(mem != MAP_FAILED, "mmap should return valid address"); + + /* + * Setting up this memslot with a KVM_X86_SW_PROTECTED_VM marks all + * offsets in the file as shared. + */ + vm_set_user_memory_region2(vm, GUEST_MEMFD_SHARING_TEST_SLOT, + KVM_MEM_GUEST_MEMFD, + GUEST_MEMFD_SHARING_TEST_GPA, page_size, mem, + guest_memfd, GUEST_MEMFD_SHARING_TEST_OFFSET); + + return mem; +} + +void test_sharing(bool back_shared_memory_with_guest_memfd) +{ + const struct vm_shape shape = { + .mode = VM_MODE_DEFAULT, + .type = KVM_X86_SW_PROTECTED_VM, + }; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + size_t page_size; + int guest_memfd; + void *mem; + + TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_VM)); + + vm = vm_create_shape_with_one_vcpu(shape, &vcpu, &guest_code); + + page_size = getpagesize(); + + guest_memfd = vm_create_guest_memfd(vm, page_size, 0); + + mem = add_memslot(vm, guest_memfd, page_size, back_shared_memory_with_guest_memfd); + + virt_map(vm, GUEST_MEMFD_SHARING_TEST_GVA, GUEST_MEMFD_SHARING_TEST_GPA, 1); + + run_test(vcpu, mem, page_size); + + /* Toggle private flag of memory attributes and run the test again. */ + if (back_shared_memory_with_guest_memfd) { + /* + * Use MADV_REMOVE to release the backing guest_memfd memory + * back to the system before it is used again. Test that this is + * only necessary when guest_memfd is used to back shared + * memory. + */ + madvise(mem, page_size, MADV_REMOVE); + } + vm_mem_set_private(vm, GUEST_MEMFD_SHARING_TEST_GPA, page_size); + vm_mem_set_shared(vm, GUEST_MEMFD_SHARING_TEST_GPA, page_size); + + run_test(vcpu, mem, page_size); + + kvm_vm_free(vm); + munmap(mem, page_size); + close(guest_memfd); +} + +int main(int argc, char *argv[]) +{ + /* + * Confidence check that when guest_memfd is associated with a memslot + * but only anonymous memory is used to back shared memory, sharing + * memory between guest and host works as expected. + */ + test_sharing(false); + + /* + * Memory sharing should work as expected when shared memory is backed + * with guest_memfd. + */ + test_sharing(true); + + return 0; +}