From nobody Sat Feb 7 09:58:53 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BF5A8C0015E for ; Thu, 22 Jun 2023 23:17:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231636AbjFVXRa (ORCPT ); Thu, 22 Jun 2023 19:17:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44388 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231608AbjFVXRX (ORCPT ); Thu, 22 Jun 2023 19:17:23 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D8C51BCC; Thu, 22 Jun 2023 16:17:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687475832; x=1719011832; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ermiXTEXQyF8E2ENU1Af3tf1v3KAorTSmp9Pi7fGpOs=; b=Vhq4I2BV6FYdew35LoEKDmIw8SZc8U8sbR6zTu2ihKFjd5C/dcF/Ukft dyesFvSu9Mpo/Zk7s/BBKQ6JQokvNnoAf312meSXwoN8EQS+kPCi+TDfh O25uvbr7aGut4NE5/N9etWkWcwqCOImqLD1O5VuWEXC7BSpOouJBVBHA6 bP3YMYlccY32NLtTBLLlQEAoIGp37chsbIfRhvQ/Erwr8dG8A6METia86 KRQdkRUMN4m9ROw9zQMW/GxcYdTDzkFj7IerrIqGGruI3oF02qbksckTS yP1AsELHEOURudq0jeFyoTUp78sd9VFduc7Q7TvV5IZUwzY/rWADmL5j6 w==; X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="358129716" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="358129716" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="718285973" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="718285973" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:10 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com, linux-coco@lists.linux.dev, Chao Peng , Ackerley Tng , Vishal Annapurve , Michael Roth Subject: [RFC PATCH v2 1/6] KVM: selftests: Fix test_add_overlapping_private_memory_regions() Date: Thu, 22 Jun 2023 16:16:25 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata The last test in test_add_overlapping_private_memory_regions() doesn't use overlapping regions resulting in the failure. When the region is overlaps with the existing ones, the error code is EEXIST instead of EINVAL. Pass the overlapping region, and check if the errno is EEXIST. Fixes: bdb645960cb5 ("KVM: selftests: Expand set_memory_region_test to vali= date guest_memfd()") Signed-off-by: Isaku Yamahata --- Changes v1 -> v2: - no change --- .../selftests/kvm/set_memory_region_test.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/t= esting/selftests/kvm/set_memory_region_test.c index f46841843300..ea7da324c4d6 100644 --- a/tools/testing/selftests/kvm/set_memory_region_test.c +++ b/tools/testing/selftests/kvm/set_memory_region_test.c @@ -432,6 +432,7 @@ static void test_add_overlapping_private_memory_regions= (void) { struct kvm_vm *vm; int memfd; + int r; =20 pr_info("Testing ADD of overlapping KVM_MEM_PRIVATE memory regions\n"); =20 @@ -453,8 +454,19 @@ static void test_add_overlapping_private_memory_region= s(void) vm_set_user_memory_region2(vm, MEM_REGION_SLOT, KVM_MEM_PRIVATE, MEM_REGION_GPA, 0, NULL, -1, 0); =20 - test_invalid_guest_memfd(vm, memfd, MEM_REGION_SIZE, - "Overlapping guest_memfd() bindings should fail"); + r =3D __vm_set_user_memory_region2(vm, MEM_REGION_SLOT, KVM_MEM_PRIVATE, + MEM_REGION_GPA * 2 - MEM_REGION_SIZE, + MEM_REGION_SIZE * 2, + 0, memfd, 0); + TEST_ASSERT(r =3D=3D -1 && errno =3D=3D EEXIST, "%s", + "Overlapping guest_memfd() bindings should fail"); + + r =3D __vm_set_user_memory_region2(vm, MEM_REGION_SLOT, KVM_MEM_PRIVATE, + MEM_REGION_GPA * 2 + MEM_REGION_SIZE, + MEM_REGION_SIZE * 2, + 0, memfd, 0); + TEST_ASSERT(r =3D=3D -1 && errno =3D=3D EEXIST, "%s", + "Overlapping guest_memfd() bindings should fail"); =20 close(memfd); kvm_vm_free(vm); --=20 2.25.1 From nobody Sat Feb 7 09:58:53 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D04F7EB64DA for ; Thu, 22 Jun 2023 23:17:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231660AbjFVXRc (ORCPT ); Thu, 22 Jun 2023 19:17:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44462 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231592AbjFVXR0 (ORCPT ); Thu, 22 Jun 2023 19:17:26 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B0402686; Thu, 22 Jun 2023 16:17:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687475834; x=1719011834; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Ey//Er7uRB344w44NonunJHMD5Ey7BtAHN0MXVhUTHM=; b=LKlzvoWIj7iG8jZR06FfSD7ThFb4U3wyZuWDqM0nnJ5PBrF9yyVt2Z/o qFwP10eH9FoSbYH7GIoBOCI9Vy5TPFrIwgVo8Maq8KUZUmB+UWZXf/G4a xulxfFvkeEzyoZvfWUwxgF1gp1dexRXN0M4nQhV5p2glICrmZ5bF+dA33 Q69E/BpS4ZMVENWRdu32VvGG9/UCn2gsXtnE8Q1m6JyOYBAoXRH8oeNCS mKmKraJ+VJ5sExO1YU7zVht/Hv4KEBp7qbbpFmNhX3Io/Jhc2OwoLhTN/ 1tw0HGaBeYeurc6Z6YCbEeCqmgZgzmSkZcYxVC4cd9WfRnBN1HYDNzILZ g==; X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="358129721" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="358129721" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:11 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="718285976" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="718285976" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:10 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com, linux-coco@lists.linux.dev, Chao Peng , Ackerley Tng , Vishal Annapurve , Michael Roth Subject: [RFC PATCH v2 2/6] KVM: selftests: Fix guest_memfd() Date: Thu, 22 Jun 2023 16:16:26 -0700 Message-Id: <6934b5a7c87a9804360678c52553cf92c3870b5a.1687474039.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata Some test cases should succeed. Check !ret instead of ret. Fixes: 36eedd5b91e3 ("KVM: selftests: Add basic selftest for guest_memfd()") Signed-off-by: Isaku Yamahata --- Changes v1 -> v2: - no change --- tools/testing/selftests/kvm/guest_memfd_test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing= /selftests/kvm/guest_memfd_test.c index 3b6532b833b2..f3b99c1e5464 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -72,11 +72,11 @@ static void test_fallocate(int fd, size_t page_size, si= ze_t total_size) =20 ret =3D fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, total_size, page_size); - TEST_ASSERT(ret, "fallocate(PUNCH_HOLE) at total_size should be fine (no-= op)"); + TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) at total_size should be fine (no= -op)"); =20 ret =3D fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, total_size + page_size, page_size); - TEST_ASSERT(ret, "fallocate(PUNCH_HOLE) after total_size should be fine (= no-op)"); + TEST_ASSERT(!ret, "fallocate(PUNCH_HOLE) after total_size should be fine = (no-op)"); =20 ret =3D fallocate(fd, FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE, page_size, page_size - 1); --=20 2.25.1 From nobody Sat Feb 7 09:58:53 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A8C7FEB64DD for ; Thu, 22 Jun 2023 23:17:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231659AbjFVXRj (ORCPT ); Thu, 22 Jun 2023 19:17:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44572 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231592AbjFVXRe (ORCPT ); Thu, 22 Jun 2023 19:17:34 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0541526A0; Thu, 22 Jun 2023 16:17:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687475839; x=1719011839; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4ROuJQzixyiTqp680sndGz2g/SfpfDyBJFI0PJfgE+Y=; b=R2LKDd7wNdndVsl3+BKTsx+L78PMZ+DJHe5o7dyHpRcTa1B4xnur2lM/ tXbYSslXOnvY4yX4hhsqXFLl/HFm5zjnkODwE/ecTZRwzGnoAcFAJD9jT pYx1cQJru1tYjpr0GQGX3xFDX/fGUCznqn3qM9fLpbxKQqQOqnZwhzzmN 44Sf1KLGbAAAN8rwSHnpIVDFIquHgrfEHkoTcw0U2WGdbbIkQ3F3n9MY2 9EiWP78TpE8RKKYbjsZiGs8rdYSyqnzwOlz5f4R896X/7yP4OdUvbWIPM aWUsfNYMG6qLVhTwp7GCL0qMopmafJWLoxO1r+zsFKerPln6vwp/Ck68g Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="358129729" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="358129729" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="718285979" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="718285979" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:11 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com, linux-coco@lists.linux.dev, Chao Peng , Ackerley Tng , Vishal Annapurve , Michael Roth Subject: [RFC PATCH v2 3/6] KVM: x86/mmu: Pass round full 64-bit error code for the KVM page fault Date: Thu, 22 Jun 2023 16:16:27 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata Because the full 64-bit error code, or more info about the fault, for the KVM page fault will be needed for protected VM, TDX and SEV-SNP, update kvm_mmu_do_page_fault() to accept the 64-bit value so it can pass it to the callbacks. The upper 32 bits of error code are discarded at kvm_mmu_page_fault() by lower_32_bits(). Now it's passed down as full 64 bits. Because only FNAME(page_fault) depends on it, move lower_32_bits() into FNAME(page_fault). The accesses of fault->error_code are as follows - FNAME(page_fault): change to explicitly use lower_32_bits() - kvm_mmu_page_fault(): explicit mask with PFERR_RSVD_MASK, PFERR_NESTED_GUEST_PAGE - mmutrace: changed u32 -> u64 - pgprintk(): change %x -> %llx No functional change is intended. This is a preparation to pass on more info with page fault error code. Signed-off-by: Isaku Yamahata --- Changes v1 -> v2: - no change --- arch/x86/kvm/mmu/mmu.c | 5 ++--- arch/x86/kvm/mmu/mmu_internal.h | 4 ++-- arch/x86/kvm/mmu/mmutrace.h | 2 +- arch/x86/kvm/mmu/paging_tmpl.h | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index dc2b9a2f717c..b8ba7f11c3cb 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -4510,7 +4510,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault static int nonpaging_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) { - pgprintk("%s: gva %lx error %x\n", __func__, fault->addr, fault->error_co= de); + pgprintk("%s: gva %llx error %llx\n", __func__, fault->addr, fault->error= _code); =20 /* This path builds a PAE pagetable, we can map 2mb pages at maximum. */ fault->max_level =3D PG_LEVEL_2M; @@ -5820,8 +5820,7 @@ int noinline kvm_mmu_page_fault(struct kvm_vcpu *vcpu= , gpa_t cr2_or_gpa, u64 err } =20 if (r =3D=3D RET_PF_INVALID) { - r =3D kvm_mmu_do_page_fault(vcpu, cr2_or_gpa, - lower_32_bits(error_code), false, + r =3D kvm_mmu_do_page_fault(vcpu, cr2_or_gpa, error_code, false, &emulation_type); if (KVM_BUG_ON(r =3D=3D RET_PF_INVALID, vcpu->kvm)) return -EIO; diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_interna= l.h index f1786698ae00..7f9ec1e5b136 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -191,7 +191,7 @@ static inline bool is_nx_huge_page_enabled(struct kvm *= kvm) struct kvm_page_fault { /* arguments to kvm_mmu_do_page_fault. */ const gpa_t addr; - const u32 error_code; + const u64 error_code; const bool prefetch; =20 /* Derived from error_code. */ @@ -283,7 +283,7 @@ enum { }; =20 static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_o= r_gpa, - u32 err, bool prefetch, int *emulation_type) + u64 err, bool prefetch, int *emulation_type) { struct kvm_page_fault fault =3D { .addr =3D cr2_or_gpa, diff --git a/arch/x86/kvm/mmu/mmutrace.h b/arch/x86/kvm/mmu/mmutrace.h index 2d7555381955..2e77883c92f6 100644 --- a/arch/x86/kvm/mmu/mmutrace.h +++ b/arch/x86/kvm/mmu/mmutrace.h @@ -261,7 +261,7 @@ TRACE_EVENT( TP_STRUCT__entry( __field(int, vcpu_id) __field(gpa_t, cr2_or_gpa) - __field(u32, error_code) + __field(u64, error_code) __field(u64 *, sptep) __field(u64, old_spte) __field(u64, new_spte) diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 0662e0278e70..ee4b881c5b39 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -758,7 +758,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, str= uct kvm_page_fault *fault struct guest_walker walker; int r; =20 - pgprintk("%s: addr %lx err %x\n", __func__, fault->addr, fault->error_cod= e); + pgprintk("%s: addr %llx err %llx\n", __func__, fault->addr, fault->error_= code); WARN_ON_ONCE(fault->is_tdp); =20 /* @@ -767,7 +767,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, str= uct kvm_page_fault *fault * The bit needs to be cleared before walking guest page tables. */ r =3D FNAME(walk_addr)(&walker, vcpu, fault->addr, - fault->error_code & ~PFERR_RSVD_MASK); + lower_32_bits(fault->error_code) & ~PFERR_RSVD_MASK); =20 /* * The page is not mapped by the guest. Let the guest handle it. --=20 2.25.1 From nobody Sat Feb 7 09:58:53 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC936EB64DC for ; Thu, 22 Jun 2023 23:17:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231697AbjFVXRm (ORCPT ); Thu, 22 Jun 2023 19:17:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44688 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231646AbjFVXRj (ORCPT ); Thu, 22 Jun 2023 19:17:39 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40EAA26A8; Thu, 22 Jun 2023 16:17:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687475842; x=1719011842; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=6833orrJKCdah5qJfCTEMu2QxzIt4doif9bOKIutL50=; b=Gy/8YXd4OVKVBV5WE9bq6JzOzMfMC1bCpT6rvEcUTWA6C+3S4YWBjqDS W6S23sEwoiG41la3UWCsSqcVDQhdJO4QyKIo7VhG+H/jMoC2GwERUIYVK Wrxg5XhzNZFKv+CN+mPEaSPixYOGhT4BHE8Dvt0xQsqzOBAaNOg2J09Gx Ek7eEOJ/7REJyPGQYmOhKFeAyA8BFoGtIQhmCc0gqjd8OHrx7tyivrqu6 aNCfUYkerBAnebES6K5VxuEJZ5R7KQZv4hiyX9ie2BSvud5Ejim0SLICy Kbq2xDx6IqTlvnyjP/rDxNuHsyNbFELrKO1DYqaEibaaieySbr2s1fa5e Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="358129737" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="358129737" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="718285983" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="718285983" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:12 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com, linux-coco@lists.linux.dev, Chao Peng , Ackerley Tng , Vishal Annapurve , Michael Roth Subject: [RFC PATCH v2 4/6] KVM: x86: Introduce fault type to indicate kvm page fault is private Date: Thu, 22 Jun 2023 16:16:28 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata Introduce kvm fault type to indicate how to handle kvm page fault. It is unfortunate and inflexible for kvm_mmu_do_page_fault() to call kvm_mem_is_private(), eventually looking up memory attributes. Later __kvm_faultin_pfn() looks up memory attributes again. There is a race condition that other threads can change memory attributes due to not gaining the mmu lock. SNP-SEV and TDX define theri way to indicate that the page fault is private. Add KVM fault type, add mmu_private_fault_mask to struct kvm_arch for SNP to determine the fault is private, add gfn_shared_mask to struct kvm_arch for TDX to determine the fault is private. KVM_FAULT_SHARED_ALWAYS is added for the conventional guest to avoid over head to lookup memory attributes. Suggested-by: Michael Roth Signed-off-by: Isaku Yamahata --- Changes v1 -> v2: - Introduced fault type and replaced is_private with fault_type. - Add kvm_get_fault_type() to encapsulate the difference. --- arch/x86/include/asm/kvm_host.h | 6 ++++++ arch/x86/kvm/mmu/mmu.c | 26 ++++++++++++++++++++------ arch/x86/kvm/mmu/mmu_internal.h | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 8ae131dc645d..5afeefc7a516 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1445,6 +1445,12 @@ struct kvm_arch { */ #define SPLIT_DESC_CACHE_MIN_NR_OBJECTS (SPTE_ENT_PER_PAGE + 1) struct kvm_mmu_memory_cache split_desc_cache; + +#ifdef CONFIG_KVM_PROTECTED_VM + /* To make the patch compile. */ + u64 mmu_private_fault_mask; + gfn_t gfn_shared_mask; +#endif }; =20 struct kvm_vm_stat { diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index b8ba7f11c3cb..feec75515f39 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3174,10 +3174,12 @@ static int host_pfn_mapping_level(struct kvm *kvm, = gfn_t gfn, =20 static int __kvm_mmu_max_mapping_level(struct kvm *kvm, const struct kvm_memory_slot *slot, - gfn_t gfn, int max_level, bool is_private) + gfn_t gfn, int max_level, + enum kvm_fault_type fault_type) { struct kvm_lpage_info *linfo; int host_level; + bool is_private =3D fault_type =3D=3D KVM_FAULT_PRIVATE; =20 max_level =3D min(max_level, max_huge_page_level); for ( ; max_level > PG_LEVEL_4K; max_level--) { @@ -3228,7 +3230,7 @@ void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, s= truct kvm_page_fault *fault */ fault->req_level =3D __kvm_mmu_max_mapping_level(vcpu->kvm, slot, fault->gfn, fault->max_level, - fault->is_private); + fault->fault_type); if (fault->req_level =3D=3D PG_LEVEL_4K || fault->huge_page_disallowed) return; =20 @@ -4328,7 +4330,7 @@ static int kvm_do_memory_fault_exit(struct kvm_vcpu *= vcpu, struct kvm_page_fault *fault) { vcpu->run->exit_reason =3D KVM_EXIT_MEMORY_FAULT; - if (fault->is_private) + if (fault->fault_type =3D=3D KVM_FAULT_PRIVATE) vcpu->run->memory.flags =3D KVM_MEMORY_EXIT_FLAG_PRIVATE; else vcpu->run->memory.flags =3D 0; @@ -4386,10 +4388,22 @@ static int __kvm_faultin_pfn(struct kvm_vcpu *vcpu,= struct kvm_page_fault *fault return RET_PF_EMULATE; } =20 - if (fault->is_private !=3D kvm_mem_is_private(vcpu->kvm, fault->gfn)) - return kvm_do_memory_fault_exit(vcpu, fault); + if (fault->fault_type =3D=3D KVM_FAULT_SHARED_ALWAYS) { + /* + * The conventional case. Don't lookup memory attributes to + * avoid overhead + */ + fault->fault_type =3D KVM_FAULT_SHARED; + } else if (fault->fault_type =3D=3D KVM_FAULT_MEM_ATTR) { + fault->fault_type =3D kvm_mem_is_private(vcpu->kvm, fault->gfn) ? + KVM_FAULT_PRIVATE : KVM_FAULT_SHARED; + } else { + if ((fault->fault_type =3D=3D KVM_FAULT_PRIVATE) !=3D + kvm_mem_is_private(vcpu->kvm, fault->gfn)) + return kvm_do_memory_fault_exit(vcpu, fault); + } =20 - if (fault->is_private) + if (fault->fault_type =3D=3D KVM_FAULT_PRIVATE) return kvm_faultin_pfn_private(vcpu, fault); =20 async =3D false; diff --git a/arch/x86/kvm/mmu/mmu_internal.h b/arch/x86/kvm/mmu/mmu_interna= l.h index 7f9ec1e5b136..0ec0b927a391 100644 --- a/arch/x86/kvm/mmu/mmu_internal.h +++ b/arch/x86/kvm/mmu/mmu_internal.h @@ -188,6 +188,13 @@ static inline bool is_nx_huge_page_enabled(struct kvm = *kvm) return READ_ONCE(nx_huge_pages) && !kvm->arch.disable_nx_huge_pages; } =20 +enum kvm_fault_type { + KVM_FAULT_MEM_ATTR, + KVM_FAULT_SHARED, + KVM_FAULT_SHARED_ALWAYS, + KVM_FAULT_PRIVATE, +}; + struct kvm_page_fault { /* arguments to kvm_mmu_do_page_fault. */ const gpa_t addr; @@ -203,9 +210,10 @@ struct kvm_page_fault { =20 /* Derived from mmu and global state. */ const bool is_tdp; - const bool is_private; const bool nx_huge_page_workaround_enabled; =20 + enum kvm_fault_type fault_type; + /* * Whether a >4KB mapping can be created or is forbidden due to NX * hugepages. @@ -282,6 +290,27 @@ enum { RET_PF_SPURIOUS, }; =20 +static inline enum kvm_fault_type kvm_get_fault_type(struct kvm *kvm, + gpa_t gpa, u64 err) +{ + +#ifdef CONFIG_KVM_PROTECTED_VM + /* SEV-SNP handling */ + if (kvm->arch.mmu_private_fault_mask) + return (err & kvm->arch.mmu_private_fault_mask) ? + KVM_FAULT_PRIVATE : KVM_FAULT_SHARED; + + /* TDX handling */ + if (kvm->arch.gfn_shared_mask) + return (gpa_to_gfn(gpa) & kvm->arch.gfn_shared_mask) ? + KVM_FAULT_SHARED : KVM_FAULT_PRIVATE; +#endif + if (kvm->arch.vm_type =3D=3D KVM_X86_PROTECTED_VM) + return KVM_FAULT_MEM_ATTR; + /* Don't query memory attributes. */ + return KVM_FAULT_SHARED_ALWAYS; +} + static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_o= r_gpa, u64 err, bool prefetch, int *emulation_type) { @@ -301,7 +330,7 @@ static inline int kvm_mmu_do_page_fault(struct kvm_vcpu= *vcpu, gpa_t cr2_or_gpa, .max_level =3D KVM_MAX_HUGEPAGE_LEVEL, .req_level =3D PG_LEVEL_4K, .goal_level =3D PG_LEVEL_4K, - .is_private =3D kvm_mem_is_private(vcpu->kvm, cr2_or_gpa >> PAGE_SHIFT), + .fault_type =3D kvm_get_fault_type(vcpu->kvm, cr2_or_gpa, err), }; int r; =20 --=20 2.25.1 From nobody Sat Feb 7 09:58:53 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 679A8EB64DA for ; Thu, 22 Jun 2023 23:17:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231715AbjFVXRq (ORCPT ); Thu, 22 Jun 2023 19:17:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231592AbjFVXRk (ORCPT ); Thu, 22 Jun 2023 19:17:40 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F24C11992; Thu, 22 Jun 2023 16:17:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687475846; x=1719011846; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zBMD9h2KBgIYaddcweRh+FeZhoyrRw3SBUE0qo0cW8k=; b=SEjhHTfvXLCgluYg021G2iTKdA5LDkSOKdkhXU1v+CHdm2IVFUerXhJE h3iwWXs7bTbW5+PM2JbrDEgffMPJMht7OJ2DpeJhOixZzEg7AnpNti1BP ID4KuG49DywQxBD2Ze95SOAo65HONypM1B2cN8J60THygaKxMCLOr+rNF GcNX21PzL7JneeZufKAP1O1afH5Zuvwy46GYpTMLvTqj8HZXWRBykPWjX bazv26LGkceO79h0IYKF35vLBJHY8GD9tvydgt/AZ8EGmb848SZ/JFl/s EhBXemdGWZWs2Hu+gfM70616ikeYhMLkxtDZB1Nxifelvr3SiTS94JEj+ A==; X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="358129743" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="358129743" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="718285986" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="718285986" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:13 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com, linux-coco@lists.linux.dev, Chao Peng , Ackerley Tng , Vishal Annapurve , Michael Roth Subject: [RFC PATCH v2 5/6] KVM: Add flags to struct kvm_gfn_range Date: Thu, 22 Jun 2023 16:16:29 -0700 Message-Id: <689da77417c2f4055f02a71aab51ff603bc195af.1687474039.git.isaku.yamahata@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata Add flags to strut kvm_gfn_range to indicate who triggered the callback and new memory attributes. TDX needs to know the reason for a callback by kvm_unmap_gfn_range(). mmu notifier, set memory attributes ioctl or KVM gmem callback. With TDX, zapping a private page from the encrypted page table and adding the page back to the same private GPA results in zeroing the page, and the guest has to accept the page again. On the change of memory attribute from private to shared, zapping the GPA range irrespective to private-or-shared and expecting the fault doesn't work for TDX. Instead, zap shared pages only and keep the private pages. Concretely - If it's from mmu notifier, zap shared pages. - If it's from KVM gmem, zap private pages. - If setting memory attributes to private, zap shared pages. - If setting memory attributes to shared, zap private pages. Signed-off-by: Isaku Yamahata --- Changes v1 -> v2: - consolidate KVM_GFN_RANGE_FLAGS_GMEM_{PUNCH_HOLE, RELEASE} into KVM_GFN_RANGE_FLAGS_GMEM. - Update the commit message to describe TDX more. Drop SEV_SNP. --- include/linux/kvm_host.h | 10 +++++++++- virt/kvm/guest_mem.c | 9 ++++++--- virt/kvm/kvm_main.c | 4 +++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 1a47cedae8a1..1fe0516fcddf 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -256,12 +256,20 @@ int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu); #endif =20 #ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER + +#define KVM_GFN_RANGE_FLAGS_SET_MEM_ATTR BIT(0) +#define KVM_GFN_RANGE_FLAGS_GMEM BIT(1) + struct kvm_gfn_range { struct kvm_memory_slot *slot; gfn_t start; gfn_t end; - pte_t pte; + union { + pte_t pte; + u64 attrs; + }; bool may_block; + unsigned int flags; }; bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range); bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range); diff --git a/virt/kvm/guest_mem.c b/virt/kvm/guest_mem.c index cdf2d84683c8..387226136960 100644 --- a/virt/kvm/guest_mem.c +++ b/virt/kvm/guest_mem.c @@ -99,7 +99,8 @@ static struct folio *kvm_gmem_get_folio(struct file *file= , pgoff_t index) } =20 static void kvm_gmem_invalidate_begin(struct kvm *kvm, struct kvm_gmem *gm= em, - pgoff_t start, pgoff_t end) + pgoff_t start, pgoff_t end, + unsigned int flags) { struct kvm_memory_slot *slot; unsigned long index; @@ -118,6 +119,7 @@ static void kvm_gmem_invalidate_begin(struct kvm *kvm, = struct kvm_gmem *gmem, .slot =3D slot, .pte =3D __pte(0), .may_block =3D true, + .flags =3D flags, }; =20 kvm_mmu_invalidate_range_add(kvm, gfn_range.start, gfn_range.end); @@ -156,7 +158,8 @@ static long kvm_gmem_punch_hole(struct file *file, loff= _t offset, loff_t len) */ filemap_invalidate_lock(file->f_mapping); =20 - kvm_gmem_invalidate_begin(kvm, gmem, start, end); + kvm_gmem_invalidate_begin(kvm, gmem, start, end, + KVM_GFN_RANGE_FLAGS_GMEM); =20 truncate_inode_pages_range(file->f_mapping, offset, offset + len - 1); =20 @@ -263,7 +266,7 @@ static int kvm_gmem_release(struct inode *inode, struct= file *file) * Free the backing memory, and more importantly, zap all SPTEs that * pointed at this file. */ - kvm_gmem_invalidate_begin(kvm, gmem, 0, -1ul); + kvm_gmem_invalidate_begin(kvm, gmem, 0, -1ul, KVM_GFN_RANGE_FLAGS_GMEM); truncate_inode_pages_final(file->f_mapping); kvm_gmem_invalidate_end(kvm, gmem, 0, -1ul); =20 diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 422d49634c56..9cdfa2fb675f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -613,6 +613,7 @@ static __always_inline int __kvm_handle_hva_range(struc= t kvm *kvm, gfn_range.start =3D hva_to_gfn_memslot(hva_start, slot); gfn_range.end =3D hva_to_gfn_memslot(hva_end + PAGE_SIZE - 1, slot); gfn_range.slot =3D slot; + gfn_range.flags =3D 0; =20 if (!locked) { locked =3D true; @@ -2391,8 +2392,9 @@ static void kvm_mem_attrs_changed(struct kvm *kvm, un= signed long attrs, bool flush =3D false; int i; =20 - gfn_range.pte =3D __pte(0); + gfn_range.attrs =3D attrs; gfn_range.may_block =3D true; + gfn_range.flags =3D KVM_GFN_RANGE_FLAGS_SET_MEM_ATTR; =20 for (i =3D 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) { slots =3D __kvm_memslots(kvm, i); --=20 2.25.1 From nobody Sat Feb 7 09:58:53 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DDDC0EB64DC for ; Thu, 22 Jun 2023 23:17:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231808AbjFVXRz (ORCPT ); Thu, 22 Jun 2023 19:17:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44820 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231700AbjFVXRu (ORCPT ); Thu, 22 Jun 2023 19:17:50 -0400 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1CBBD26B0; Thu, 22 Jun 2023 16:17:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1687475854; x=1719011854; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BD6pXTs5JxVG1xLxlJ9ylWBhK590xLSHJkxsDTrYBeo=; b=ZBjCB8nhfDeF4EJvPg9bdCYQR9UOPyTY2IjR97f0p03UlKcIj2BrhHT/ 0Lm2x9sHgDqEmR4/sFG2HAwRFg6aKWEA5uMGDaRo4Hh7/n6z7P2hM8gfi otBzFP8PjtyiQS/n6ewH9SSXi834a/bsEUtbWkJorIOMbfTldgvXJyaoP QXpg8w8QToxaMl9S5gUPyxFBkeoKIfGEvqvuLAmk/ugaJ1ZoEx37bCkQF 7RLYiNz2HQ0wQrNDoVWh9iZ99auCTjBAxI21S3zwQOK+RH6Ex3TfGvdFy Q72/XLDf0lNxW3xzIsl1C83IABjyRHkFWIhvJJym73i+fuUMsfE1J0Lbs w==; X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="358129749" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="358129749" Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10749"; a="718285989" X-IronPort-AV: E=Sophos;i="6.01,150,1684825200"; d="scan'208";a="718285989" Received: from ls.sc.intel.com (HELO localhost) ([172.25.112.31]) by fmsmga007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 22 Jun 2023 16:17:13 -0700 From: isaku.yamahata@intel.com To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: isaku.yamahata@intel.com, isaku.yamahata@gmail.com, Paolo Bonzini , erdemaktas@google.com, Sean Christopherson , Sagi Shahar , David Matlack , Kai Huang , Zhi Wang , chen.bo@intel.com, linux-coco@lists.linux.dev, Chao Peng , Ackerley Tng , Vishal Annapurve , Michael Roth Subject: [RFC PATCH v2 6/6] KVM: x86: Add is_vm_type_supported callback Date: Thu, 22 Jun 2023 16:16:30 -0700 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Isaku Yamahata For TDX, allow the backend can override the supported vm type. Add KVM_X86_TDX_VM to reserve the bit. Signed-off-by: Isaku Yamahata --- Changes v1 -> v2 - no change --- arch/x86/include/asm/kvm-x86-ops.h | 1 + arch/x86/include/asm/kvm_host.h | 1 + arch/x86/include/uapi/asm/kvm.h | 1 + arch/x86/kvm/svm/svm.c | 7 +++++++ arch/x86/kvm/vmx/vmx.c | 6 ++++++ arch/x86/kvm/x86.c | 10 +++++++++- arch/x86/kvm/x86.h | 2 ++ 7 files changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-= x86-ops.h index 13bc212cd4bc..c0143906fe6d 100644 --- a/arch/x86/include/asm/kvm-x86-ops.h +++ b/arch/x86/include/asm/kvm-x86-ops.h @@ -20,6 +20,7 @@ KVM_X86_OP(hardware_disable) KVM_X86_OP(hardware_unsetup) KVM_X86_OP(has_emulated_msr) KVM_X86_OP(vcpu_after_set_cpuid) +KVM_X86_OP(is_vm_type_supported) KVM_X86_OP(vm_init) KVM_X86_OP_OPTIONAL(vm_destroy) KVM_X86_OP_OPTIONAL_RET0(vcpu_precreate) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_hos= t.h index 5afeefc7a516..6adcc6be6466 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -1549,6 +1549,7 @@ struct kvm_x86_ops { bool (*has_emulated_msr)(struct kvm *kvm, u32 index); void (*vcpu_after_set_cpuid)(struct kvm_vcpu *vcpu); =20 + bool (*is_vm_type_supported)(unsigned long vm_type); unsigned int vm_size; int (*vm_init)(struct kvm *kvm); void (*vm_destroy)(struct kvm *kvm); diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kv= m.h index 6afbfbb32d56..53d382b3b423 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -561,5 +561,6 @@ struct kvm_pmu_event_filter { =20 #define KVM_X86_DEFAULT_VM 0 #define KVM_X86_PROTECTED_VM 1 +#define KVM_X86_TDX_VM 2 =20 #endif /* _ASM_X86_KVM_H */ diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index eb308c9994f9..e9ed8729f63b 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -4756,6 +4756,12 @@ static void svm_vm_destroy(struct kvm *kvm) sev_vm_destroy(kvm); } =20 +static bool svm_is_vm_type_supported(unsigned long type) +{ + /* FIXME: Check if CPU is capable of SEV. */ + return __kvm_is_vm_type_supported(type); +} + static int svm_vm_init(struct kvm *kvm) { if (!pause_filter_count || !pause_filter_thresh) @@ -4784,6 +4790,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata =3D { .vcpu_free =3D svm_vcpu_free, .vcpu_reset =3D svm_vcpu_reset, =20 + .is_vm_type_supported =3D svm_is_vm_type_supported, .vm_size =3D sizeof(struct kvm_svm), .vm_init =3D svm_vm_init, .vm_destroy =3D svm_vm_destroy, diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 44fb619803b8..b5394ba8cb9c 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7469,6 +7469,11 @@ static int vmx_vcpu_create(struct kvm_vcpu *vcpu) return err; } =20 +static bool vmx_is_vm_type_supported(unsigned long type) +{ + return __kvm_is_vm_type_supported(type); +} + #define L1TF_MSG_SMT "L1TF CPU bug present and SMT on, data leak possible.= See CVE-2018-3646 and https://www.kernel.org/doc/html/latest/admin-guide/h= w-vuln/l1tf.html for details.\n" #define L1TF_MSG_L1D "L1TF CPU bug present and virtualization mitigation d= isabled, data leak possible. See CVE-2018-3646 and https://www.kernel.org/d= oc/html/latest/admin-guide/hw-vuln/l1tf.html for details.\n" =20 @@ -8138,6 +8143,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata =3D { .hardware_disable =3D vmx_hardware_disable, .has_emulated_msr =3D vmx_has_emulated_msr, =20 + .is_vm_type_supported =3D vmx_is_vm_type_supported, .vm_size =3D sizeof(struct kvm_vmx), .vm_init =3D vmx_vm_init, .vm_destroy =3D vmx_vm_destroy, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c9e1c9369be2..b5f865f39a00 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4418,12 +4418,18 @@ static int kvm_ioctl_get_supported_hv_cpuid(struct = kvm_vcpu *vcpu, return 0; } =20 -static bool kvm_is_vm_type_supported(unsigned long type) +bool __kvm_is_vm_type_supported(unsigned long type) { return type =3D=3D KVM_X86_DEFAULT_VM || (type =3D=3D KVM_X86_PROTECTED_VM && IS_ENABLED(CONFIG_KVM_PROTECTED_VM) && tdp_enabled); } +EXPORT_SYMBOL_GPL(__kvm_is_vm_type_supported); + +static bool kvm_is_vm_type_supported(unsigned long type) +{ + return static_call(kvm_x86_is_vm_type_supported)(type); +} =20 int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) { @@ -4618,6 +4624,8 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, lon= g ext) r =3D BIT(KVM_X86_DEFAULT_VM); if (kvm_is_vm_type_supported(KVM_X86_PROTECTED_VM)) r |=3D BIT(KVM_X86_PROTECTED_VM); + if (kvm_is_vm_type_supported(KVM_X86_TDX_VM)) + r |=3D BIT(KVM_X86_TDX_VM); break; default: break; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index c544602d07a3..7d5aa8f0571a 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -9,6 +9,8 @@ #include "kvm_cache_regs.h" #include "kvm_emulate.h" =20 +bool __kvm_is_vm_type_supported(unsigned long type); + struct kvm_caps { /* control of guest tsc rate supported? */ bool has_tsc_control; --=20 2.25.1