From mboxrd@z Thu Jan 1 00:00:00 1970 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 816BFC4167D for ; Sun, 5 Nov 2023 16:35:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 1D5D2440174; Sun, 5 Nov 2023 11:35:14 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 18685440150; Sun, 5 Nov 2023 11:35:14 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 000A5440174; Sun, 5 Nov 2023 11:35:13 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id DF249440150 for ; Sun, 5 Nov 2023 11:35:13 -0500 (EST) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id B71E31CADDB for ; Sun, 5 Nov 2023 16:35:13 +0000 (UTC) X-FDA: 81424450506.15.FB998FB Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf12.hostedemail.com (Postfix) with ESMTP id EE7D24000E for ; Sun, 5 Nov 2023 16:35:11 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=ipLaO9iW; spf=pass (imf12.hostedemail.com: domain of pbonzini@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=pbonzini@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1699202112; 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:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=/2lNQXYYLsrbLYVTniaVgwqPe8IQbGXrUlIvAzks0mI=; b=fH/b/S6OuPMHl5BCl1YV0SbJjfqm/O6WSPiqocoMFXoLbMtATCmDp9uu4t4X9B2EBa3bXO Wxw3xjpSjbFOcJJVa673v2mBPXYL1LeP4b955xA9bQd4PBYnewY39uWKrUexVQsnYRSxZ5 cosqHTExKsgRIaOLrpw78VHXBMk4x34= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1699202112; a=rsa-sha256; cv=none; b=HtX7aXT6+aSTFrhvOp6oJJKg0rs3dsSHtl6VWS3qsiojrhqnGN/4v2C76woZHqeRNawev+ 1YuDpO69KlFYgggJ59+5HzvkmX/9H16RWN8TWWg8TehVJlZM+XXbjuqEz9bsBGy1FJEQGJ OvxGFGQLO6YvqQTDVpOQJ9LDCVQdj84= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=ipLaO9iW; spf=pass (imf12.hostedemail.com: domain of pbonzini@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=pbonzini@redhat.com; dmarc=pass (policy=none) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1699202111; h=from:from: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:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/2lNQXYYLsrbLYVTniaVgwqPe8IQbGXrUlIvAzks0mI=; b=ipLaO9iWdqc/5bvtOvzp3Thhh6DBrA0W0VdMiNj2TF0GEzvMBDta20gGUABLJWeil5dAMf WSzMajORiFLY282TtKHuBZ/L6HVaYc859S5wvxwAHZyL4WyViTUEeCahzraVEgrxneAdWE e2A8hHd0CLgSXGayA6VLQE0x7L/C4sE= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-623-PZYekO_bNTiMZxiF_ZfE-g-1; Sun, 05 Nov 2023 11:35:05 -0500 X-MC-Unique: PZYekO_bNTiMZxiF_ZfE-g-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B902180C346; Sun, 5 Nov 2023 16:35:03 +0000 (UTC) Received: from avogadro.redhat.com (unknown [10.39.192.93]) by smtp.corp.redhat.com (Postfix) with ESMTP id 960692166B26; Sun, 5 Nov 2023 16:34:56 +0000 (UTC) From: Paolo Bonzini To: Paolo Bonzini , Marc Zyngier , Oliver Upton , Huacai Chen , Michael Ellerman , Anup Patel , Paul Walmsley , Palmer Dabbelt , Albert Ou , Sean Christopherson , Alexander Viro , Christian Brauner , "Matthew Wilcox (Oracle)" , Andrew Morton Cc: kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Xiaoyao Li , Xu Yilun , Chao Peng , Fuad Tabba , Jarkko Sakkinen , Anish Moorthy , David Matlack , Yu Zhang , Isaku Yamahata , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , Vlastimil Babka , Vishal Annapurve , Ackerley Tng , Maciej Szmigiero , David Hildenbrand , Quentin Perret , Michael Roth , Wang , Liam Merwick , Isaku Yamahata , "Kirill A. Shutemov" Subject: [PATCH 33/34] KVM: selftests: Test KVM exit behavior for private memory/access Date: Sun, 5 Nov 2023 17:30:36 +0100 Message-ID: <20231105163040.14904-34-pbonzini@redhat.com> In-Reply-To: <20231105163040.14904-1-pbonzini@redhat.com> References: <20231105163040.14904-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.6 X-Rspamd-Queue-Id: EE7D24000E X-Rspam-User: X-Stat-Signature: zsicfcqeiwpntqkpdroxpcae4wiadqcs X-Rspamd-Server: rspam03 X-HE-Tag: 1699202111-817284 X-HE-Meta: U2FsdGVkX1+o/pA1kQdhAf7HNJ+sxV4upsflezAV1+COXQpGUwoFrzND5wrdCux+wgsiGe5JBRvkpx/BgKjeVPJ/ZlnpOsON7BQGxUww8FwUSDej54LW234fxqBv/ca4wmhC9JIlvHS54E/9UCwGNhg9JtEPrlPmCE9ITgwCiDafd8XqS79eWdX+v/ECGrznxfQHFurbX54o5DtvCbyn1y7qinGvcDKhYb2SVN6SvfSanTMYRvJV6cGcfQyemRZHvonWxbJZOoG66LOuShkv/mnaGt9a1ufSJGITXOKJa70wpVLHgtHhHIX4tD66kNmAvPEDwoKdZvulZRKpW2J3vaFouIEts276ObpY7IzVR5UjO8UNkcdPVmMIYmxaVqzfrtRTZixjoJAod0KHVU9evJMMuDuE3LhdepraqnlxqWDcC3q+Rr9k22Qt653uL6+cF1R8CEwDyAs/yfS1qR+B28iBpI8oxC/yKb3Co+WFFFNtBOlRk8LYZW5OAZdXEsHv32aPHiEr8spsARIHffWOSPdovYJXxXfqRqwiZA+QwPMxp0GVLVEOTFbsJRAQsV93wDZLDT0MeTk7WcvzK/S1NGm9RlOHsFbvNYBeR8QNWs+rTRezBERyr0mdhr/O8vBWUFPOEdL6rPNk8UIQ24g6u6YNEEV7x6bjXS2JpkuAxnzQcoxIwYJt1OimJJgIbFESXB4KkIkV5mGw7FISlFmKkj8s3MhRvw6ROeccco59omlWODkvqg8pckrPkSAkKZwZK6kw89NPT2Y0z4oQ5gYACchcAPfDk/TTfakHz4VFrbkKOFvu7x4TSEqm/RrJI1FinFyoxqCp9VYPw4GIfvvcS0hIUJ1UKbsf1fsAEDpiylb9UgKoV1dITIeJ3v1x8mKOUaGKvhp4g+u6AWNls1OB1XXnP62OoU23Temgjzzo1ClLDpGdYPQalKUBiHEgUCXT/GZBqhh1KW31+cvk5WE vMsKOeMy Iy2V3jMijoFwR9U16zhcLYlp/aGaJ8mCXFQcIdU3iClTL7kjRMafhaY9Do/0sJdH3yym98WJX8U43USyEl62dd0BK+SPJOyzE9gfGpPDgC6f4LfxvCkKBlb4GaihXfsSGaaj87ukvpPrAX3P6hi4BD/BLu7ZCBCh4OYvr+qgmtGIwyNiq4njT8Kkz0C3nHQGs9lQXgkXO3VNY8vrSvYBK5bshEJIQ3TIIsoHNZT10EWyjPAuCH18LpG6e3NIY3UkoB4TS4u3ZVkxePBg= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: From: Ackerley Tng "Testing private access when memslot gets deleted" tests the behavior of KVM when a private memslot gets deleted while the VM is using the private memslot. When KVM looks up the deleted (slot = NULL) memslot, KVM should exit to userspace with KVM_EXIT_MEMORY_FAULT. In the second test, upon a private access to non-private memslot, KVM should also exit to userspace with KVM_EXIT_MEMORY_FAULT. Intentionally don't take a requirement on KVM_CAP_GUEST_MEMFD, KVM_CAP_MEMORY_FAULT_INFO, KVM_MEMORY_ATTRIBUTE_PRIVATE, etc., as it's a KVM bug to advertise KVM_X86_SW_PROTECTED_VM without its prerequisites. Signed-off-by: Ackerley Tng [sean: call out the similarities with set_memory_region_test] Signed-off-by: Sean Christopherson Message-Id: <20231027182217.3615211-36-seanjc@google.com> Signed-off-by: Paolo Bonzini --- tools/testing/selftests/kvm/Makefile | 1 + .../kvm/x86_64/private_mem_kvm_exits_test.c | 120 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index fd3b30a4ca7b..69ce8e06b3a3 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -92,6 +92,7 @@ TEST_GEN_PROGS_x86_64 += x86_64/nested_exceptions_test TEST_GEN_PROGS_x86_64 += x86_64/platform_info_test TEST_GEN_PROGS_x86_64 += x86_64/pmu_event_filter_test TEST_GEN_PROGS_x86_64 += x86_64/private_mem_conversions_test +TEST_GEN_PROGS_x86_64 += x86_64/private_mem_kvm_exits_test TEST_GEN_PROGS_x86_64 += x86_64/set_boot_cpu_id TEST_GEN_PROGS_x86_64 += x86_64/set_sregs_test TEST_GEN_PROGS_x86_64 += x86_64/smaller_maxphyaddr_emulation_test diff --git a/tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c b/tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c new file mode 100644 index 000000000000..2f02f6128482 --- /dev/null +++ b/tools/testing/selftests/kvm/x86_64/private_mem_kvm_exits_test.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2022, Google LLC. + */ +#include +#include +#include + +#include "kvm_util.h" +#include "processor.h" +#include "test_util.h" + +/* Arbitrarily selected to avoid overlaps with anything else */ +#define EXITS_TEST_GVA 0xc0000000 +#define EXITS_TEST_GPA EXITS_TEST_GVA +#define EXITS_TEST_NPAGES 1 +#define EXITS_TEST_SIZE (EXITS_TEST_NPAGES * PAGE_SIZE) +#define EXITS_TEST_SLOT 10 + +static uint64_t guest_repeatedly_read(void) +{ + volatile uint64_t value; + + while (true) + value = *((uint64_t *) EXITS_TEST_GVA); + + return value; +} + +static uint32_t run_vcpu_get_exit_reason(struct kvm_vcpu *vcpu) +{ + int r; + + r = _vcpu_run(vcpu); + if (r) { + TEST_ASSERT(errno == EFAULT, KVM_IOCTL_ERROR(KVM_RUN, r)); + TEST_ASSERT_EQ(vcpu->run->exit_reason, KVM_EXIT_MEMORY_FAULT); + } + return vcpu->run->exit_reason; +} + +const struct vm_shape protected_vm_shape = { + .mode = VM_MODE_DEFAULT, + .type = KVM_X86_SW_PROTECTED_VM, +}; + +static void test_private_access_memslot_deleted(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + pthread_t vm_thread; + void *thread_return; + uint32_t exit_reason; + + vm = vm_create_shape_with_one_vcpu(protected_vm_shape, &vcpu, + guest_repeatedly_read); + + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, + EXITS_TEST_GPA, EXITS_TEST_SLOT, + EXITS_TEST_NPAGES, + KVM_MEM_GUEST_MEMFD); + + virt_map(vm, EXITS_TEST_GVA, EXITS_TEST_GPA, EXITS_TEST_NPAGES); + + /* Request to access page privately */ + vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE); + + pthread_create(&vm_thread, NULL, + (void *(*)(void *))run_vcpu_get_exit_reason, + (void *)vcpu); + + vm_mem_region_delete(vm, EXITS_TEST_SLOT); + + pthread_join(vm_thread, &thread_return); + exit_reason = (uint32_t)(uint64_t)thread_return; + + TEST_ASSERT_EQ(exit_reason, KVM_EXIT_MEMORY_FAULT); + TEST_ASSERT_EQ(vcpu->run->memory_fault.flags, KVM_MEMORY_EXIT_FLAG_PRIVATE); + TEST_ASSERT_EQ(vcpu->run->memory_fault.gpa, EXITS_TEST_GPA); + TEST_ASSERT_EQ(vcpu->run->memory_fault.size, EXITS_TEST_SIZE); + + kvm_vm_free(vm); +} + +static void test_private_access_memslot_not_private(void) +{ + struct kvm_vm *vm; + struct kvm_vcpu *vcpu; + uint32_t exit_reason; + + vm = vm_create_shape_with_one_vcpu(protected_vm_shape, &vcpu, + guest_repeatedly_read); + + /* Add a non-private memslot (flags = 0) */ + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, + EXITS_TEST_GPA, EXITS_TEST_SLOT, + EXITS_TEST_NPAGES, 0); + + virt_map(vm, EXITS_TEST_GVA, EXITS_TEST_GPA, EXITS_TEST_NPAGES); + + /* Request to access page privately */ + vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE); + + exit_reason = run_vcpu_get_exit_reason(vcpu); + + TEST_ASSERT_EQ(exit_reason, KVM_EXIT_MEMORY_FAULT); + TEST_ASSERT_EQ(vcpu->run->memory_fault.flags, KVM_MEMORY_EXIT_FLAG_PRIVATE); + TEST_ASSERT_EQ(vcpu->run->memory_fault.gpa, EXITS_TEST_GPA); + TEST_ASSERT_EQ(vcpu->run->memory_fault.size, EXITS_TEST_SIZE); + + kvm_vm_free(vm); +} + +int main(int argc, char *argv[]) +{ + TEST_REQUIRE(kvm_check_cap(KVM_CAP_VM_TYPES) & BIT(KVM_X86_SW_PROTECTED_VM)); + + test_private_access_memslot_deleted(); + test_private_access_memslot_not_private(); +} -- 2.39.1